a rare dead lock when uninject dll

c++ / delphi package - dll injection and api hooking
Post Reply
nemo314
Posts: 6
Joined: Sun May 04, 2014 11:30 am

a rare dead lock when uninject dll

Post by nemo314 »

system : Windows Version 7601 (Service Pack 1) MP (4 procs) Free x64

call stack like that

0045e348 76f43bd5 ntdll_77450000!NtDelayExecution+0x15
0045e3b0 76f444a5 KERNELBASE!SleepEx+0x65
0045e3c0 6b86f3bb KERNELBASE!Sleep+0xf
0045e950 6b8707df xxxxxxxx!CCodeHook::~CCodeHook+0x4ab
0045e95c 6b86513b xxxxxxxx!CCodeHook::`scalar deleting destructor'+0xf
0045e9bc 6b865ae3 xxxxxxxx!VirtualAlloc2+0x54b
0045e9d0 6b865158 xxxxxxxx!UnhookLoadLibrary+0x43
0045ea30 6b864750 xxxxxxxx!VirtualAlloc2+0x568
0045ea44 6b8613e3 xxxxxxxx!UnhookAPI+0x10
0045ea4c 6b8618f4 xxxxxxxx!chrome1::unhook(void)+0x13
0045f2a4 6b87af90 xxxxxxxx!DllMain(struct HINSTANCE__ * hModule = 0x00000000`6b860000, unsigned long ul_reason_for_call = 0, void * lpReserved = 0x00000000`00000001)+0x304
0045f2e4 6b87af17 xxxxxxxx!__DllMainCRTStartup(void * hDllHandle = 0x00000000`6b860000, unsigned long dwReason = 0, void * lpreserved = 0x00000000`00000001)+0x72
0045f2f8 774899a0 xxxxxxxx!_DllMainCRTStartup(void * hDllHandle = 0x00000000`6b860000, unsigned long dwReason = 0, void * lpreserved = 0x00000000`00000001)+0x1c
0045f318 7749d702 ntdll_77450000!LdrpCallInitRoutine+0x14
0045f3bc 7749d5a4 ntdll_77450000!LdrShutdownProcess+0x1aa
0045f3d0 766379ec ntdll_77450000!RtlExitUserProcess+0x74
0045f3e4 10001370 kernel32!ExitProcessStub+0x12
WARNING: Stack unwind information not available. Following frames may be wrong.
0045f4d4 7747f201 wtsapi32!WTSCloseServer
0045f66c 7748bb59 ntdll_77450000!RtlDosApplyFileIsolationRedirection_Ustr+0x31e
0045f70c 77483ca4 ntdll_77450000!RtlQueryInformationActivationContext+0x3f2



my code like that, and do it in dllmain, hook in DLL_PROCESS_ATTACH and unhook in DLL_PROCESS_DETACH


int chrome1::hook()
{
InitializeMadCHook();
HookAPI("shell32.dll","SHFileOperationW",mySHFileOperationW, &(PVOID&)pSHFileOperationW);
return 0;
}

int chrome1::unhook()
{
if (pSHFileOperationW)
UnhookAPI( &(PVOID&)pSHFileOperationW);
FinalizeMadCHook();
return 0;

}

when it happens, chrome will not works any more even create a new process

may be a crash in loadlibrary is the reason?
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: a rare dead lock when uninject dll

Post by madshi »

First of all: You don't need to unhook in your hook dll, madCodeHook does that automatically when you call UninjectLibrary(). Your UnhookAPI() should have no effect, but it shouldn't harm, either.

From the callstack it seems to me that madCodeHook believes that one of your hook callback functions is still "in use". E.g. imagine you have hooked MessageBoxA(). Now imagine Chrome calls MessageBoxA(), your hook callback function calls MessageBoxANext() and the message box is still visible on screen. If you uninject your hook dll in this moment, and if madCodeHook followed your request immediately and unloaded your hook dll from Chrome, in the moment when the user closes the message box, the thread would try to return to your hook callback function, which is now a code section which is no longer even allocated (because your hook dll already got uploaded). As a result the thread would crash with an access violation.

Because of the above stability issue, madCodeHook keeps a record of which hook callback functions are currently in use. And uninjection is delayed until all callback functions are no longer in use. Usually this works fine. It's a very important feature to allow stable uninjection. However, sometimes this can result in uninjection getting stuck, because madCodeHook believes that a hook callback function is still in use. madCodeHook could be right, or it could be wrong. In rare situations this stability check can be overcautious. E.g. if the thread which called MessageBoxA() gets terminated while the message box is still on screen, madCodeHook doesn't notice this and still thinks that the hook callback function is still in use, although it no longer is. But this problem usually only occurs if threads get violently terminated (via TerminateThread), which is not a good thing to do, anyway.

Is it possible that one of your hooked APIs is really still "in use" in the moment when you try to uninject? Which APIs are you hooking?
nemo314
Posts: 6
Joined: Sun May 04, 2014 11:30 am

Re: a rare dead lock when uninject dll

Post by nemo314 »

it is a mini dll, only recv user downloading file, and notify my service for virus scan, without any function named UnhookLoadLibrary.

i only hook SHFileOperationW in chrome for download protect, and the dead lock is in madCodeHook's Hooking.cpp.

static BOOL UnhookInternal(LPVOID *pNextHook, BOOL dontUnhookHelperHooks, BOOL wait)

....

if (unhookHelpers)
UnhookLoadLibrary(wait);
}
__except (ExceptionFilter(L"UnhookInternal", GetExceptionInformation()))
{
result = false;
}
return result;
}

i guess some chrome ext make loadlibrary crash, so it come into dead lock. check the owner thread may fix ?
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: a rare dead lock when uninject dll

Post by madshi »

It is not a deadlock. The behaviour is intentional, as I explained in my previous comment. Please read it again. If you don't understand it, feel free to ask questions...
nemo314
Posts: 6
Joined: Sun May 04, 2014 11:30 am

Re: a rare dead lock when uninject dll

Post by nemo314 »

i am sorry for my inconsiderate words. i will try some codes for crash or terminate environment. thanks for reply
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: a rare dead lock when uninject dll

Post by madshi »

It's not about words... :D I just wanted to make sure you understood what I was saying. That's important because only then we can move forward with this problem.
manutai
Posts: 85
Joined: Sun Aug 03, 2008 1:40 am

Re: a rare dead lock when uninject dll

Post by manutai »

Environment :

​Windows 7 + McAfee DLP 11.x + Chrome(any recent version)

Issue :

- We created have a DLL, in which on DLL_PROCESS_ATTACH we have hooked RegisterHotKey() API and on DLL_PROCESS_DETTACH we have unhooked the same API using UnhookAPI() after which we have called FinalizeMadCode(). In our callback of this API we have simply called the nextHook which we got as a out parameter in HookAPI().
- This Dll is then injected all the system-wide processes.
- Now when we start chrome, it hangs in some dead-lock(same as mentioned in this thread).
- And when we don't call Unhook API(as suggested above) we observed that chorme starts properly.
- In all our implementation, where we have achieved hooking of API we have called UnhookAPI() before calling FinalizeMadCode() and it seems to be working in all other condition except for this one.

Question :Now just want to know if is it absolutely safe to not call UnhookAPI() before calling FinalizeMadCode() and it is for sure that after calling FinalizeMadCode() our Callback function for the hooked API will never be called?
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: a rare dead lock when uninject dll

Post by madshi »

Yes, it is safe to not call UnhookAPI(). If you look at all the madCodeHook demos, none of them call UnhookAPI() in DLL_PROCESS_DETACH. The only reason UnhookAPI() exists at all is if you want to uninstall an API hook in the middle of something. UnhookAPI() should not be called in DLL_PROCESS_DETACH.

FinalizeMadCHook() should remove all API hooks, so afterwards your hook callback function should no longer be called. Of course it's possible that some thread is still "inside" of your hook callback function from an earlier API call.
Post Reply