Cheat Engine

You may request or share scripts for MicroMacro in this forum.
Post Reply
Message
Author
zuel
Posts: 21
Joined: Mon Jan 10, 2011 12:49 am

Cheat Engine

#1 Post by zuel » Sun Jan 16, 2011 2:37 am

Here is some code for anyone who wishes to utilize Cheat Engines xml. It simply loads the Cheat Engine XML into a table called memLocation. It then creates a sub table for each CheatEntry by name and creates two fields, Start and Offsets.

Example end result:

Code: Select all

MemLocation={
  Name1={
    Start=0xffffff,
    Offsets={0xffff,0xffff,0xffff},
  ,}
  Name2={
    Start=0xffffff,
    Offsets={0xffff,0xffff,0xffff},
  ,}
}
Here is the code:

Code: Select all



memLocation={};

mem = xml.open("./scripts/DOBotMem.XML");
elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
for i,v in pairs(elements) do
	print(v:getElement("Description"):getValue());
	of = v:getElement("Pointer"):getElement("Offsets"):getElements("Offset");
	print (#of);
	if(#of > 1)then
		Offsets = {};
		for ii = #of,1,-1 do 
			table.insert(Offsets,tonumber(of[ii]:getValue(),16));
		end
		memLocation[v:getElement("Description"):getValue()] = {   
			["Start"] = tonumber(v:getElement("Pointer"):getElement("Address"):getValue(),16),
			["Offsets"] = Offsets,
		};		
	else
		Offset = tonumber(of[1]:getValue(),16);
		memLocation[v:getElement("Description"):getValue()] = {   
			["Start"] = tonumber(v:getElement("Pointer"):getElement("Address"):getValue(),16),
			["Offsets"] = Offset,
		};		
	end
end

tprint(memLocation);
Last edited by zuel on Sun Jan 16, 2011 4:03 pm, edited 1 time in total.

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: Cheat Engine

#2 Post by Administrator » Sun Jan 16, 2011 12:28 pm

Nice, so once you create a table with Cheat Engine, you can use this to load the saved table? Or am I understanding this wrong?

zuel
Posts: 21
Joined: Mon Jan 10, 2011 12:49 am

Re: Cheat Engine

#3 Post by zuel » Sun Jan 16, 2011 1:33 pm

Yup. Just get your address's with Cheat engine, Save it to XML. And the code will parse all the CheatEntries into a LUA table.

then just use memLocation like

memoryReadIntPtr(myProc, memLocation["PlayerHealth"]["Start"],memLocation["PlayerHealth"]["Offsets"]);


where PlayerHealth is the name you chose to give the address pointer in Cheat Engine.

zuel
Posts: 21
Joined: Mon Jan 10, 2011 12:49 am

Re: Cheat Engine

#4 Post by zuel » Sun Jan 16, 2011 2:33 pm

Hang on. Terminology.

A table could mean one or more things, even in CheatEngine.

I do not mean this will load the Dissect Data Structures function accessed from the memory view.

It will load Cheat Engines main window address's that you have selected and are displayed in the bottom portion of the window.

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: Cheat Engine

#5 Post by Administrator » Sun Jan 16, 2011 3:36 pm

Yeah, this is pretty cool. Great idea, really. I'll probably end up using it myself. Definitely would be useful when it comes to managing adding/removing/editing all those pointers. Thanks for the code.

zuel
Posts: 21
Joined: Mon Jan 10, 2011 12:49 am

Re: Cheat Engine

#6 Post by zuel » Mon Jan 17, 2011 11:50 pm

Okay, I am honestly a tweeker, without drugs even.

Here is a different version that creates a class and handles correctly reading the memory address's without you even needing to know what LUA functions to call.

I think this is a bit easier, requires no knowledge of what memory functions are needed when converting the cheatengine address to lua etc.. And it should handle all types.

but I am not sure if I did Type 5,7 or 8 correctly.

Code: Select all

--Byte            Type 0   
--2 Byte          Type 1   
--4 Byte          Type 2   
--Float           Type 3   
--Double          Type 4   
--Binary          Type 5   
--8 Byte          Type 6   
--Text            Type 7   
--Array of Bytes  Type 8   
                           

function LoadCheatEngine(file)
	memLocations={};
	local mem = xml.open("./scripts/DOBotMem.XML");
	local elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
	for i,v in pairs(elements) do
		local memLocation=MemoryLocation(v);
		memLocations[memLocation.Name] = memLocation;
	end
	return memLocations;
end

MemoryLocation = class(function(memLoc,CEXMLCheatEntry)
	memLoc.Name = CEXMLCheatEntry:getElement("Description"):getValue();
	memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Address"):getValue(),16);
	memLoc.Type = tonumber(CEXMLCheatEntry:getElement("Type"):getValue(),10);
	memLoc.IsPointer = (CEXMLCheatEntry:getElement("Pointer")~=nil);
	memLoc.Offsets = nil;
	memLoc.Length = 0;
	if(memLoc.IsPointer)then
		memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Pointer"):getElement("Address"):getValue(),16);
		osets = nil;
		of = CEXMLCheatEntry:getElement("Pointer"):getElement("Offsets"):getElements("Offset");
		if(#of > 1)then
			osets = {};
			for ii = #of,1,-1 do 
				table.insert(osets,tonumber(of[ii]:getValue(),16));
			end
		elseif(#of == 1) then
				osets = tonumber(of[1]:getValue(),16);
		end
		
		memLoc.Offsets = osets;
	end
	if(memLoc.Type==7 or memLoc.Type==8 or memLoc.Type==5)then
		memLoc.Length = tonumber(CEXMLCheatEntry:getElement("Length"):getValue(),10);
	end
end)

function MemoryLocation:Value(process)
	if(self.IsPointer)then
		if(self.Type==0)then
			return memoryReadBytePtr(process, self.Address, self.Offsets);
		elseif(self.Type==1)then
			return memoryReadShortPtr(process, self.Address, self.Offsets);
		elseif(self.Type==2)then
			return memoryReadIntPtr(process, self.Address, self.Offsets);
		elseif(self.Type==3)then
			return memoryReadFloatPtr(process, self.Address, self.Offsets);
		elseif(self.Type==4)then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type==5)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
			end
			return bytes;
		elseif(self.Type==6)then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type==7)then
			return memoryReadStringPtr(process, self.Address, self.Offsets, self.Length);
		elseif(self.Type==8)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
			end
			return bytes;
		end
	else
		if(self.Type==0)then
			return memoryReadByte(process, self.Address);
		elseif(self.Type==1)then
			return memoryReadShort(process, self.Address);
		elseif(self.Type==2)then
			return memoryReadInt(process, self.Address);
		elseif(self.Type==3)then
			return memoryReadFloat(process, self.Address);
		elseif(self.Type==4)then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type==5)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address));
			end
			return bytes;
		elseif(self.Type==6)then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type==7)then
			return memoryReadString(process, self.Address, self.Length);
		elseif(self.Type==8)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address));
			end
			return bytes;
		end	
	end
