process hang-up when exit

c++ / delphi package - dll injection and api hooking
Post Reply
powerlinm
Posts: 33
Joined: Mon Dec 17, 2007 8:05 am

process hang-up when exit

Post by powerlinm »

it's said to report this bug.
i use hook 3.1.3
some process sometimes hang-up when exit,
following the stack:
ntkrnlpa.exe!KiSwapContext+0x26
ntkrnlpa.exe!KiSwapThread+0x2e5
ntkrnlpa.exe!KeWaitForSingleObject+0x346
ntkrnlpa.exe!KiSuspendThread+0x18
ntkrnlpa.exe!KiDeliverApc+0x117
ntkrnlpa.exe!KiSwapThread+0x300
ntkrnlpa.exe!KeDelayExecutionThread+0x2ab
ntkrnlpa.exe!NtDelayExecution+0x84
ntkrnlpa.exe!KiFastCallEntry+0xfc
ntdll.dll!KiFastSystemCallRet
ntdll.dll!NtDelayExecution+0xc
!OpenFileMappingW+0x72
!00000222+0x94
!OpenGlobalFileMapping+0x10
!00000286+0x14a
!0000000B+0x1b
!000003AE+0x1b
!0000044E+0x57
!00000041+0xe9
!000000FB+0x5e
!StaticLibHelper_Final+0x32
!DllMain+0xad6
!__DllMainCRTStartup+0x6c
!_DllMainCRTStartup+0x1e
ntdll.dll!LdrpCallInitRoutine+0x14
ntdll.dll!LdrShutdownProcess+0x182
!_ExitProcess+0x43
!ExitProcess+0x14
!__crtExitProcess+0x17
!doexit+0x10a
!exit+0x11
!done+0x46
!wmain+0x973
!ErrorReportingFilter+0x541
!BaseProcessStart+0x23
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: process hang-up when exit

Post by madshi »

A few questions:

(1) Are we talking about a 64bit or 32bit process?
(2) Is this a new problem introduced in madCodeHook 3.1.3, or did this problem occur with older versions, too?
(3) Are you using the static lib shippin with madCodeHook? Or are you compiling the madCodeHook C++ source code into your hook dll?
(4) Are you using any flags in your HookAPI() calls? If so, which?
powerlinm
Posts: 33
Joined: Mon Dec 17, 2007 8:05 am

Re: process hang-up when exit

Post by powerlinm »

the ansers:
(1) 32 bit process run on 64bit Win7.
(2) I am not sure the problem only in madCodeHook 3.1.3, but it seems 3.1.2 also has the problem.
(3) I use static lib , link to dll, i Use VC 2008.
(4) this is my code of Hook:

Code: Select all

		
In  DllMain::DLL_PROCESS_ATTACH
           if(!HookAPI ("ole32.DLL", "CoCreateInstance", myCoCreateInstance, (PVOID*) &OrigCoCreateInstance))
		{
			_ASSERT(0);
		}
		else
		{
			ATLTRACE2( MY_CATEGORY, 0,"RegisterDragDrop Success");
		}


			bRet = HookAPI("shell32.dll","SHFileOperationW",mySHFileOperationW, (PVOID*)&OrigSHFileOperationW);
			bRet = HookAPI("shell32.dll","SHFileOperationEx",mySHFileOperationEx, (PVOID*)&OrigSHFileOperationEx);


		bRet = HookAPI("Kernel32.dll", "CreateFileW",myCreateFileW, (PVOID*)&OrigCreateFileW);
		bRet = HookAPI("Kernel32.dll", "CreateDirectoryW",myCreateDirectoryW, (PVOID*)&OrigCreateDirectoryW);
			bRet = HookAPI("Kernel32.dll","MoveFileWithProgressW", myMoveFileWithProgressW, (PVOID*)&OrigMoveFileWithProgressW);
			TRACE_HOOK_RET(bRet);
			bRet = HookAPI("Kernel32.dll","CopyFileExW",myCopyFileExW, (PVOID*)&OrigCopyFileExW);
			TRACE_HOOK_RET(bRet);
			bRet = HookAPI("Kernel32.dll","PrivCopyFileExW",myPrivCopyFileExW, (PVOID*)&OrigPrivCopyFileExW);
			TRACE_HOOK_RET(bRet);
			bRet = HookAPI("rapi.dll","CeRapiInit",myCeRapiInit, (PVOID*)&OrigCeRapiInit);
			TRACE_HOOK_RET(bRet);
			bRet = HookAPI("rapi.dll","CeRapiInitEx",myCeRapiInitEx, (PVOID*)&OrigCeRapiInitEx);
			TRACE_HOOK_RET(bRet);
	BOOL bRet = HookAPI("Ntdll.dll", "NtCreateFile",myNtCreateFile, (PVOID*)&OrigNtCreateFile); 
	bRet = HookAPI("Ntdll.dll", "NtOpenFile",myNtOpenFile, (PVOID*)&OrigNtOpenFile);

