Hook-wrapper doesn't call my function!

Aug 30, 2010 at 1:35 PM

Hi all,

 

I created a loader that can load any process and hook its CreateFileW function. It does so by creating a remote thread and inject a DLL using the remote thread.

The injected DLL is linked with EasyHook64.dll . On the PROCESS_ATTACH message, I call a function that performs the hook install (which runs in the target process):

 

Here is the code:

 

	HMODULE hKernel32 = LoadLibraryA("kernel32.dll");
	TRACED_HOOK_HANDLE hHook = NULL;
	NTSTATUS rc;
	ULONG ACLEntries[1] = {0};

	MessageBoxW(NULL, L"Installing...", L"Message!", MB_OK);
	DebugBreak();

	hHook = (TRACED_HOOK_HANDLE) VirtualAlloc(NULL, sizeof(HOOK_TRACE_INFO), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	rc = LhInstallHook(GetProcAddress(hKernel32, "CreateFileW"), CreateFileWHook, (PVOID)0x12345678, hHook);
	if (!SUCCEEDED(rc)) {
		MessageBoxW(NULL, L"Shit", L"aaa File!", MB_OK);
	}

    	// activate the hook for the current thread
    	rc = LhSetInclusiveACL(ACLEntries, 1, hHook);
	if (!SUCCEEDED(rc)) {
		MessageBoxW(NULL, L"Shit2", L"aaa File!", MB_OK);
	}

After the first MessageBox, I attached to my target process using windbg and made sure the hook is installed:


--- Before

0:001> u kernel32!CreateFileWImplementation
kernel32!CreateFileWImplementation:
00000000`77412a30 48895c2408      mov     qword ptr [rsp+8],rbx
00000000`77412a35 48896c2410      mov     qword ptr [rsp+10h],rbp
00000000`77412a3a 4889742418      mov     qword ptr [rsp+18h],rsi
00000000`77412a3f 57              push    rdi
00000000`77412a40 4883ec50        sub     rsp,50h
00000000`77412a44 8bda            mov     ebx,edx
00000000`77412a46 488bf9          mov     rdi,rcx
00000000`77412a49 488bd1          mov     rdx,rcx


--- After

0:001> u kernel32!CreateFileWImplementation
kernel32!CreateFileWImplementation:
00000000`77412a30 e963d8fdff      jmp     00000000`773f0298
00000000`77412a35 48896c2410      mov     qword ptr [rsp+10h],rbp
00000000`77412a3a 4889742418      mov     qword ptr [rsp+18h],rsi
00000000`77412a3f 57              push    rdi
00000000`77412a40 4883ec50        sub     rsp,50h
00000000`77412a44 8bda            mov     ebx,edx
00000000`77412a46 488bf9          mov     rdi,rcx
00000000`77412a49 488bd1          mov     rdx,rcx

 

But the hook itself doesn't work, the trampoline jumps to a wrapper and it decides not to execute my procedure.

1. Can you suggest what is the problem?
2. How can I decide whether to call the original CreateFileW or dismiss it?

Please help, I have a deadline coming ;-)

Thank you!
-- Dave

Aug 30, 2010 at 1:59 PM

I also enumerated all the threads, and pass their IDs to LhSetInclusiveACL, but still it doesn't work!

Aug 31, 2010 at 1:25 AM

1.  Your code seems correct.  I have no advice for you.  A post of the call stack may help.

2.  The "wrapper" will check if the call is coming from hooked function or not.  If it comes from hooked function, it will call the original API.  Or, you can get the original API pointer from TRACED_HOOK_HANDLE::Link::OldProc.

Aug 31, 2010 at 2:04 PM

I put a breakpoint on kernel32!CreateFileWImplementation as soon after the trampoline was written.

Here is the call stack when I got a hit on the bp:

 # Call Site
00 kernel32!CreateFileWImplementation
01 injected!InstallHook+0x17d
02 injected!DllMain+0x50
03 injected!__DllMainCRTStartup+0xae
04 injected!_DllMainCRTStartup+0x31
05 ntdll!LdrpRunInitializeRoutines+0x1fe
06 ntdll!LdrpLoadDll+0x31e
07 ntdll!LdrLoadDll+0x9a
08 KERNELBASE!LoadLibraryExW+0x19c
09 KERNELBASE!LoadLibraryExA+0x51
0a kernel32!LoadLibraryA+0x34
0b kernel32!BaseThreadInitThunk+0xd
0c ntdll!RtlUserThreadStart+0x1d

Here is the "wrapper" code:

00000000`76fe029b 51              push    rcx
00000000`76fe029c 52              push    rdx
00000000`76fe029d 4150            push    r8
00000000`76fe029f 4151            push    r9
00000000`76fe02a1 4883ec40        sub     rsp,40h
00000000`76fe02a5 0f11442430      movups  xmmword ptr [rsp+30h],xmm0
00000000`76fe02aa 0f114c2420      movups  xmmword ptr [rsp+20h],xmm1
00000000`76fe02af 0f11542410      movups  xmmword ptr [rsp+10h],xmm2
00000000`76fe02b4 0f111c24        movups  xmmword ptr [rsp],xmm3
00000000`76fe02b8 4883ec20        sub     rsp,20h
00000000`76fe02bc 488d05cdffffff  lea     rax,[00000000`76fe0290]
00000000`76fe02c3 488b00          mov     rax,qword ptr [rax]
00000000`76fe02c6 f048ff00        lock inc qword ptr [rax]
00000000`76fe02ca 48833daeffffff00 cmp     qword ptr [00000000`76fe0280],0
00000000`76fe02d2 3e751a          ht jne  00000000`76fe02ef			// This JMP is taken
00000000`76fe02d5 488d05b4ffffff  lea     rax,[00000000`76fe0290]
00000000`76fe02dc 488b00          mov     rax,qword ptr [rax]
00000000`76fe02df f048ff08        lock dec qword ptr [rax]
00000000`76fe02e3 488d058effffff  lea     rax,[00000000`76fe0278]
00000000`76fe02ea e989000000      jmp     00000000`76fe0378
00000000`76fe02ef 488d0da2ffffff  lea     rcx,[00000000`76fe0298]
00000000`76fe02f6 488b942480000000 mov     rdx,qword ptr [rsp+80h]
00000000`76fe02fe 4c8d842480000000 lea     r8,[rsp+80h]
00000000`76fe0306 ff1564ffffff    call    qword ptr [00000000`76fe0270]		// Returns 0
00000000`76fe030c 4885c0          test    rax,rax
00000000`76fe030f 3e7517          ht jne  00000000`76fe0329			// Not taken
00000000`76fe0312 488d0577ffffff  lea     rax,[00000000`76fe0290]
00000000`76fe0319 488b00          mov     rax,qword ptr [rax]
00000000`76fe031c f048ff08        lock dec qword ptr [rax]
00000000`76fe0320 488d0551ffffff  lea     rax,[00000000`76fe0278]
00000000`76fe0327 eb4f            jmp     00000000`76fe0378
00000000`76fe0329 488d0511000000  lea     rax,[00000000`76fe0341]
00000000`76fe0330 4889842480000000 mov     qword ptr [rsp+80h],rax
00000000`76fe0338 488d0541ffffff  lea     rax,[00000000`76fe0280]
00000000`76fe033f eb37            jmp     00000000`76fe0378
00000000`76fe0341 6a00            push    0
00000000`76fe0343 50              push    rax
00000000`76fe0344 4883ec30        sub     rsp,30h
00000000`76fe0348 0f11442420      movups  xmmword ptr [rsp+20h],xmm0
00000000`76fe034d 488d0d44ffffff  lea     rcx,[00000000`76fe0298]
00000000`76fe0354 488d542438      lea     rdx,[rsp+38h]
00000000`76fe0359 ff1529ffffff    call    qword ptr [00000000`76fe0288]
00000000`76fe035f 488d052affffff  lea     rax,[00000000`76fe0290]
00000000`76fe0366 488b00          mov     rax,qword ptr [rax]
00000000`76fe0369 f048ff08        lock dec qword ptr [rax]
00000000`76fe036d 4883c430        add     rsp,30h
00000000`76fe0371 0f104424f0      movups  xmm0,xmmword ptr [rsp-10h]
00000000`76fe0376 58              pop     rax
00000000`76fe0377 c3              ret
00000000`76fe0378 4883c460        add     rsp,60h
00000000`76fe037c 0f105c24c0      movups  xmm3,xmmword ptr [rsp-40h]
00000000`76fe0381 0f105424d0      movups  xmm2,xmmword ptr [rsp-30h]
00000000`76fe0386 0f104c24e0      movups  xmm1,xmmword ptr [rsp-20h]
00000000`76fe038b 0f104424f0      movups  xmm0,xmmword ptr [rsp-10h]
00000000`76fe0390 4159            pop     r9
00000000`76fe0392 4158            pop     r8
00000000`76fe0394 5a              pop     rdx
00000000`76fe0395 59              pop     rcx
00000000`76fe0396 ff20            jmp     qword ptr [rax]
00000000`76fe0398 48895c2408      mov     qword ptr [rsp+8],rbx
00000000`76fe039d e993260200      jmp     kernel32!CreateFileWImplementation+0x5 (00000000`77002a35)


 

Sep 1, 2010 at 4:11 PM

After some tracing I dicovered that the The flow of LhBarrierIntro ends because IsLoaderLock() returns TRUE

Q.1. What does that mean, is loader locked ?
Q.2. What are the risks of running the handler when the loader is locked, in case I'm running purely unmanaged code?

Please give advice on the logic I chose for hooking:

1. I run a console application and it injects a remote thread (by calling CreateRemoteThread to a process that I choose
2. The remote threads simply performs LoadLibrary to my own coded library (A.DLL)
3. A.DLL is dynamically linked with EasyHook64.dll (On load-time)
4. DllMain() of A.DLL Calls my own imlemented function InstallHook() on DLL_PROCESS_ATTACH.
5. InstallHook() uses LhInstallHook and LhSetInclusiveACL in order to install a hook on CreateFileW

Thanks in advance!