MadCode Hook didn't work on WINME
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
MadCode Hook didn't work on WINME
Hi there,
i just tried an application that hooks an API within the application only, NOT a System Wide hook, and it didn't work the first time, but worked after i closed it and re-stared the application, so which isn't good.
so i need to know does madcodehook installs something into the system first? and the application have to restart after the first time?
second HOW can i tell if the hook failed from within my application so i can try to re-hook again without having to restart the application? do i just use the longBool returned by HookAPI, and if it didn't hook the first do i have to use HookAPI again or should i use RenewHook instead?
I noticed this on WINME, so I'm not sure if it has the same effect on other systems.
Thanks,
i just tried an application that hooks an API within the application only, NOT a System Wide hook, and it didn't work the first time, but worked after i closed it and re-stared the application, so which isn't good.
so i need to know does madcodehook installs something into the system first? and the application have to restart after the first time?
second HOW can i tell if the hook failed from within my application so i can try to re-hook again without having to restart the application? do i just use the longBool returned by HookAPI, and if it didn't hook the first do i have to use HookAPI again or should i use RenewHook instead?
I noticed this on WINME, so I'm not sure if it has the same effect on other systems.
Thanks,
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
Some more info:
after i restared the system, the same exact thing happend, start the application the first time and no Hooks.... close the application, and start it again and voild we are hooked, also HookAPI always returns TRUE even when we are not hooked.....
Is this a bug?
i tried four different times, it won't work on the first run of the application.
What do you think?
thanks.
after i restared the system, the same exact thing happend, start the application the first time and no Hooks.... close the application, and start it again and voild we are hooked, also HookAPI always returns TRUE even when we are not hooked.....
Is this a bug?
i tried four different times, it won't work on the first run of the application.
What do you think?
thanks.
I can only guess what went wrong. Here's my guess: In win9x there are several 32bit APIs which do nothing but thunk down to the win9x 16bit dlls. The 32bit APIs are structered very strangely, as a result madCodeHook can't use the main hooking technique (extended code overwriting). In that case madCodeHook automatically uses the alternative hooking technique (mixture mode, explained in the documentation). This alternative hooking technique is not bad at all, but it has one disadvantage: If an application called GetProcAddress to get the address of an API and saves this address somewhere to later use it for calling the API. And if madCodeHook *later* hooks this API for the first time, the hook will not catch API calls which are done through the saved address. As soon as the API was hooked the first time, the problem is gone (until the next reboot).
This would explain why you needed to restart the application.
Which API did you hook?
This would explain why you needed to restart the application.
Which API did you hook?
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
i was hooking OpenClipboard API so i can control what the user can copy to the clipboard before it gets to the clipboard .... that way i can allow or disallow the process based on what is being copied?
also i tried to RenewHook but nothing and unhooked and hooked again without any success, the only way to get it to work is restarting the APP.
so do you have any solutions to this problem? any work arounds.?
Thanks.
also i tried to RenewHook but nothing and unhooked and hooked again without any success, the only way to get it to work is restarting the APP.
so do you have any solutions to this problem? any work arounds.?
Thanks.
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
-
- Posts: 75
- Joined: Sun Oct 31, 2004 5:45 am
Cool,
Ok here is what Works so others can benefit from it.
I Put the Hook on the very first line after initialization, and put the UnHook at the very first line in finalization .. and it works every time.
BTW no need to hook and unhook it just has to be hook first.
Thanks again for your help.
Can you see me jump up and down !
Ok here is what Works so others can benefit from it.
I Put the Hook on the very first line after initialization, and put the UnHook at the very first line in finalization .. and it works every time.
BTW no need to hook and unhook it just has to be hook first.
Thanks again for your help.
Can you see me jump up and down !
madshi i am working on my new codehook and i have added a ExtendedImportTable hook which catch *some* (only if procedure is global declarated) of the APIs which are imported by GetProcAddress here is the code:
Code: Select all
var oldLoadLibraryA: function(s: pchar): integer; stdcall;
LoadLibraryABeforeOurHookWasInstalled: function(s: pchar): integer; stdcall;
function myLoadLibraryA(s: pchar): integer; stdcall;
begin
result := oldLoadLibraryA(s);
MessageBox(0,pchar('Dll loaded: '+s),nil,0);
end;
function HookExtendedImportTable(hmodule: integer; oldaddress, newaddress, notchange: pointer): integer; stdcall;
type trelocblock = record
vaddress: integer;
size: integer;
end;
prelocblock = ^trelocblock;
var myreloc: prelocblock;
reloccount: integer;
startp: ^word;
i: integer;
p: ^integer;
IDH: PImageDosHeader;
INH: PImageNtHeaders;
begin
result := 0;
if (hmodule <> 0) then
begin
IDH := pointer(hmodule);
if (not IsBadReadPtr(IDH,4)) and (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then
begin
INH := pointer(cardinal(hmodule)+cardinal(IDH^._lfanew));
if (not IsBadReadPtr(INH,4)) and (INH^.Signature = IMAGE_NT_SIGNATURE) then
begin
myreloc := pointer(hmodule+integer(INH^.OptionalHeader.DataDirectory[5].VirtualAddress));
startp := pointer(integer(myreloc)+8);
while myreloc^.vaddress <> 0 do
begin
reloccount := (myreloc^.size-8) div sizeof(word);
for i := 0 to reloccount-1 do
begin
if (startp^ xor $3000 < $1000) then
begin
p := pointer(myreloc^.vaddress+startp^ mod $3000+hmodule);
if (not isbadreadptr(pointer(integer(p)-2),6)) and
(pbyte(integer(p)-2)^ = $FF) and
((pbyte(integer(p)-1)^ = $25) or (pbyte(integer(p)-1)^ = $15)) and
(not isbadreadptr(pointer(p^),4)) and
(p^ <> integer(notchange)) and
(not isbadreadptr(ppointer(p^)^,4)) and
(ppointer(p^)^ = oldaddress) then
begin
ppointer(p^)^ := newaddress;
inc(result);
end;
end;
startp := pointer(integer(startp)+sizeof(word));
end;
myreloc := pointer(startp);
startp := pointer(integer(startp)+8);
end;
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// we dont know that:
@LoadLibraryABeforeOurHookWasInstalled := getprocaddress(getmodulehandle('kernel32.dll'),'LoadLibraryA');
LoadLibraryABeforeOurHookWasInstalled('aha2.dll');
// our extended Import Table Hook (i call it RelocationHook)
@OldLoadLibraryA := GetProcAddress(GetModuleHandleA('kernel32.dll'),'LoadLibraryA');
HookExtendedImportTable(GetModuleHandle(nil),@oldLoadLibraryA,@myLoadLibraryA,@@oldLoadLibraryA);
// new call
LoadLibraryABeforeOurHookWasInstalled('aha.dll');
end;
I have done some little changes of the HookExtendedImportTable code.
Now u dont need to know the address of you old call (@@oldLoadLibrary) but u have to add a new funktion NextLoadLibraryA
The Hookmethod is littlebit faster because of removing one IF line and removing one isbadreadptr call. (but i think its not interesting ;>)
also i forgot to say that the result is the count of all installed hooks
using NextCodeHook instead of @@oldLoadLibrary will help u (madshi) to implement it easier to madCodeHook
also i forgot to say that u dont need to use ImportTable hook anymore because this hook will do it also.
only problem is that u have to call it for every module, ill look if i can add it so i can change the header to:
function HookExtendedImportTable(oldaddress, newaddress: pointer; var nextaddress: pointer): integer; stdcall;
here is the new code:
Now u dont need to know the address of you old call (@@oldLoadLibrary) but u have to add a new funktion NextLoadLibraryA
The Hookmethod is littlebit faster because of removing one IF line and removing one isbadreadptr call. (but i think its not interesting ;>)
also i forgot to say that the result is the count of all installed hooks
using NextCodeHook instead of @@oldLoadLibrary will help u (madshi) to implement it easier to madCodeHook
also i forgot to say that u dont need to use ImportTable hook anymore because this hook will do it also.
only problem is that u have to call it for every module, ill look if i can add it so i can change the header to:
function HookExtendedImportTable(oldaddress, newaddress: pointer; var nextaddress: pointer): integer; stdcall;
here is the new code:
Code: Select all
var oldLoadLibraryA: function(s: pchar): integer; stdcall;
LoadLibraryABeforeOurHookWasInstalled: function(s: pchar): integer; stdcall;
nextLoadLibraryA: function(s: pchar): integer; stdcall;
function myLoadLibraryA(s: pchar): integer; stdcall;
begin
result := nextLoadLibraryA(s);
MessageBox(0,pchar('Dll loaded: '+s),nil,0);
end;
function HookExtendedImportTable(hmodule: integer; oldaddress, newaddress: pointer; var nextaddress: pointer): integer; stdcall;
type TRelocBlock = record
vaddress: integer;
size: integer;
end;
PRelocBLock = ^TRelocBlock;
var myreloc: PRelocBlock;
reloccount: integer;
startp: ^word;
i: integer;
p: ^integer;
IDH: PImageDosHeader;
INH: PImageNtHeaders;
begin
result := 0;
IDH := pointer(hmodule);
if (not IsBadReadPtr(IDH,4)) and (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then
begin
INH := pointer(cardinal(hmodule)+cardinal(IDH^._lfanew));
if (not IsBadReadPtr(INH,4)) and (INH^.Signature = IMAGE_NT_SIGNATURE) then
begin
myreloc := pointer(hmodule+integer(INH^.OptionalHeader.DataDirectory[5].VirtualAddress));
startp := pointer(integer(myreloc)+8);
while myreloc^.vaddress <> 0 do
begin
reloccount := (myreloc^.size-8) div sizeof(word);
for i := 0 to reloccount-1 do
begin
if (startp^ xor $3000 < $1000) then
begin
p := pointer(myreloc^.vaddress+startp^ mod $3000+hmodule);
if (not isbadreadptr(pointer(integer(p)-2),6)) and
(pbyte(integer(p)-2)^ = $FF) and
((pbyte(integer(p)-1)^ = $25) or (pbyte(integer(p)-1)^ = $15)) and
(not isbadreadptr(ppointer(p^)^,4)) and
(ppointer(p^)^ = oldaddress) then
begin
ppointer(p^)^ := newaddress;
inc(result);
end;
end;
startp := pointer(integer(startp)+sizeof(word));
end;
myreloc := pointer(startp);
startp := pointer(integer(startp)+8);
end;
end;
end;
nextaddress := oldaddress;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
// we dont know that:
@LoadLibraryABeforeOurHookWasInstalled := getprocaddress(getmodulehandle('kernel32.dll'),'LoadLibraryA');
LoadLibraryABeforeOurHookWasInstalled('aha2.dll'); // not catched because hook is not installed
// our extended Import Table Hook (i call it RelocationHook)
@OldLoadLibraryA := GetProcAddress(GetModuleHandleA('kernel32.dll'),'LoadLibraryA');
HookExtendedImportTable(GetModuleHandle(nil),@oldLoadLibraryA,@myLoadLibraryA,@nextLoadLibraryA);
// new call
LoadLibraryABeforeOurHookWasInstalled('aha.dll'); // catched
LoadLibraryA('test.dll'); // catched
end;