 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
starterkit How do I cheat?
Reputation: 0
Joined: 18 Sep 2013 Posts: 6
|
Posted: Fri Jan 31, 2014 5:05 pm Post subject: Reverse engineering. |
|
|
Alright I've got a spoileral code that I want to backtrack through to find the base.
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10
My final addresses are 1a0295a0, 1a029c20, 1a02a920, and 1a02a2a0.
First off I can remove all the *valid since x*0=0 and x*1=x.
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0|1|2+0x04:]=hash;
ad0|1|2+0x10
And I can subtract ten from all my addresses to get my ad values.
1a029590(1ba6fc1c), 1a029c10(1ba6f49c), 1a02a910(1ba6f99c), and 1a02a290(1ba6f71c)
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0|1|2+0x04:]=hash;
Then do I add or subtract 4 from where they are pointing? Or where they are?
Because looking at the rest of the spoileral code it looks like +4 from current address, but looking at the memory itself it looks like a -4 from pointer...
|
|
Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Jan 31, 2014 5:46 pm Post subject: |
|
|
starterkit wrote: | Alright I've got a spoileral code that I want to backtrack through to find the base. | You know, the simplest way would probably be to tell spoileral to display base... If it can output ad0, it can output base.
If you can't for some reason, could you post your complete cheat table/file/whatever it is called or a link to it. There are stuff I'd like to inspect there (that "hash" is really weird...).
_________________
DO NOT PM me if you want help on making/fixing/using a hack. |
|
Back to top |
|
 |
starterkit How do I cheat?
Reputation: 0
Joined: 18 Sep 2013 Posts: 6
|
Posted: Fri Jan 31, 2014 7:23 pm Post subject: |
|
|
Spoileral is being a crash ridden mess that locks up every time I try to do anything so here's the code.
[script]
[involve]vbg
[group]main
[subject]Resources(current):dir
[e_with],0,9999999,unsigned
[subject]resource_name:calc,@vbg->p_resource_name
[back]
[/group]
[group]p_resource_name
[:0x0070EA04:]=>base; //wrong base that I want to change
0x48058FEE=>hash; //string key 'f'
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10=>base;
0x518E5C1C=>hash; //string key 'used'
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10=>base;
0xB427DD3B=>hash; //string key 'game'
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10=>base;
0x541F84B8=>hash; //string key 'resource'
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10=>base;
0x********=>hash; //string key 'resource.name' one of 0xA34B1939, 0xC75BAF90, 0x90105D41, or 0x4D12DEE9
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10=>base;
0x00BBECBA=>hash; //string key 'now'
[:$base:]=>base;
[:$base+0x10:]=>tmp1;
[:$base+0x18:]=>tmp2;
($tmp1&$hash)*0x20=>tmp1;
$tmp2+$tmp1=>ad0;
[:$ad0+0x1C:]=>ad1;
[:$ad1+0x1C:]=>ad2;
[:$ad0+0x04:]==$hash=>valid0;
[:$ad1+0x04:]==$hash=>valid1;
[:$ad2+0x04:]==$hash=>valid2;
($ad0*$valid0)|($ad1*$valid1)|($ad2*$valid2)+0x10
[/group]
[/involve]
[replace]0x00,vbg->main
[/script]
|
|
Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Fri Jan 31, 2014 9:48 pm Post subject: |
|
|
f.used.game ? Aww but that's a kirikiri game ! (you should have some .xp3 file(s) in the game's directory)
In that case you should try using the debug console: run the game with the "-debug" command switch. The console understands "f.used.game.resource.BLAH.now = 9999".
If that fails, use the "-hkconsole=F1", parameter, and press F1 to show the debug console.
If that fails, try using the .exe from another kirikiri game.
If that fails, use kikiriki to unpack/repack your .xp3 files and mod the .ks or .tjs file(s) that modify your resources.
If that fails (due to encrypted archives), use xp3dumper to extract your whole game, mod it, repack it with kikiriki, then play using the exe from the official kirikiri sdk or from any other kirikiri game that doesn't use encrypted archives.
Aside that, I didn't know kirikiri engine stored its variables that way and I can look into making it work with cheat engine, but it's going to be VERY UGLY, because cheat engine doesn't support pointers like [ReadHere]+[ReadSomewhereElse]*20, so there is going to be some lua with frequent refresh involved...
For my personal satisfaction: is that one of dual/tri/ninetail's games?
_________________
DO NOT PM me if you want help on making/fixing/using a hack. |
|
Back to top |
|
 |
starterkit How do I cheat?
Reputation: 0
Joined: 18 Sep 2013 Posts: 6
|
Posted: Fri Jan 31, 2014 11:33 pm Post subject: |
|
|
Yep its a dualtail. I'm aware of the debugger having triggered it many times testing out pointers that didn't quite work. I'm just butting my head against a wall because it got in my way... even though I explicitly hunted the wall down.
|
|
Back to top |
|
 |
