|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
movss Cheater Reputation: 0
Joined: 10 Feb 2018 Posts: 38
|
Posted: Sun Feb 11, 2018 7:47 am Post subject: use apihook in AA |
|
|
I written in Lua script can work, so I want to write with AA
----------
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
globalalloc(mymsg,100)
alloc(text,10)
globalalloc(orimsg,4)
text:
db 'hooked',0
mymsg:
push ebp
mov ebp,esp
push 0
push text
push text
push 0
call [orimsg]
pop ebp
ret 10
{$lua}
myhookscript=generateAPIHookScript("MessageBoxA", "mymsg", "orimsg")
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(text)
MessageBoxA:
db 89 FF 55 89 E5
----------
But it doesn't work, why?
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
|
Back to top |
|
|
movss Cheater Reputation: 0
Joined: 10 Feb 2018 Posts: 38
|
Posted: Sun Feb 11, 2018 7:50 am Post subject: |
|
|
I see, the end should be {$asm}
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Sun Feb 11, 2018 9:43 am Post subject: |
|
|
That too. As I said earlier, Lua blocks are executed first. Unfortunately, in your script, generateAPIHookScript expects that mymsg exists. It doesn't.
The proper way would be something like this.
Code: | [ENABLE]
alloc(mymsg,256)
label(orimsg)
label(text)
registersymbol(mymsg)
registersymbol(orimsg)
mymsg:
push 0
push text
push text
push 0
call [orimsg]
ret 10
text:
db 'hooked',0
orimsg:
dd 0
alloc(origMessageBoxABytes,32)
registersymbol(origMessageBoxABytes)
origMessageBoxABytes:
readmem(MessageBoxA,32)
{$lua}
if syntaxcheck then return end
local timer = createTimer()
timer.Interval = 50
timer.OnTimer = function (t)
t.destroy()
if memrec.Active then
local myhookscript = generateAPIHookScript("MessageBoxA", "mymsg", "orimsg")
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end
end
end
{$asm}
[DISABLE]
MessageBoxA:
readmem(origMessageBoxABytes,32)
unregistersymbol(mymsg)
unregistersymbol(orimsg)
unregistersymbol(origMessageBoxABytes)
dealloc(mymsg)
dealloc(origMessageBoxABytes) |
Lua block uses a timer object. Few things will happen in this order:
- timer object will be created
- AA script executed
- the rest of Lua code executed (the part inside OnTimer function)
Because there's no "UnHooking", we have to manually store few original bytes of MessageBoxA and restore them when deactivating the script.
EDIT:
After digging more, it look likes we can trick generateAPIHookScript and just use "0" and then replace "jmp 0" with "jmp addressToJumpTo".
We do not need timer object anymore!
Lua block must be placed just after alloc line, i.e. alloc(addressToJumpTo)
In DISABLE section we can use dealloc(originalcall0), that way we do not get memory leaks.
Example script with hooking and unhooking MessageBoxA:
Code: | {$strict}
[ENABLE]
alloc(mymsg,256)
{$lua}
-- NOTE: this generated code will use originalcall0 and returnhere0
-- do not declare labels/symbols with such names
local myhookscript = generateAPIHookScript("MessageBoxA", "0") or ''
return myhookscript:gsub('jmp 0\r\n','jmp mymsg\r\n')
{$asm}
label(orimsg)
label(text)
registersymbol(mymsg)
registersymbol(orimsg)
mymsg:
push 0
push text
push text
push 0
call [orimsg]
ret 10
text:
db 'hooked',0
orimsg:
dd originalcall0
alloc(origMessageBoxABytes,32)
registersymbol(origMessageBoxABytes)
origMessageBoxABytes:
readmem(MessageBoxA,32)
[DISABLE]
MessageBoxA:
readmem(origMessageBoxABytes,32)
unregistersymbol(mymsg)
unregistersymbol(orimsg)
unregistersymbol(origMessageBoxABytes)
dealloc(mymsg)
dealloc(origMessageBoxABytes)
dealloc(originalcall0) |
_________________
|
|
Back to top |
|
|
movss Cheater Reputation: 0
Joined: 10 Feb 2018 Posts: 38
|
Posted: Sun Feb 11, 2018 5:03 pm Post subject: |
|
|
mgr.inz.Player wrote: | Lua blocks are executed first.
Also, you have to treat those Lua blocks as text p
|
i think it is not that ,,
When the hook script is generated, it points to two addresses, and the two addresses must exist in advance. The first is the API function entry address. the second address is used as a jump address, I have observed,
it contains
mov edi,edi
push ebp
mov ebp,esp
jmp somewhere
so it saves the top 5 bytes of API function , cannot read his address when cancel api hook, directly write the 5 byte will be ok
|
|
Back to top |
|
|
movss Cheater Reputation: 0
Joined: 10 Feb 2018 Posts: 38
|
Posted: Mon Feb 12, 2018 3:00 am Post subject: |
|
|
mgr.inz.Player wrote: | That too. As I said earlier, Lua blocks are executed first. Unfortunately, in your script, generateAPIHookScript expects that mymsg exists. It doesn't.
|
according my text,before hooking, make sure the first 5 bytes of the api function are not hooked
below code are simple and usrful
Code: |
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
{$lua}
myhook=[[
MessageBoxA:
db 8B FF 55 8B EC // make sure is unhooking ,
globalalloc(mymsg,100)
alloc(text,10)
globalalloc(orimsg,4)
text:
db 'hooked',0
mymsg:
push ebp
mov ebp,esp
push 0
push text
push text
push 0
call [orimsg]
pop ebp
ret 10
]]
autoAssemble(myhook)
myhookscript=generateAPIHookScript("MessageBoxA", "mymsg", "orimsg")
if (myhookscript~=nil) then
autoAssemble(myhookscript)
end
{$asm}
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(text)
MessageBoxA:
db 89 FF 55 89 E5
|
_________________
A wild programmer |
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Feb 12, 2018 10:41 am Post subject: |
|
|
movss wrote: | Code: |
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
{$lua}
myhook=[[
MessageBoxA:
db 8B FF 55 8B EC // make sure is unhooking ,
...
...
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(text)
MessageBoxA:
db 89 FF 55 89 E5
|
|
"db 8B FF 55 8B EC" and "db 89 FF 55 89 E5". Something is wrong.
Also, MessageBoxA can have different bytes at the beginning, it depends on dll version..
I think my solution (second script in my previous post) is more universal, it should work on any 32bit MessageBoxA version.
_________________
|
|
Back to top |
|
|
movss Cheater Reputation: 0
Joined: 10 Feb 2018 Posts: 38
|
Posted: Thu Feb 15, 2018 5:30 am Post subject: |
|
|
mgr.inz.Player wrote: | movss wrote: | Code: |
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
{$lua}
myhook=[[
MessageBoxA:
db 8B FF 55 8B EC // make sure is unhooking ,
...
...
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(text)
MessageBoxA:
db 89 FF 55 89 E5
|
|
"db 8B FF 55 8B EC" and "db 89 FF 55 89 E5". Something is wrong.
Also, MessageBoxA can have different bytes at the beginning, it depends on dll version..
I think my solution (second script in my previous post) is more universal, it should work on any 32bit MessageBoxA version. |
Normally, the first 5 bytes of a function are fixed,
Mov EDI, EDI(Why is there a mov edi edi? That is to be prepared by hook)
Push EBP
Mov EBP, ESP
also ,you can use readmem(address ,5) before hook
_________________
A wild programmer |
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Fri Feb 16, 2018 1:43 pm Post subject: |
|
|
Anyway. I prefer my method.
generateAPIHookScript returns something like this:
Code: | print( generateAPIHookScript("MessageBoxA", "0") )
alloc(originalcall0,2048)
label(returnhere0)
originalcall0:
mov edi,edi
push ebp
mov ebp,esp
jmp returnhere0
MessageBoxA:
jmp 0
returnhere0: |
Then I replaced "jmp 0" with "jmp mymsg" by using Lua string.gsub:
Code: | myhookscript:gsub('jmp 0\r\n','jmp mymsg\r\n') |
So, whole script looks like this (after Lua preprocessing):
Code: | {$strict}
[ENABLE]
alloc(mymsg,256)
alloc(originalcall0,2048)
label(returnhere0)
originalcall0:
mov edi,edi
push ebp
mov ebp,esp
jmp returnhere0
MessageBoxA:
jmp mymsg
returnhere0:
label(orimsg)
label(text)
registersymbol(mymsg)
registersymbol(orimsg)
mymsg:
push 0
push text
push text
push 0
call [orimsg]
ret 10
text:
db 'hooked',0
orimsg:
dd originalcall0
alloc(origMessageBoxABytes,32)
registersymbol(origMessageBoxABytes)
origMessageBoxABytes:
readmem(MessageBoxA,32)
[DISABLE]
MessageBoxA:
readmem(origMessageBoxABytes,32)
unregistersymbol(mymsg)
unregistersymbol(orimsg)
unregistersymbol(origMessageBoxABytes)
dealloc(mymsg)
dealloc(origMessageBoxABytes)
dealloc(originalcall0) |
- there's no memory leaking because every allocated memory is deallocated after deactivating memory record,
- no need to use globalalloc. globalalloc is problematic in some scenarios, ask anyone who is making CT compilation (many AA scripts from different authors)
_________________
|
|
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
|
|