In DllMain::DLL_PROCESS_DETACH
  			m_oldFilter = SetUnhandledExceptionFilter(myUnhandledExceptionFilter);
			SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);

			// FinalizeMadCHook is needed only if you're using the static madCHook.lib
			FinalizeMadCHook();  // hang-up sometimes
	
			SetUnhandledExceptionFilter(m_oldFilter);
(5) a question:
can i use CreateIpcQueue in DllMain::DLL_PROCESS_ATTACH ?
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: process hang-up when exit

Post by madshi »

Do you currently use CreateIpcQueue in DllMain? You should not, because it creates threads and that's not a good thing to do for a hook dll.
powerlinm
Posts: 33
Joined: Mon Dec 17, 2007 8:05 am

Re: process hang-up when exit

Post by powerlinm »

yes, is use CreateIpcQueue in dllmain, and maybe not called DestroyIpcQueue, so FinalizeMadCHook hang-up.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: process hang-up when exit

Post by madshi »

What exact purpose do you need this for? Maybe there's a better alternative? E.g. your exe could write configuration information to a shared memory buffer and your hook dll could read it. This would work without needing any threads or other "bad" (for a hook dll) stuff.
powerlinm
Posts: 33
Joined: Mon Dec 17, 2007 8:05 am

Re: process hang-up when exit

Post by powerlinm »

I must use ipc in hooked process, because I use the machook lib for encrypt file. I define two type process: 1. trust 2 Not trust.
when drag content from trust process(winword.exe) to "not trust" process(wordpad.exe), trust process want to know the process which droped is a trust process, if also a trust process, pass it's operation, if not, deni. In order to know this, the trust process send IPC message to the process which droped. the IPC name is PC_NAME_[PID], so every process have a unique name.

and the IPC thread have a lot other functions, so there's no better alternative.

I Use CreateIpcQueue in thread many years, Most of the time work well.
But recently, i meet hang-up problem. please help me to solve it, thanks a lot.

If i call DestroyIpcQueue in DLL_PROCESS_DETACH case as following code, the process hang-up also.
I tested in Win7 64bit OS, but process is 32 bit. XP not tested.
When build VC project, it hang-up every time. if I remove DestroyIpcQueue(ipcName), It work well, but may hang-up in FinalizeMadCHook at XP.

Code: Select all

	case DLL_PROCESS_DETACH:
		{
			bRun = FALSE;
			while (g_hThread)
			{
				DWORD dwThreadCode = 0;

				if (!GetExitCodeThread(g_hThread, &dwThreadCode))
				{
					break;
				}

				if (dwThreadCode != STILL_ACTIVE )
				{
					break;
				}

				SetEvent(hObject);
				WaitForSingleObject(g_hThread, 1000);

				if (!GetExitCodeThread(g_hThread, &dwThreadCode))
				{
					break;
				}

				if (dwThreadCode != STILL_ACTIVE )
				{
					break;
				}

				if (g_hThread && !g_OnCallHookLibFun)
				{				
					TerminateThread(g_hThread, 0);
					g_hThread = NULL;

					break;
				}
			}

			if (g_bCreatedIpcMsgQueue)
			{
				DestroyIpcQueue(ipcName);
			}

			m_oldFilter = SetUnhandledExceptionFilter(myUnhandledExceptionFilter);
			SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);

			// FinalizeMadCHook is needed only if you're using the static madCHook.lib
			FinalizeMadCHook();

			gbHookOk = FALSE;	

			CloseHandle(g_hHookMutex);

			if (g_lpMapFile != NULL)
			{
				UnmapViewOfFile(g_lpMapFile);
			}
			CloseHandle(g_hMemHandle);
	
			SetUnhandledExceptionFilter(m_oldFilter);
		}

		break;

