Hooking LoadLibraryW

c++ / delphi package - dll injection and api hooking
Post Reply
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Hooking LoadLibraryW

Post by mark »

Hi, I need to intercept all calls system wide (2k,xp & 2k3) to LoadLibraryW and be selective about which one's get allowed through, yet I have major issues with this !!!

I can intercept LoadLibraryA with no problem at all !

A snippet of code as follows seem's ok

Code: Select all

function LoadLibraryWCallBack(lpLibFilename : PWideChar) : dword; stdcall;
begin
   result := LoadLibraryWNext(lpLibFilename);
end;
yet, if I go

Code: Select all

function LoadLibraryWCallBack(lpLibFilename : PWideChar) : dword; stdcall;
begin
   if true then
      result := LoadLibraryWNext(lpLibFilename)
   else
   begin
      result := 0;
      setlasterror(ERROR_FILE_NOT_FOUND);
   end;
end;
it fails ! Essentially I was working backward's commenting stuff out until I got to the point of the first function, so I readded the logic but without the actual function call - the if true bit should be if alloweddll(lpLibFilename) ???

WFT ? I know InjectLibrary uses LoadLibrary from some code madshi sent me ages ago with a much earlier version but I'm stumped as to why this should give me so many problems !!!

Any ideas anyone ?

:confused:
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Those 2 snippets should behave identical.

Have you checked out the HookLoadLibrary.dpr demo?
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

Yeah, was fine. That's what I thought, but if I include the second version of the function then start notepad, the File Open fails with unable to load library type errors !!!

I've just put that in a lib all by itself, seemed the next logical thing to do and it causes no problem ! Will put the logic in there next and see what happens with that...


This may be a silly question but would it make any difference if I didn't try hooking all the API's from a single library and split them into logical groups ????
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Please show me the whole code of the hook dll which fails. Maybe there's a bug in calling HookAPI?
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

I will, but first I'm going to go over the code as it's rather a complex DLL hooking many API's. I think i'll break it down into distinct DLL's and specific set's of API's and go from there.

I should be able to rework most of the code into seperate lump's tonight and will let you know how it goes, fingers crossed...
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

Seperating the dll into several smaller dlls makes sense only if you will only inject some of the dlls in specific situations. If you will load all dlls, anyway, I'd recommend to keep it in one dll, cause that reduces overhead = increases performance.
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

I've split the code and it's much more stable now. The LoadLibrary calls are hooked in a seperate DLL to the others and seem's to be much happier although I'm not sure why ! :confused:

Guess I'll have to carry on scanning the code looking for a memory leak or similar !!!

Cheers for the input.

Mark
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

mark wrote:I've split the code and it's much more stable now. :(
Well, it would appear that all is now well with the exception of LoadLibraryExW which I cannot seem to fathom out for some reason. If I put a simple

Code: Select all

Result := LoadLibraryExW(......)
entry in the Callback function it works, anything else seem's to screw up the value of the lib parameters (param1 in the func prototype) ?

Any idea's ?

Does the dll injection code now use LoadLibraryExW anywhere ?

I've tried doing the following

Code: Select all

function LoadLibraryExW(lib : pwidechar; .......) : dword; stdcall;
var p : pchar;
begin
   getmem(p,1024);
   p := lib;

   if alloweddllw(lib) then
      result := LoadLibraryExWNext(p, ....)
   else
   begin
      result := 0;
      setlasterror(ERROR_FILE_NOT_FOUND);
   end;

   freemem(p);
end;
to no avail. If i inject the HookLoadLibrary example system wide then inject this code the log file show's incorrect values being passed (like other text from within my DLL) to the LoadLibraryExWNext function which is bizare as I can't seem to work out how the corruption is getting in ?

I think I'm going to need to throw a demo of this together and post it to you if you don't mind ?

:crazy: :crazy: :crazy:

Cheers

Mark
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

I guess that your "alloweddllw" function probably violates hooking rule 7 (see documentation). It's just a guess, though.
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

madshi wrote:I guess that your "alloweddllw" function probably violates hooking rule 7 (see documentation). It's just a guess, though.
Guess that makes me a lame brain for forgetting about the 'golden' hooking rules :( I'll have to check the code but suspect I am calling an Ansi function and only because there is no Wide version .....

Will have to check further ! Strange thing is though, LoadLibraryWCallback does not have this problem !!!
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

mark wrote:
madshi wrote:I guess that your "alloweddllw" function probably violates hooking rule 7 (see documentation). It's just a guess, though.
Guess that makes me a lame brain for forgetting about the 'golden' hooking rules :( I'll have to check the code but suspect I am calling an Ansi function and only because there is no Wide version .....

Will have to check further ! Strange thing is though, LoadLibraryWCallback does not have this problem !!!
Does this mean that I can use ansi strings inside the callback functions etc. but need to avoid ansi function calls etc... ? So can I pass ansi strings to my own functions within the callback function ???
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Post by madshi »

mark wrote:Does this mean that I can use ansi strings inside the callback functions etc. but need to avoid ansi function calls etc... ? So can I pass ansi strings to my own functions within the callback function ???
Yes.
mark
Posts: 8
Joined: Wed Dec 15, 2004 1:17 pm
Location: UK
Contact:

Post by mark »

Well, after days of tracing code, checking api call details on MSDN, Google etc. I had what I thought was a completely 'wide' version of the logic yet it STILL caused problems.

Having dug deeper and deeper it would appear that the content of the lib constant within the actual callback function (LoadLibraryExW) was corrupt upon return from the IsAllowed logic, therefore, in a sudden flash of inspiration I changed my code and instead of

Code: Select all

if IsAllowedDLL(lib) then
   result := LoadLibraryExWNext(lib,.......)
else
begin
   setlasterror(ERROR_FILE_NOT_FOUND);
   result := 0;
end;
I used the following and it worked a dream,

Code: Select all

   result := IsAllowedDLL(lib);
   if result = 0 then setlasterror(ERROR_FILE_NOT_FOUND);

so perhaps was something to do with the BOOL return value from IsAllowed and simply returning the handle (I called LoadLibraryExWNext inside the IsAllowedDLL function :wink: ) to the loaded library worked. Hurrar and it's Christmas :D :D :D

Have a good christmas and new year folks.....

Mark
Post Reply