View previous topic :: View next topic |
Author |
Message |
661089799107 Expert Cheater
Reputation: 3
Joined: 25 Jan 2009 Posts: 186
|
Posted: Thu Dec 13, 2012 2:00 pm Post subject: Calling game function & thread local storage |
|
|
So I'm trying to call a game function. However this particular one is causing the game to crash.
I used the "Break and trace instructions" to see why.
Comparing a call from the game by doing the required action, and calling the function with the Auto Assemble.
And this is where it seems to go wrong. (several functions deep)
Code: |
mov eax, fs:[00000018] // Linear address of TIB
mov ecx, [ebp+08]
and dword ptr [eax+34], 00 // Last error number (?)
cmp ecx, 40
jae 7575F4A6 // Doesn't jump from either AA call or normal call
// EAX = 7FFDF000 (game call), EAX = 7FFA6000 (AA call)
// ECX = 8
mov eax, [eax+ecx*4+00000E10]
// EAX is now 0 when calling with AA, and then it is later dereferenced causing an exception. It was 0x002350B0 when the game called it.
|
So from what i understand: the last instruction in the above code block is accessing the Thread Information Block with the offset of 0xE30 (8*4+E10).
I believe this would be thread local storage (TLS)?
What would be the best way to call the function without it crashing?
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25804 Location: The netherlands
|
Posted: Thu Dec 13, 2012 2:18 pm Post subject: |
|
|
I've never used this method so not sure if it works, but suspend the process and look for a thread that isn't waiting for some kind of event (might take several tries), then store the state and change eip to your injected code that calls the function , upon return restore the state to the original
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
661089799107 Expert Cheater
Reputation: 3
Joined: 25 Jan 2009 Posts: 186
|
Posted: Thu Dec 13, 2012 2:45 pm Post subject: |
|
|
Thanks for the quick response.
Sorry. I should of been more clear.
While that sounds like it should work: I'd like to do this without having to do it manually. As I am doing this from within the game process, and using my injected DLL to automate my character. I was using the Auto Assembly to see why it wasn't working.
|
|
Back to top |
|
 |
n0 m3rcY Cheater
Reputation: 0
Joined: 18 Jun 2012 Posts: 42
|
Posted: Thu Dec 13, 2012 5:12 pm Post subject: |
|
|
What was ebp earlier in the proc?
|
|
Back to top |
|
 |
661089799107 Expert Cheater
Reputation: 3
Joined: 25 Jan 2009 Posts: 186
|
Posted: Thu Dec 13, 2012 7:32 pm Post subject: |
|
|
n0 m3rcY wrote: | What was ebp earlier in the proc? |
The function was set up with a standard stack frame.
Edit: I guess I should be able to find where the thread that accesses this function is created. Then I can store the thread handle, and use the method Dark Byte mentioned.
- DebugActiveProcess
- SuspendThread
- GetThreadContext (backup registers)
- SetThreadContext (modify EIP to my code, ending with a 0xCC BP?)
- ResumeThread
- WaitForDebugEvent
- SetThreadContext (restore registers)
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25804 Location: The netherlands
|
Posted: Fri Dec 14, 2012 3:59 am Post subject: |
|
|
If you're doing it from inside a dll then DebugActiveProcess won't work.
Anyhow, you only need SetThreadContext once.
1: SuspendThread
2: GetThreadContext.
3: Check if thread was in waiting state. If Yes, ResumeThread and goto 1 (perhaps send it a message to awaken it as well)
4: Save context to a static/hardcoded location
5: SetThreadContext to new eip
Your code:
1: Do stuff
2: When done, read the state from the known location
3: Setup the registers to what they should be (do not use registers to store the address, use direct addresses only)
4: Jump to the eip address store in the context at the known location (jmp [AddressOfStoredContextEIP] )
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
661089799107 Expert Cheater
Reputation: 3
Joined: 25 Jan 2009 Posts: 186
|
Posted: Fri Dec 14, 2012 11:31 am Post subject: |
|
|
Thank you. I got it working
Code: |
_declspec(naked) void mainThread_useItem()
{
__asm
{
PUSHAD
push [selectedItem_addr]
call [useItem_addr]
POPAD
JMP [contextBackup.Eip]
};
}
|
Code: |
void useItem(int pos)
{
*pSelectedItem = pos;
callFunctionFromMainThread(reinterpret_cast<DWORD>(&mainThread_useItem));
}
|
Code: |
void callFunctionFromMainThread(DWORD newEIP)
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, mainThreadID);
if(!hThread)
{
std::cout << "[Error] OpenThread\n";
return;
}
// Suspend thread so we can change the EIP
if(SuspendThread(hThread) == -1)
{
std::cout << "[Error] SuspendThread\n";
return;
}
contextBackup.ContextFlags = CONTEXT_FULL;
// Backup registers
if(!GetThreadContext(hThread, &contextBackup))
{
std::cout << "[Error] GetThreadContext\n";
if(ResumeThread(hThread) == -1)
{
std::cout << "[Error] ResumeThread\n";
}
return;
}
DWORD oldEIP = contextBackup.Eip;
// Set new EIP
contextBackup.Eip = newEIP;
if(!SetThreadContext(hThread, &contextBackup))
{
std::cout << "[Error] SetThreadContext\n";
if(ResumeThread(hThread) == -1)
{
std::cout << "[Error] ResumeThread\n";
}
}
contextBackup.Eip = oldEIP;
// Resume execution (in our code)
ResumeThread(hThread);
}
|
|
|
Back to top |
|
 |
TsTg Master Cheater
Reputation: 5
Joined: 12 Dec 2012 Posts: 340 Location: Somewhere....
|
Posted: Fri Dec 14, 2012 9:52 pm Post subject: |
|
|
Would a technique like this work with a game that uses integrity checks on its executable code ??
I would like to program a DLL that can inject any custom code in a certain location in game code, here's my idea:
1- Create my watching thread in the target process(via DLL inject or CreateRemoteThread)
2- Constantly Susupend the target thread and get the Thread context
3- compare if EIP is my taget address, then redirect it if euqal(SetThreadContext)
4- in my custom code i put JMP DWORD [Original EIP+next command offset]
5- Resume the thread
But my question is would that affect the game speed as am constantly suspending and resuming it's thread ??
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25804 Location: The netherlands
|
Posted: Sat Dec 15, 2012 4:16 am Post subject: |
|
|
No, that will not work.
The time between resuming the process and suspending it again is too big, it may have already executed that function 10 times, or 0 times if no context switch had happened inbetween
If it worked it wouldn't slow down the game too much (as suspending and resuming it happens in the running context of another thread so that thread was most likely not even running at that time)
But yeah, it won't work because this is too inaccurate.
One method that does work is set the trap flag and capture every single step exception. This will of course make the game run at 0.00000001 frames per day
Blecknight:
You might want to do a pushfd/popfd as well, in case you break right after a compare and before a conditional jump
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
 |
|