The process only have one thread when hang-up, an the thread's stack as following:

ntoskrnl.exe!KeWaitForMultipleObjects+0xc0a
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x732
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!PoStartNextPowerIrp+0xba4
ntoskrnl.exe!PoStartNextPowerIrp+0x1821
ntoskrnl.exe!KeAcquireSpinLockAtDpcLevel+0x93d
ntoskrnl.exe!KeWaitForMutexObject+0x19f
ntoskrnl.exe!ExAcquireSharedStarveExclusive+0x30f
ntoskrnl.exe!NtQuerySystemInformation+0x5a06
ntoskrnl.exe!RtlRunOnceExecuteOnce+0x15b6
ntoskrnl.exe!RtlRunOnceExecuteOnce+0x3090
ntoskrnl.exe!NtConnectPort+0x41
ntoskrnl.exe!KeSynchronizeExecution+0x3a23
ntdll.dll!NtConnectPort+0xa
wow64.dll!Wow64EmulateAtlThunk+0x11134
wow64.dll!Wow64SystemServiceEx+0xd7
wow64cpu.dll!TurboDispatchJumpAddressEnd+0x2d
wow64.dll!Wow64SystemServiceEx+0x1ce
wow64.dll!Wow64LdrpInitialize+0x429
ntdll.dll!RtlUniform+0x6e6
ntdll.dll!RtlCreateTagHeap+0xa7
ntdll.dll!LdrInitializeThunk+0xe
ntdll.dll!NtConnectPort+0x12
DseFileSystemExt.dll!_DestroyIpcQueue@4+0x24
DseFileSystemExt.dll!DllMain+0xb56
DseFileSystemExt.dll!__DllMainCRTStartup+0x6c
DseFileSystemExt.dll!_DllMainCRTStartup+0x1e
ntdll.dll!RtlQueryEnvironmentVariable+0x241
ntdll.dll!LdrShutdownProcess+0x141
ntdll.dll!RtlExitUserProcess+0x74
cvtres.exe+0x422e
ntdll.dll!RtlInitializeExceptionChain+0x63
ntdll.dll!RtlInitializeExceptionChain+0x36
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: process hang-up when exit

Post by madshi »

The process probably hangs because of the loader lock, which essentially can block other threads from running as long as anyone is in DllMain. Which means that the IPC thread may not be able to close down while you're in DllMain. DestroyIpcQueue is simply not written for use in DllMain. The DllMain documentation (see Microsoft) clearly states that you have to be very careful about what you do in DllMain, otherwise you'll risk deadlocks. That's Windows design, not a bug in madCodeHook.

There are 2 possible solutions:

(1) Somehow implement a logic which calls DestroyIpcQueue before your dll goes into DllMain(PROCESS_DETACH). I'm not sure if you can do this, depends on whether you know that your dll is going to be unloaded before it is actually unloaded.

(2) Replace the IPC logic with something else. E.g. if you need to know which process is a trusted one and which not, simply create a dummy named object for each process. E.g. in WinWord (trusted) use CreateEvent(..., "%processId%IsTrusted") and in WordPad (not trusted) do CreateEvent(..., "%processId%IsNotTrusted"). Then when anyone needs to know which process is trusted and which is not, simply try OpenEvent. Of course this is just one way to do it. There are others (e.g. storing everything in one big shared memory buffer). In any case, it is possible, although might need more work/code, to solve such problems with creating and destroying IPC queues in DllMain.

Please see hooking rule 9:

http://help.madshi.net/HookingRules.htm

It clearly states that what you're doing now is not a good idea for overall stability.
powerlinm
Posts: 33
Joined: Mon Dec 17, 2007 8:05 am

Re: process hang-up when exit

Post by powerlinm »

Thanks madshi.
For your 2 solutions:
1. There is no way to know my dll is going to be unloaded, so this solution is impossible.
2. This solusion may be work, but I will do many other work to Implement those functions.
No matter how, thank you very much for your advice, I will try to use your suggestion.
Post Reply