View previous topic :: View next topic |
Author |
Message |
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Thu Jan 13, 2011 6:55 pm Post subject: Logging api calls |
|
|
Let's say you want to do what everyone has always dreamed about. Logging the next 10 PeekMessage api calls, there's just no api that's more interesting right ?
The function declaration of that routine is:
Code: |
BOOL PeekMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg
);
|
Code: |
pmAddress=getAddress("PeekMessageA");
count=0;
function debugger_onBreakpoint()
if (EIP == pmAddress) then
count = count + 1
ret=readInteger(ESP)
lpMsg=readInteger(ESP+4)
hWnd=readInteger(ESP+8)
wMsgFilterMin=readInteger(ESP+12)
wMsgFilterMax=readInteger(ESP+16)
wRemoveMsg=readInteger(ESP+20)
print("PeekMessage (lpMsg="..lpMsg.." hWnd="..hWnd.." wMsgFilterMin="..wMsgFilterMin.." wMsgFilterMax=".. wMsgFilterMax.." wRemoveMsg="..wRemoveMsg..") return address="..ret)
if count>=10 then
debug_removeBreakpoint(pmAddress);
end
return 1 --I handled it so don't tell the user
else
return 0 --unexpected breakpoint, show the the user
end
end
debug_setBreakpoint("PeekMessageA");
|
once this routine has been executed it will print out all the calls and the parameters that where given
You can probably extend it to read the LPMSG as well
If it doesn't seem to work, make sure you downloaded Cheat Engine after the date of this post (before it had some minor bugs)
_________________
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
Last edited by Dark Byte on Sun Apr 01, 2012 5:17 am; edited 1 time in total |
|
Back to top |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sat Jan 15, 2011 11:00 am Post subject: |
|
|
can i hook winsock that way? send,recv functions?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sat Jan 15, 2011 11:24 am Post subject: |
|
|
sure.
It's probably easier to use the packet editor plugin though or base of something off that source. ( sourceis in 5.6.1, but should be portable/compatible with ce 6)
Anyhow, if you want to use this method keep in mind that the function you want to watch is "ws2_32.send" / "ws2_32.recv" instead of just "send/recv"
Or if you want to actually hook it instead of debugging, I recommend using the "generateAPIHookScript" routine (this routine takes strings only as addresses)
_________________
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 |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sat Jan 15, 2011 2:12 pm Post subject: |
|
|
so the structure is:
Code: | int send(
__in SOCKET s,
__in const char *buf,
__in int len,
__in int flags
); |
the function is ws2_32.send
I've tried to write hook and it looks like this:
Code: | pmAddress=getAddress("ws2_32.send");
count=0;
function debugger_onBreakpoint()
if (EIP == pmAddress) then
count = count + 1
ret=readInteger(ESP)
s=readInteger(ESP+4)
len=readInteger(ESP+12)
buf=readString(readInteger(ESP+8),len)
flags=readInteger(ESP+16)
print("send (s="..s.." buf="..buf.." len="..len.." flags=".. flags..") return address="..ret)
if count>=100 then
debug_removeBreakpoint("ws2_32.send");
end
return 1 --I handled it so don't tell the user
else
return 0 --unexpected breakpoint, show the the user
end
end
debug_setBreakpoint("ws2_32.send"); |
//the code works wow Dark Byte Rulez!!
so my new question is how to call functions?
should i write to EIP the address of send when its equal to zero? and then write to ESP that what I want?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sat Jan 15, 2011 5:51 pm Post subject: |
|
|
well, you could decrease esp by the amount of bytes the parameters take, fill in those bytes and adjust eip to the function you want to call, or you could just change eip to a routine you wrote yourself
Or you could just start off from scratch without debugging on a routine you hooked
Here is a method of hooking api's that I prefer. I use this method in almost all the hooking mechanisms inside ce from speedhack to memory alloc hooking:
Code: |
autoAssemble([[
globalalloc(MyPeekMessageHook,2048)
globalAlloc(OriginalPeekMessageA,4)
label(placeyourbphereifyouliketoseetheresults)
registersymbol(placeyourbphereifyouliketoseetheresults)
MyPeekMessageHook:
//do whatever you want in your hook
//I could just do jmp [OriginalPeekMessageA] if I wanted
//but this way the parameters are more easily readable for me
//and lets me mess with the results
push ebp
mov ebp,esp
//ebp=old ebp
//ebp+4=old return address
//ebp+8=first parameter
//ebp+c=second
//ebp+10=third
//ebp+14=fourth
//ebp+18=fifth
push [ebp+18]
push [ebp+14]
push [ebp+10]
push [ebp+c]
push [ebp+8]
call [OriginalPeekMessageA]
placeyourbphereifyouliketoseetheresults:
//eax now contains the return value.
//and this space gives you room to tamper with the results
pop ebp//restore ebp to what it was
ret 14 //undo the pushed parameters and return
]]
)
myhookscript=generateAPIHookScript("PeekMessageA", "MyPeekMessageHook", "OriginalPeekMessageA");
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end
|
you can also use generateAPIHookScript on dllname exports of a dll you injected.
and if you do want to combine it with debugging just add in a registersymbol call in the aa script for a label at the begin and/or end of the routine and evaluate the results there (just set the breakpoint on the name of the registered symbol)
_________________
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 |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sun Jan 16, 2011 4:17 am Post subject: |
|
|
but Your script is like a filter of parameters, I want to know how to call the original function with my own parameters whenever I want(if it is possible)
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sun Jan 16, 2011 5:04 am Post subject: |
|
|
then you just replace
Code: |
push [ebp+18]
push [ebp+14]
push [ebp+10]
push [ebp+c]
push [ebp+8]
|
with your own parameters
_________________
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 |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sun Jan 16, 2011 5:12 am Post subject: |
|
|
so I have to fill:
Code: | //ebp=old ebp
//ebp+4=old return address
//ebp+8=first parameter
//ebp+c=second
//ebp+10=third
//ebp+14=fourth
//ebp+18=fifth |
with my own parameters?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sun Jan 16, 2011 5:16 am Post subject: |
|
|
No, you can just leave those alone. Those are the callers parameters
You have to input new parameters on new stack positions
so push the last parameter first
then the one before it
etc...
and then call the api you want to call
so instead of push [ebp+18] you'd do , push myaddress or push #100 or whatever you want to give as parameter
---
and as I've said before this is a lot easier done in combination of dll injection. You just have to export one pointer and your hook routine, and when your hook routine wants to call the original function it would just need to call that pointer with the correct function type definition.
Makes keeping track of stuff and memory allocations more easy as well
_________________
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 |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sun Jan 16, 2011 5:56 am Post subject: |
|
|
I've tried to do what you said, and I wrote code that doesn't works:
Code: |
autoAssemble([[
globalalloc(MyMessageBoxHook,2048)
globalalloc(message,10)
globalalloc(caption,2)
globalalloc(OriginalMessageBoxA,4)
writeString(message,"blablablaa");
writeString(caption,"XD");
MyMessageBoxHook:
push ebp
mov ebp,esp
push #0
push [caption]
push [message]
push #0
call [OriginalMessageBoxA]
pop ebp
ret 14
]]
)
myhookscript=generateAPIHookScript("MessageBoxA", "MyMessageBoxHook", "OriginalMessageBoxA");
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end |
idk what's wrong with this code, can You help me?
|
|
Back to top |
|
|
GH*master Expert Cheater Reputation: 8
Joined: 10 Jan 2008 Posts: 159
|
Posted: Sun Jan 16, 2011 6:16 am Post subject: HI |
|
|
Thanks for this tutorial, Dark Byte. Very impressive
Last edited by GH*master on Sun Jan 16, 2011 6:38 am; edited 1 time in total |
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sun Jan 16, 2011 8:01 am Post subject: |
|
|
you're using lua code inside auto assembler code
instead of "writeString(message,"blablablaa"); " use
Code: |
message:
db 'blablablaa',0
|
and instead of
writeString(caption,"XD") use
which also shows that you need to increase the allocations by 1 on each alloc (and you can just use alloc if you only want to use those addresses in the script)
also, because the function only takes 16 bytes as parameters, you should use ret 10
and MessageBoxA requires a pointer to a string, not the string itself so remove the brackets around them
so, this script should work better:
Code: |
autoAssemble([[
globalalloc(MyMessageBoxHook,2048)
alloc(message,11)
alloc(caption,3)
globalalloc(OriginalMessageBoxA,4)
message:
db 'blablablaa',0
caption:
db 'XD',0
MyMessageBoxHook:
push ebp
mov ebp,esp
push #0
push caption
push message
push #0
call [OriginalMessageBoxA]
pop ebp
ret 10
]]
)
myhookscript=generateAPIHookScript("MessageBoxA", "MyMessageBoxHook", "OriginalMessageBoxA");
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end
|
_________________
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 |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sun Jan 16, 2011 11:06 am Post subject: |
|
|
So, the code works, but it's not exactly that what I wanted, I'd like to call MessageBox from Cheat Engine, but I want Cheat Engine to show message box when I click "Execute now" button. Sorry for the problems
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
Posted: Sun Jan 16, 2011 1:55 pm Post subject: |
|
|
Use showMessage(msg) then.
Example:
Code: | showMessage("Hello world!"); |
_________________
- Retired. |
|
Back to top |
|
|
Demolish Cheater Reputation: 0
Joined: 27 Dec 2010 Posts: 32
|
Posted: Sun Jan 16, 2011 2:02 pm Post subject: |
|
|
Wiccaan wrote: | Use showMessage(msg) then.
Example:
Code: | showMessage("Hello world!"); |
|
this isn't that easy, I'd like to know how to hook functions, not only ShowMessage, but send,recv functions of winsock
|
|
Back to top |
|
|
|