 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Filipe_Br Master Cheater
Reputation: 3
Joined: 07 Jan 2016 Posts: 272 Location: My house
|
Posted: Tue Nov 27, 2018 6:59 am Post subject: Crash program when calling Kernel sleep |
|
|
I know the cheat engine has a sleep function that works perfectly. But for a precise project I understand why this error only occurs when calling some functions.
Code: | alloc(func, $1000)
registersymbol(func)
createthread(func)
func:
push rbp
mov rbp,rsp
mov rcx,#2000
call Sleep
mov rsp,rbp
pop rbp
ret |
I have already checked the values of rsp and rbp, when the function returns and they correct.
The problem is to stack for some reason the Sleep function is changing the return value "(pointer) KERNEL32.BaseThreadInitThunk + 14". And this causes the thread not to return to where it should.
Although that code does not work, it works:
Code: | alloc(func, $1000)
registersymbol(func)
createthread(func)
func:
mov rcx,#2000
call Sleep
ret |
Is the problem that occurred because I put the value 0 in the stack (this is always rbp value) or because before calling Sleep I changed the value of rbp.
This fact of rbp always being at 0 should mean something, but found nothing about it. Just remembering that this problem only occurs in some functions.
_________________
... |
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 150
Joined: 06 Jul 2014 Posts: 4657
|
Posted: Tue Nov 27, 2018 8:38 am Post subject: |
|
|
Windows x64 ABI requires a 32-byte scratch space on the stack for all callees' register parameters.
Also, it's safer to let the thread manage memory deallocation.
Code: | alloc(foo,2048,kernel32.dll)
createthread(foo)
foo:
sub rsp,28
mov ecx,#10000
call kernel32.Sleep
// dealloc and kill thread
add rsp,28
mov rcx,foo
xor rdx,rdx
mov r8d,8000
jmp kernel32.VirtualFree |
The stack should be aligned on a 16-byte boundary at the time of the call, so take that into account if you're calling a function from a code injection.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Filipe_Br Master Cheater
Reputation: 3
Joined: 07 Jan 2016 Posts: 272 Location: My house
|
Posted: Tue Nov 27, 2018 10:02 am Post subject: |
|
|
ParkourPenguin wrote: | Windows x64 ABI requires a 32-byte scratch space on the stack for all callees' register parameters.
Also, it's safer to let the thread manage memory deallocation.
Code: | alloc(foo,2048,kernel32.dll)
createthread(foo)
foo:
sub rsp,28
mov ecx,#10000
call kernel32.Sleep
// dealloc and kill thread
add rsp,28
mov rcx,foo
xor rdx,rdx
mov r8d,8000
jmp kernel32.VirtualFree |
The stack should be aligned on a 16-byte boundary at the time of the call, so take that into account if you're calling a function from a code injection. |
The second code though does not crash the app, is it correct? or should I leave a scratch space on the stack?
Is there any reason for this code at the end? Is it really necessary? Code: | mov rcx,foo
xor rdx,rdx
mov r8d,8000 |
If my code is executed by 'executeCode' do I need this? Code: | jmp kernel32.VirtualFree |
_________________
... |
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 150
Joined: 06 Jul 2014 Posts: 4657
|
Posted: Tue Nov 27, 2018 10:23 am Post subject: |
|
|
Filipe_Br wrote: | The second code though does not crash the app, is it correct? or should I leave a scratch space on the stack? |
It's undefined behaviour if you don't leave scratch space for callees. That should be enough of a reason to avoid it.
Also, I didn't mention this explicitly, but I gave the stack 40 bytes (0x28) instead of 32 (0x20) to align it on a 16-byte boundary. If you're pushing the old stack frame pointer onto the stack, it's already aligned, so you only need to give it the required 32 bytes.
Filipe_Br wrote: | Is there any reason for this code at the end? Is it really necessary? |
That code is a tail call to VirtualFree. rcx, rdx, and r8d are parameters: lpAddress, dwSize, and dwFreeType respectively. Look at Microsoft's documentation for more information.
If you have a good reason to manage the memory yourself (e.g. calling it multiple times), then delete the tail call and return. Just make absolutely certain the memory cannot be freed while a thread is accessing it.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Filipe_Br Master Cheater
Reputation: 3
Joined: 07 Jan 2016 Posts: 272 Location: My house
|
Posted: Tue Nov 27, 2018 10:38 am Post subject: |
|
|
Thanks, your help was really very important.
I'm writing a plugin in Lua, it's actually not a plugin but a script that will be useful.
This script generates an assembly script to call API functions through Lua.
With your help some bugs were arranged.
Currently the script is able to call functions that receive or return integers, float, double, or string. But I intend to improve it, to support multi level pointer, vector and struct.
An example of use:
Code: | messagebox = createFunction("stdcall", "MessageBoxA", {"int32", "string", "string", "int32"}, "int32")
messagebox(0, "ola", "oi", 0) |
_________________
... |
|
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
|
|