Solved

Hooking delay loaded DLLs?

Posted on 2010-11-21
19
1,474 Views
Last Modified: 2013-12-03
Hi,

What is the 'correct' way to hook functions which are in DLL's loaded /after/ I've injected my own (MFC) API-hooking DLL?  I have some processes I'm trying to hook whose libraries I am interested in are sometimes loaded after I've attempted the hook, so the hook is missed.  Is there a reliable way to ensure functions I am interested in are hooked as soon as they are loaded i a DLL?

Thanks,
Chris J
0
Comment
Question by:chrispauljarram
  • 9
  • 9
19 Comments
 
LVL 5

Expert Comment

by:greatsubash
Comment Utility
0
 

Author Comment

by:chrispauljarram
Comment Utility
Hi greatsubasg,

I've had a quick look at those but can't see anything there that refers to my actual problem?  They seem to just give advice about hooking methods and not detecting when DLL's are delay loaded in order to not miss the opportunity to patch their IAT entries at that time..

Apologies if I'm misexplaining, I hope this clarifies things a little.

Thanks,
Chris
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
In this case, you need to hook LoadLibrary, so when a new DLL is loaded, you can look to see if it is one you are interested in.  If it is, then you can inject your hooking stuff into the DLL, otherwise ignore it.

HTH
0
 

Author Comment

by:chrispauljarram
Comment Utility
OK I'll give that a go today, I was aware of that method and did wonder if maybe that was the correct way to do it (i.e. It'll work in all cases) but wanted to hear it from the horses mouth :)  Will try it out and report back in a bit.

Cheers,
Chris
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
Yeah, it is the way to go.  If you get hold of the Jeffrey Richter's book about hooking, he talks a lot about it, with some cool example code.  Be aware though that hooking is a *very* dangerous game and it may lead to no end of problems, including system wide crashes (I know, I have been there :)).  I have written classes that help with it all though, so if you ever need any help in general, let us know :)
0
 

Author Comment

by:chrispauljarram
Comment Utility
Hi again mywad99,

I'll try and get hold of a copy of Jeffrey's book, sounds like it could be very useful.  Yes I would be /extremely/ grateful if you have any classes I can look at that help with this!  I tried patching LoadLibrary and hit a few problems.

Firstly, am I right in saying I need to attempt to hook all of the following?:-

LoadLibrary
LoadLibraryA
LoadLibraryW
LoadLibraryEx

(are there any others I'm missing?)

Reason I ask is the first app I injected only uses LoadLibraryA from Kernel32.dll (according to dependency walker).

The second problem is the instant I try and hook LoadLibraryA, it closes the app I am trying to hook -  Could this be because I'm attempting the IAT patch from within my 'InitInstance' MFC DLL function, the one called in my injected DLL to inject it in the first place?  Just wondering what the safe way to do this is...  I think ultimately I'll move this all to a standard Win32 dll to ditch the MFC dependency completely, but not sure that would solve this problem?

Thanks again, your help is very much appreciated!

Chris
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
Take a look at the class I wrote for hooking, hopefully it will help you.  Any questions please ask...

 APIFunctionHooker.h APIFunctionHooker.cpp
0
 

Author Comment

by:chrispauljarram
Comment Utility
Hi again,

Well by strange coincidence that is already the exact class I'm using already!  Don't recall seeing an author name on it, guess maybe I grabbed it from another thread here some time ago?  What it does mean though at least is you are the best person to help with it!  I'm trying to patch LoadLibraryA in my InitInstance function using:-

CFuncInAPIHook::Instance().HookFunction ( _T("kernel32.dll"), _T("LoadLibraryA"), AfxGetInstanceHandle(), ( PROC )&myLoadLibraryA );

All other functions patch 100% fine using this call (many OpenGL calls I'm patching for instance), but trying to patch loadlibrary like this closes the target app.

Any ideas?

Cheers once again, and thanks for the use of your library btw :)

Chris
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
Heh, I had a feeling I had given that class to someone on here before, just did not remember it was you!

Can you upload a simple cut down version of your app (say, an MFC dialog app) that demonstrates this issue please?  Or just paste the entire .cpp that contains your calls, so I can step through it and help figure out the problem?

TIA
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
Whilst you upload that, some food for thought: I am not sure that LoadLibrary will be called if you are delay loading a DLL; according to http://msdn.microsoft.com/en-us/library/151kt790.aspx it "relieves you of the need to use the Windows SDK functions LoadLibrary and GetProcAddress to implement DLL delayed loading"

Hmm.....
0
 

Author Comment

by:chrispauljarram
Comment Utility
Hi again,

Sorry for the delay, got called away yesterday.  I've just put together the most basic of MFC DLL's which does nothing but try and hook LoadLibraryA using your APIHooking classes.  Of the two games I've injected this into (it gets injected automatcially by another app when the game process is detected, just using the bog standard CreateRemoteThread / LoadLibrary technique), they both crash on startup ("xxx has stopped working..."). /However/, prior to crashing there are a few calls to my version of LoadLibrary that are working (and printing out the parameter correctly), so it appears to be working initially but the hook is then causing a crash after a few LoadLibrary calls.  I've attached the project (it is a .rar file with a .zip extension to force the attachment system to accept it), one example game where this happens if you want to try and inject into it is the demo release of NoLimits rollercoaster simulator, it is very small, quick to run and downloadable at http://www.nolimitscoaster.com/Download/download.html.

Thanks again, I hope this is something simple :)

