Inject an unmanaged DLL into a managed application

Jan 31, 2009 at 4:02 PM
Hi Chirs,

I'm using the unmanaged API in unmanaged application. In my testing suite, I need to inject the unmanaged DLL into a managed module. Have you ever test this case? If not, please download a sample application from microsoft and have a test: http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/TestRun05.exe (referrer: http://msdn.microsoft.com/en-us/magazine/cc163613.aspx)

After I changed to EasyHook, this case failed in my testing suite, the target thread cannot be resumed. (I didn't step into your source code for details), once I resumed the target thread manually, the target application will crash.

Thanks and Regards,
Paul
Jan 31, 2009 at 4:05 PM
Both my application and injecting dll are unmanaged code, that is, I'm using unmanaged APIs only. I'm going to perform testing on mixed applications soon.
Jan 31, 2009 at 6:31 PM
Of course it will be a problem if the system runs low on resources...

Why do you need to test such rare conditions?
Jan 31, 2009 at 8:31 PM
Is this problem specific to your application or does it also fail with the demos shipping with easyhook?
Feb 1, 2009 at 12:07 PM
I tested the sample application ProcessMonitor.exe and verified that the sample works well when inject a managed dll into a mixed application or a managed application.

I'm using the unmanaged APIs only because all my code is C++ only. I'm intending to inject the dll to applications for memory usage monitor. Currently I'm just tested injecting the dll into various types of applications, including native applications, managed applications, mixed applications, windows apps, console apps, and in future, will also test 64bit apps, and 16bit apps in ntvdm if possible.

Why use unmanaged APIs only?
Because for some applications, or some users' computers, they may not install the .NET framework, and injecting .NET dlls into unmanaged applications should lead a crash.
Feb 1, 2009 at 12:11 PM
Technically, injecting a unmanaged dll into managed/mixed application should work.
Feb 1, 2009 at 5:25 PM
>Technically, injecting a unmanaged dll into managed/mixed application should work.

well no doubt about that... EasyHook.dll is an unmanaged DLL... So even if you do a pure managed injection, internally an unmanaged injection is performed...

But that was not what I was wondering about. The microsoft APP you linked me too, is simulating low memory scenarios. And I am not sure if this will cause injection to crash, but I think it will at least fail...
Feb 4, 2009 at 3:18 PM
Edited Feb 4, 2009 at 3:57 PM
I got some time to look into this issue today again, and got some clues:

Firstly there are 3 ways to create a remote thread:
1. RhCreateStealthRemoteThread
2. NtCreateThreadEx
3. CreateRemoteThread

In this scenario, 1&3 can works well while 2 is the default approach, but 2 doesn't work:
NtCreateThreadEx creates remote thread on the target process, and returned a succeeded code, but suspended (normally it will be resumed and then load injecting dll). So RhInjectLibrary waits there and blocked the host application.
It now comes to the crash. I use process explorer, when I watch the property of the target process, the thread created by host application is still suspending. If I resume it manually, the target process crash.

Even with method1, there is still an issue: LhWaitForPendingRemovals dead locked in "Sleep" function.
Here is the code in DllMain:

...
    else if (ul_reason_for_call == DLL_PROCESS_DETACH) {

        LhUninstallAllHooks();
        LhWaitForPendingRemovals();
...



Can you take some time to test injecting an unmanaged dll using the example UnmanagedHook to a managed application and hook an API? Or put it into your test suite.

Thanks a bunch and regards,
Feb 4, 2009 at 4:18 PM
Edited Feb 4, 2009 at 4:26 PM
The reason for "LhWaitForPendingRemovals dead locked" is:

I hooked WaitForMultipleObjects and CreateProcess, and the target process is a cmd.exe, and then cmd.exe created an eatmem.exe. The DllMain of eatmem on deattaching the process called during WaitForMultipleObjects and then made the deadlock. It's really a rare case, but it do happens.
Feb 8, 2009 at 5:42 PM
Edited Feb 8, 2009 at 5:43 PM
the thing with WaitForMultipleObjects is weird because LhUninstallAllHooks() should remove the hook before the deadlock can occur?!

But after all I still don't get your problem. I mean all your cases are well tested and I am not really sure why they should all fail in your application...?! Or did I miss something?!
Feb 9, 2009 at 12:26 PM
Edited Feb 9, 2009 at 12:27 PM
Hi Chris,

I really appreciate your nice work, it might be caused by some of the settings on my computer. I tried to reproduce this issue by modifying your sample code, but I failed to hook any APIs with the same code in my application. I'm now leaving these issues as is and working on a workaround to fix my defects.

Best regards,