end

-- Example calling
        myProc =openProcess( findProcess("MyApp") )

	memL =  LoadCheatEngine("./scripts/DOBotMem.XML");
	
	print(memL["PlayerName"]:Value(myProc));



zuel
Posts: 21
Joined: Mon Jan 10, 2011 12:49 am

Re: Cheat Engine

#7 Post by zuel » Wed Jan 19, 2011 3:26 am

Okay. I can't believe this, but I just found out CheatEngine 6.0 has a new table structure.

here you go, this will handle the old and the new.

Example call:

Code: Select all


include("CheatEngine.lua");

appName = "Dragon*";

myProc = openProcess( findProcess(appName) );
	
window = findWindow(appName);

function main()

	memL =  LoadCheatEngine("./scripts/game.ct",findProcess(appName));
	
	print(memL["PlayerName"]:Value(myProc));
end
startMacro(main, true);

Code: Select all

function split(str, pat)
   local t = {}  -- NOTE: use {n = 0} in Lua-5.0
   local fpat = "(.-)" .. pat
   local last_end = 1
   local s, e, cap = str:find(fpat, 1)
   while s do
      if s ~= 1 or cap ~= "" then
	 table.insert(t,cap)
      end
      last_end = e+1
      s, e, cap = str:find(fpat, last_end)
   end
   if last_end <= #str then
      cap = str:sub(last_end)
      table.insert(t, cap)
   end
   return t