Cheers,
Chris
TelemReader.zip
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
OK.  It would be good to see exactly how you are injecting this: can you post the code you are using that injects this simple DLL please, explaining how you acquire the handle to the process for injection?  Not being dumb here, it might be that the principle is sound but you are making a mistake early on in the process.  

Ideally, I need some code that run "out of the  box" if you get me, without having to spend time setting up the problem where that time would be better spent helping you solve the problem!
0
 

Author Comment

by:chrispauljarram
Comment Utility
OK, well the DLL is definately being injected lets put it that way.. it is running and printing debug output to a console.  The process handle (which is valid and being used elsewhere in the application ) is obtained using:-
m_hProcess = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_CREATE_THREAD|
                    PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, processID);

The only thing not working is the LoadLibrary hooking.  I know this same function is being used to inject the code in the first place, but afaik this shouldn't interfere with its patching?


The section of injection code is:-

      m_hLibModule = 0;
      CString pluginName = CString(CGlobals::m_strWorkingDirectory) + "\\" + TELEM_READER_PLUGIN_NAME + "\0";
      char szLibPath[_MAX_PATH];
      memcpy(szLibPath, pluginName.GetBuffer(), pluginName.GetLength() + 1);
      LPVOID remoteAddress = VirtualAllocEx(m_hProcess, NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE);

      if(remoteAddress != NULL)
      {
            if(WriteProcessMemory(m_hProcess,remoteAddress,(void*) szLibPath,sizeof(szLibPath),NULL) != 0)
            {
                  HMODULE hModule = GetModuleHandle((LPCSTR) "Kernel32");
                  FARPROC pa = GetProcAddress(hModule, "LoadLibraryA");
                  HANDLE rt = CreateRemoteThread(m_hProcess, NULL, 0, (LPTHREAD_START_ROUTINE) pa, remoteAddress, 0, NULL);

                  if(rt != NULL)
                  {
                        WaitForSingleObject(rt, INFINITE);
                        GetExitCodeThread(rt, &m_hLibModule); // get remote module address for unloading when this process is closed.

                        if(m_hLibModule == 0)
                        {
                              // Report injection error.
                        }
                        else
                        {
                              // Report injection success.
                        }
                  }
            }
            
            VirtualFreeEx(m_hProcess, remoteAddress, 0, MEM_RELEASE);
      }

Building the DLL project I sent you and changing the plugin name above should hopefully be enough for this to work (assuming you have the ID of the process to test with)...

Cheers,
Chris
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
This is very interesting, and I will adhere to help you find a solution to your problem.  I am trying to replicate the problem at the minute, and as soon as I can do that I will be back (bear in mind this might not be until the weekend now, sorry - lots to do (to get paid for :))

What I would advise though is what I was trying do do: write two simple apps: one that has your injection code above and one that dynamically loads, via LoadLibrary, a DLL written by you (the simple Win32 DLL with Export Symbols option in VS is enough).  Have the injection app inject your telemReader dll into the the second executable, then have that executable call LoadLibrary (via a button click handler, say).  Then see if you get the same hanging problem.
0
 

Author Comment

by:chrispauljarram
Comment Utility
Cheers again my friend :)  Its not super-urgent so no probs for the delay, just appreciate the help - To look at it from a different perspective (and taking into account what you say about loadlibrary not necessarily being called for delay-loaded modules) I'm just wondering if it would be better to periodically enumerate the modules of the target process every second or so (from my injecting app) until those I'm interested in are present, and do the injection / hooking then - do you think this makes more sense?

Thanks,
Chris
0
 
LVL 19

Accepted Solution

by:
mrwad99 earned 500 total points
Comment Utility
Have not forgotten about this btw, still fiddling with it when I get the time.  Have also commented on your other question, which might be of use...
0
 

Author Comment

by:chrispauljarram
Comment Utility
Not to worry with this one, I'm just checking for the module's presence in a loop now (using GetModuleHandle(name)) until it is present.

Cheers,
Chris
0
 

Author Closing Comment

by:chrispauljarram
Comment Utility
Partial solution, thanks again :)
0
 
LVL 19

Expert Comment

by:mrwad99
Comment Utility
No problem :o)  Like I say, I will investigate whether or not LoadLibrary gets called when a delay loaded DLL is loaded: if not, it looks like you have the solution with your loop as you described above.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now