 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
ThereIsNoSpoon How do I cheat?
Reputation: 0
Joined: 27 Oct 2015 Posts: 8 Location: DWORD PTR
|
Posted: Tue Oct 27, 2015 2:04 pm Post subject: [C++] inline asm, pointers, structures, native code... uff |
|
|
Hey guys,
I might be new to you guys but this forum is definately not new to me. I've been visiting this place for many years - one of my favourite places in the internet.
Untill this moment, I had no reason to post, I've been doing quite fine.
CE is really amazing tool, giving us so much and automating so much for us. Something really brilliant! (Thank you DarkByte, you're my idol).
But finally, I would to do something on my own, starting from a scratch.
I took Torch Light 2 (single player) as my target. The game is quite simple, unprotected - seem to be perfect a place to flex my c++ / hacking skills.
I've already did some homework, analysed and identified part of PlayerStruct. I've also did pattern search, to find the right place to intercept pointer address, but then I hit the wall.
At the moment I can't just figure out on my own, how to:
- use inline asm to intercept native game code and use it to get a pointer of out one of registers (doing fine in autoassembly)
- reverse and use typedef functions to use native game code.
- assign memory address to my already defined PlayerStruct so i can use arrow pointers, intead of memcpy (that's what the masters did in D Hackit, isn't it?)
This is the code I've already made. Just please note, it is still crashing the game in many cases.
Pointer I am looking for is hiding in ESI. So easy to intercept using CE.
CommonStructs.h
Code: | #include <wtypes.h>
typedef struct PlayerInfoStruct_t {
BYTE Unknown1[0x558];
FLOAT HP;
DWORD HPBonus;
DWORD HPBonus2;
FLOAT Something1;
DWORD Armor;
DWORD Dexterity;
DWORD Strength;
DWORD Vitality;
DWORD Focus;
DWORD MP;
DWORD MPBonus;
DWORD Sommething2;
DWORD Gold;
DWORD Experience;
DWORD Fame;
DWORD FameLevel; // 0x00 - 0x34
BYTE Unknown4[0x0C];
DWORD StatPoints;
DWORD SkillPoints;
} PLAYERINFOSTRUCT, *pPLAYERINFOSTRUCT; |
DllMain.cpp
Code: | typedef void (__cdecl* _AddFocus)();
DWORD SearchPattern(char* chPattern, DWORD dwFrom, DWORD dwTo)
{
DWORD dwOffset = dwFrom;
DWORD dwSize = strlen(chPattern) - 1;
DWORD dwFoundAddress = 0;
char * pEnd = chPattern;
while (1)
{
char &chMyposition = *(char*)dwOffset;
if ((pEnd[1] != 'x'))
{
char chTemp = (char)strtoul(pEnd, &pEnd, 0x10);
if (chTemp == chMyposition)
{
if (dwFoundAddress == 0)
{
dwFoundAddress = dwOffset;
}
}
else
{
pEnd = chPattern;
if (dwFoundAddress != 0)
dwOffset = dwFoundAddress;
dwFoundAddress = 0;
}
}
else
{
pEnd = &pEnd[2];
}
dwOffset++;
if (((DWORD)pEnd - (DWORD)chPattern >= dwSize) || (dwOffset >= dwTo))
break;
}
return dwFoundAddress;
}
unsigned int __stdcall TorchLightInit(void* pParam) {
PLAYERINFOSTRUCT* pis;
DWORD fnStatPointAddFocus = 0x00509DB0;
DWORD dwAddFocus = 0;
char buf[128];
dwAddFocus = SearchPattern("56 8B F1 8B 86 A0 05 00 00 85 C0 7E 2A FF 86 78", 0x00400000, 0x007FFFFFF);
if (dwAddFocus != 0) {
sprintf_s(buf, "0x%08X", dwAddFocus);
MessageBoxA(0, "dwAddFocus", buf, MB_OK);
// my approach to use a native game code...
((_AddFocus)dwAddFocus)(); // not matter how do I define this function, always crashing the game.
}
//BYTE pChat[] = { 0x55, 0x8B, 0xEC, 0x83, 0x3D, 0x48, 0x2B, 0x86, 0x00, 0x00, 0x74, 0x17, 0x8B, 0x45, 0x10, 0x50 };
//char * mChat = "xxx????????xxxx";
//Chat_add = dwFindPattern(0x00400000, 0x00700000, pChat, mChat);
return NULL;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
_beginthreadex(NULL, 0, &TorchLightInit, NULL, NULL, NULL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
} |
This is the function described by me as a AddFocus.
Code: | 00509DB0 - 56 - push esi
00509DB1 - 8B F1 - mov esi,ecx
00509DB3 - 8B 86 A0050000 - mov eax,[esi+000005A0]
00509DB9 - 85 C0 - test eax,eax
00509DBB - 7E 2A - jle 00509DE7
00509DBD - FF 86 78050000 - inc [esi+00000578]
00509DC3 - 48 - dec eax
00509DC4 - 89 86 A0050000 - mov [esi+000005A0],eax
00509DCA - E8 21D41D00 - call 006E71F0
00509DCF - C6 80 4A020000 01 - mov byte ptr [eax+0000024A],01
00509DD6 - 8B B6 C8050000 - mov esi,[esi+000005C8]
00509DDC - 85 F6 - test esi,esi
00509DDE - 74 07 - je 00509DE7
00509DE0 - C6 86 ED000000 01 - mov byte ptr [esi+000000ED],01
00509DE7 - 5E - pop esi
00509DE8 - C3 - ret |
Does the "ret" always mean return value or is just there due to CALL inside the game code?
I would also know, how to define a structure and then assing to it specific memory addres so I can use arrow pointers, instead of memory editing.
And finally, I would like to say sorry, excusing you guys, as I am a bit drunk at the moment I am writing this post.
Any kind of help you provide will be greatly appreciated.
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
Posted: Tue Oct 27, 2015 2:59 pm Post subject: |
|
|
Not sure if you are using the Steam version of TL2 or not, but there is protection on it. It uses SteamDRM (aka SteamStub) variant 2. It has some minor anti-cheat measures, mostly from debugging purposes but they are all easily bypassed. If you use a cracked version of the game it is probably already unpacked from the DRM anyway. If you are using the Steam version and want to unpack the file, you can check out my Steamless project here:
https://github.com/atom0s/Steamless.NET
For the official Steam version, the similar function you are looking at is as follows:
Code: | Torchlight2.exe+127A50 - 56 - push esi
Torchlight2.exe+127A51 - 8B F1 - mov esi,ecx
Torchlight2.exe+127A53 - 8B 86 A8050000 - mov eax,[esi+000005A8]
Torchlight2.exe+127A59 - 85 C0 - test eax,eax
Torchlight2.exe+127A5B - 7E 35 - jle Torchlight2.exe+127A92
Torchlight2.exe+127A5D - FF 86 78050000 - inc [esi+00000578]
Torchlight2.exe+127A63 - 48 - dec eax
Torchlight2.exe+127A64 - 89 86 A8050000 - mov [esi+000005A8],eax
Torchlight2.exe+127A6A - E8 71321D00 - call Torchlight2.exe+2FACE0
Torchlight2.exe+127A6F - C6 80 4A020000 01 - mov byte ptr [eax+0000024A],01 { 1 }
Torchlight2.exe+127A76 - 8B 86 D0050000 - mov eax,[esi+000005D0]
Torchlight2.exe+127A7C - 85 C0 - test eax,eax
Torchlight2.exe+127A7E - 74 07 - je Torchlight2.exe+127A87
Torchlight2.exe+127A80 - C6 80 ED000000 01 - mov byte ptr [eax+000000ED],01 { 1 }
Torchlight2.exe+127A87 - 8B CE - mov ecx,esi
Torchlight2.exe+127A89 - E8 F2FEFFFF - call Torchlight2.exe+127980
Torchlight2.exe+127A8E - B0 01 - mov al,01 { 1 }
Torchlight2.exe+127A90 - 5E - pop esi
Torchlight2.exe+127A91 - C3 - ret
Torchlight2.exe+127A92 - 32 C0 - xor al,al
Torchlight2.exe+127A94 - 5E - pop esi
Torchlight2.exe+127A95 - C3 - ret
|
Which shows that there is a return value being used. Looking at how it is called, we can see the following as well:
Code: | call sub_412F60
mov ecx, [eax+2Ch]
call sub_527A50
sub ebp, 1
jnz short loc_77D860 |
So ECX is being populated, so we can assume this is going to be a __thiscall function where ecx holds a class object pointer. We also see a return value is being checked with the jump.
In IDA the signature of the function is seen as:
Code: | char __thiscall sub_527A50(int this) |
_________________
- Retired. |
|
Back to top |
|
 |
ThereIsNoSpoon How do I cheat?
Reputation: 0
Joined: 27 Oct 2015 Posts: 8 Location: DWORD PTR
|
Posted: Wed Oct 28, 2015 7:02 am Post subject: |
|
|
Thanks for your reply and for pointing me out all of these things.
Also thanks for sharing with me your Steamless tool. Works awesome!
I am working with Torchlight II v1.9.5.1, cracked by RELOADED.
- calling native functions by function pointers
I have learned a bit about calling functions from injected dlls using function pointers. Now I am able to call all the native functions on my own
You were almost right about the function definition, but definitely sure about the calling method. The only difference is this
Code: | typedef int (__thiscall* tAddFocus)(PLAYERINFOSTRUCT* pThis); |
EDIT: After doing some research, I can tell that you were completely right about the function definition.
Code: | char __thiscall sub_527A50(int this)
// CHAR can be used as a BYTE long representation of INT
// (int this) ints are commonly used by IDA to represent pointers
|
- using class / struct by pointers
Now I also know how to rebuild and use pointers to my own class / struct and simplify all the work by using arrow pointers, instead of annoying memory editing, to modify different variables in memory.
Something beautiful.
- inline asm
Still looking for a simple example of how to use inline asm to intercept data from registers. I assume we do it same way as we always did in autoassembly;
- place a jmp to copy of code,
- register jmp_back,
- execute the copy of code,
- jump back to original code.
But how to write it in inline asm? -.-
Looking forward for more of your replies. Can't wait to sort it out!
[===========EDIT==============]
All now works perfectly fine, native game function is beeing called and I have a direct access to my struct.
This is my revised code.
Code: | #include "CommonStructs.h"
#include <process.h>
// just for now I made it all static, todo: SearchPattern, Inline asm.
DWORD dwfnAddFocus = 0x00509DB0;
DWORD dwPlayerInfo = 0x08933000;
// this is it! game does not crash, native function is being executed!
typedef int (__thiscall* tAddFocus)(PLAYERINFOSTRUCT* pThis);
tAddFocus oAddFocus = (tAddFocus)dwfnAddFocus;
unsigned int __stdcall TorchLightInit(void* pParam) {
PLAYERINFOSTRUCT* pPIS = (PLAYERINFOSTRUCT*)dwPlayerInfo;
while (true) {
// calling native game function! :)
oAddFocus(pPIS);
Sleep(1000);
// modifying data inside my struct :)
pPIS->Strength += rand() % 3;
pPIS->Dexterity += rand() % 3;
pPIS->Focus += rand() % 3;
Sleep(1000);
}
return NULL;
} |
|
|
Back to top |
|
 |
ThereIsNoSpoon How do I cheat?
Reputation: 0
Joined: 27 Oct 2015 Posts: 8 Location: DWORD PTR
|
Posted: Fri Oct 30, 2015 2:40 pm Post subject: |
|
|
Now this is something even better!
Instead of passing pointer to your struct or class every time you call a native game function with 'this' parameter, you can do something like this:
Code: | typedef int (__thiscall* tAddFocus)(void* pThis);
typedef class CPlayer {
public:
BYTE Unknown1[0x558];
FLOAT HP;
DWORD HPBonus;
DWORD HPBonus2;
FLOAT Something1;
DWORD Armor;
DWORD Dexterity;
DWORD Strength;
DWORD Vitality;
DWORD Focus;
DWORD MP;
DWORD MPBonus;
DWORD Sommething2;
DWORD Gold;
DWORD Experience;
DWORD Fame;
DWORD FameLevel; // 0x00 - 0x34
BYTE Unknown4[0x0C];
DWORD StatPoints;
DWORD SkillPoints;
int fnAddFocus() {
tAddFocus oAddFocus = (tAddFocus)0x00509DB0;
return oAddFocus(this);
}
} *pPlayer; |
And then you can simply call the function from inside of your class.
Code: | CPlayer* pPlayer = (CPlayer*)dwPlayerInfo;
// native game function called from inside of your class
pPlayer->fnAddFocus();
// 10 extra level up, some extra stat and skill points just by arrow pointer
pPlayer->Level += 10;
pPlayer->StatPoints = 1000;
pPlayer->SkillPoints = 1000; |
This is amazing!
All I would like to learn right now is a sufisticated and elegant method of getting pointers from registers in inline asm manner. I am a bit bored of getting pointers by pointers to pointers of pointers by memory reading.
btw. I have noticed that I have posted my topic in section of General Game Hacking for CE. My bad.
Can I have this topic moved to General Programming Section, please?
Sorry for the trouble.
|
|
Back to top |
|
 |
atom0s Moderator
Reputation: 205
Joined: 25 Jan 2006 Posts: 8587 Location: 127.0.0.1
|
|
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
|
|