end


function LoadCheatEngine(file,process)
	memLocations={};
	local mem = xml.open(file);
	local cheatVersion = mem:getAttribute("CheatEngineTableVersion");

	if(cheatVersion == nil)then
		local elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
		for i,v in pairs(elements) do
			local memLocation=MemoryLocation(v);
			memLocations[memLocation.Name] = memLocation;
		end
		return memLocations;
	elseif(cheatVersion==10)then
		local elements = mem:getElement("CheatEntries"):getElements("CheatEntry");
		for i,v in pairs(elements) do
			local memLocation=MemoryLocation10(v,process);
			memLocations[memLocation.Name] = memLocation;
		end
		return memLocations;		
	else
		print("unsupported CheatEngine file");
	end
	return nil;
end


MemoryLocation10 = class(function(memLoc,CEXMLCheatEntry,process)

	memLoc.Name = string.gsub(CEXMLCheatEntry:getElement("Description"):getValue(), '"', "");
	
	local addrS = CEXMLCheatEntry:getElement("Address"):getValue();
	local addrList = split(string.gsub(addrS, '"', ""),"+");

	if(#addrList == 1) then
		memLoc.Address = tonumber(addrList[1],16);
	else
		local addrOffset = tonumber(addrList[2],16);
		local addrModule = getModuleAddress(process, addrList[1]);
		memLoc.Address = addrModule + addrOffset;
	end
	
	memLoc.Type = CEXMLCheatEntry:getElement("VariableType"):getValue();
	memLoc.IsPointer = (CEXMLCheatEntry:getElement("Offsets")~=nil);
	memLoc.Offsets = nil;
	memLoc.Length = 0;
	if(memLoc.IsPointer)then
		osets = nil;
		of = CEXMLCheatEntry:getElement("Offsets"):getElements("Offset");
		if(#of > 1)then
			osets = {};
			for ii = #of,1,-1 do 
				table.insert(osets,tonumber(of[ii]:getValue(),16));
			end
		elseif(#of == 1) then
				osets = tonumber(of[1]:getValue(),16);
		end
		
		memLoc.Offsets = osets;
	end
	if(memLoc.Type=="String")then
		memLoc.Length = tonumber(CEXMLCheatEntry:getElement("Length"):getValue(),10);
	end
	if(memLoc.Type=="Array of byte")then
		memLoc.Length = tonumber(CEXMLCheatEntry:getElement("ByteLength"):getValue(),10);
	end
	if(memLoc.Type=="Binary")then
		memLoc.Length = tonumber(CEXMLCheatEntry:getElement("ByteLength"):getValue(),10);
		memLoc.Start = tonumber(CEXMLCheatEntry:getElement("BitStart"):getValue(),10);		
	end
end)


MemoryLocation = class(function(memLoc,CEXMLCheatEntry)
	memLoc.Name = CEXMLCheatEntry:getElement("Description"):getValue();
	memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Address"):getValue(),16);
	memLoc.Type = tonumber(CEXMLCheatEntry:getElement("Type"):getValue(),10);
	memLoc.IsPointer = (CEXMLCheatEntry:getElement("Pointer")~=nil);
	memLoc.Offsets = nil;
	memLoc.Length = 0;
	if(memLoc.IsPointer)then
		memLoc.Address = tonumber(CEXMLCheatEntry:getElement("Pointer"):getElement("Address"):getValue(),16);
		osets = nil;
		of = CEXMLCheatEntry:getElement("Pointer"):getElement("Offsets"):getElements("Offset");
		if(#of > 1)then
			osets = {};
			for ii = #of,1,-1 do 
				table.insert(osets,tonumber(of[ii]:getValue(),16));
			end
		elseif(#of == 1) then
				osets = tonumber(of[1]:getValue(),16);
		end
		
		memLoc.Offsets = osets;
	end
	if(memLoc.Type==7 or memLoc.Type==8 or memLoc.Type==5)then
		memLoc.Length = tonumber(CEXMLCheatEntry:getElement("Length"):getValue(),10);
	end
end)

function MemoryLocation:Value(process)
	--tprint(self);
	if(self.IsPointer)then
		if(self.Type==0)then
			return memoryReadBytePtr(process, self.Address, self.Offsets);
		elseif(self.Type==1)then
			return memoryReadShortPtr(process, self.Address, self.Offsets);
		elseif(self.Type==2)then
			return memoryReadIntPtr(process, self.Address, self.Offsets);
		elseif(self.Type==3)then
			return memoryReadFloatPtr(process, self.Address, self.Offsets);
		elseif(self.Type==4)then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type==5)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
			end
			return bytes;
		elseif(self.Type==6)then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type==7)then
			return memoryReadStringPtr(process, self.Address, self.Offsets, self.Length);
		elseif(self.Type==8)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets));
			end
			return bytes;
		end
	else
		if(self.Type==0)then
			return memoryReadByte(process, self.Address);
		elseif(self.Type==1)then
			return memoryReadShort(process, self.Address);
		elseif(self.Type==2)then
			return memoryReadInt(process, self.Address);
		elseif(self.Type==3)then
			return memoryReadFloat(process, self.Address);
		elseif(self.Type==4)then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type==5)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address));
			end
			return bytes;
		elseif(self.Type==6)then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type==7)then
			return memoryReadString(process, self.Address, self.Length);
		elseif(self.Type==8)then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address));
			end
			return bytes;
		end	
	end