Gniarf Grandmaster Cheater Supreme
Reputation: 43
Joined: 12 Mar 2012 Posts: 1285
|
Posted: Sat Feb 01, 2014 1:37 am Post subject: |
|
|
starterkit wrote: | I'm just butting my head against a wall because it got in my way... | "it"? What got in your way? And why do you absolutely need a pointer?
To cheat in those games it's much better to use the console than trying to build a clanky pointer, especially in a game shit-coded by 2/3/9tail (they are notorious in my book for that). I mean sometimes a given variable can be a integer, and seconds later it can be a float, or even a string.
Plus, 2/3/9tail doesn't encrypt their archives, so it's almost as if the game was open-source.
EDIT: ok I got a variable locator to work on 3 different games. It seems you had 2 problems:
1-"f" isn't a top level object, the top level object is "global". Typing "f.used" in the console is just a shorthand for "global.f.used".
2-I think the hash for "game" is incorrect. The other hashes work in my tests, but not this one.
Press ctrl+alt+shift+L at the main menu (in CE), paste that and execute:
(or put it in the table's lua script and luacall() it from an AA script)
Code: | --fill that yourself or implement the hashing algorithm in lua.
HashTable = {};
HashTable["f"]=0x48058FEE;
HashTable["used"]=0x518E5C1C;
HashTable["now"]=0x00BBECBA;
HashTable["game"]=0xB427DD3B; --doesn't work, incorrect hash?
HashTable["resource"]=0x541F84B8;
function GetMemberPtr(Base,SubNodeHash)
--returns the address for arrays/dictionaries
--or the value for integers
if (Base==nil) then
return nil;
end
local MemberArray=readInteger(Base+0x18);
if (MemberArray==nil) then
return nil;
end
local ArrayOffset=bAnd(0x20*bAnd(readInteger(Base+0x10),SubNodeHash),0xFFFFFFFF);
if (ArrayOffset==nil) then
return nil;
end
local SubNodeAddress=0;
local ad=MemberArray+ArrayOffset;
local RecursionLimit=00;
while (ad and readInteger(ad+4)~=SubNodeHash and RecursionLimit<500) do
ad = readInteger(ad+0x1C);
RecursionLimit=RecursionLimit+1;
end
if ad==nil or RecursionLimit==500 then
return nil
end
SubNodeAddress=ad;
return SubNodeAddress+0x10;
end
function GetMemberPtrByName(Base,Name)
if Base==nil then
return nil;
end
local ReturnValue=GetMemberPtr(Base,HashTable[Name]);
if ReturnValue==nil then
print("Couldn't find "..Name);
end
return ReturnValue;
end
function LocateBase()
-- try to locate that piece of code:
-- game.exe+26A98D - A1 C4D47000 - mov eax,[game.exe+30D4C4] //we want that game.exe+30D4C4
-- game.exe+26A992 - 85 C0 - test eax,eax //signature begins here
-- game.exe+26A994 - 74 62 - je game.exe+26A9F8
-- game.exe+26A996 - 8B 50 2C - mov edx,[eax+2C]
-- game.exe+26A999 - 89 55 D4 - mov [ebp-2C],edx
-- game.exe+26A99C - 33 D2 - xor edx,edx
-- game.exe+26A99E - E8 F502DDFF - call game.exe+3AC98
-- game.exe+26A9A3 - 66 C7 45 E8 0800 - mov word ptr [ebp-18],0008
-- game.exe+26A9A9 - 6A 00 - push 00
-- game.exe+26A9AB - 6A 00 - push 00
-- game.exe+26A9AD - 6A 00 - push 00
-- //after that, the global object should be at [[game.exe+30D4C4]+30]
local results=AOBScan("85 C0 74 62 8B 50 2C 89 55 D4 33 D2");
if (results==nil) then
print("Couldn't find the signature to locate the Base pointer");
return nil;
end
local count=stringlist_getCount(results);
if (count>1) then
print("Oops, looks like the 'unique' signature was found multiple times");
end
local address=stringlist_getString(results,0);
object_destroy(results);
results=nil;
return readInteger(getAddress(address)-4);
end
function Main()
local RootNodeAddr=readInteger(readInteger(LocateBase())+0x30);
print("RootNodeAddr ="..string.format("%x",RootNodeAddr));
--my test variable was f.used.now = 123654
local PointerWalker=GetMemberPtrByName(RootNodeAddr,"f");
PointerWalker=GetMemberPtrByName(readInteger(PointerWalker),"used");
PointerWalker=GetMemberPtrByName(readInteger(PointerWalker),"now");
if PointerWalker then
print("variable is at ="..string.format("%x",PointerWalker));
print("variable = "..readInteger(PointerWalker));
end
print("done");
end
Main() | Since variables can move around real easily, you'll just have to do create a timer to periodically redo the PointerWalker part and register a symbol to the resulting address. Just don't periodically call LocateBase (it's SLOW).
_________________
DO NOT PM me if you want help on making/fixing/using a hack. |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|