end


function MemoryLocation10:Value(process)
	--tprint(self);
	if(self.IsPointer)then
		if(self.Type=="Byte")then
			return memoryReadBytePtr(process, self.Address, self.Offsets);
		elseif(self.Type=="2 Bytes")then
			return memoryReadShortPtr(process, self.Address, self.Offsets);
		elseif(self.Type=="4 Bytes")then
			return memoryReadIntPtr(process, self.Address, self.Offsets);
		elseif(self.Type=="Float")then
			return memoryReadFloatPtr(process, self.Address, self.Offsets);
		elseif(self.Type=="8 Bytes")then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type=="Binary")then
			bytes = {};
			for i=self.Start,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets + i));
			end
			return bytes;
		elseif(self.Type=="Double")then
			return memoryReadDoublePtr(process, self.Address, self.Offsets);
		elseif(self.Type=="String")then
			return memoryReadStringPtr(process, self.Address, self.Offsets, self.Length);
		elseif(self.Type=="Array of byte")then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadBytePtr(process, self.Address, self.Offsets + i));
			end
			return bytes;
		end
	else
		if(self.Type=="Byte")then
			return memoryReadByte(process, self.Address);
		elseif(self.Type=="2 Bytes")then
			return memoryReadShort(process, self.Address);
		elseif(self.Type=="4 Bytes")then
			return memoryReadInt(process, self.Address);
		elseif(self.Type=="Float")then
			return memoryReadFloat(process, self.Address);
		elseif(self.Type=="8 Bytes")then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type=="Binary")then
			bytes = {};
			for i=self.Start,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address + i));
			end
			return bytes;
		elseif(self.Type=="Double")then
			return memoryReadDouble(process, self.Address);
		elseif(self.Type=="String")then
			return memoryReadString(process, self.Address, self.Length);
		elseif(self.Type=="Array of byte")then
			bytes = {};
			for i=1,self.Length do
					table.insert(bytes, memoryReadByte(process, self.Address + i));
			end
			return bytes;
		end	
	end
end



RicalEyl
Posts: 63
Joined: Fri Aug 13, 2010 2:38 pm

Re: Cheat Engine

#8 Post by RicalEyl » Tue Jul 19, 2011 5:18 am

what cheat engine are you refering to? cant find it :(

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: Cheat Engine

#9 Post by Administrator » Tue Jul 19, 2011 11:13 am

RicalEyl wrote:what cheat engine are you refering to? cant find it :(
http://www.google.com/search?q=cheat%20 ... channel=np

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests