Unidentified Hook Error

closed account (G309216C)
Hi,

I am really struggling, I made a simple NT\ZW function hook, without any direct __asm keyword accept from few machine code signatures.

I have not used any fancy stuff like dissembler or anything fancy like that. All it does is add a jump in front of the Entry point of Target Address.

I do not understand why this hook is not working, what could it be? I tried to fix it for few hours still did not find a fix to it. I reckon it is something ridiculous but not jumping to any conclusions, although I doubt if I should make the patch ATOMIC but for now I want to see what is causing this error.

CODE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<Windows.h>

typedef NTSTATUS (NTAPI *ZwResumeThreads)(IN HANDLE ThreadHandle, OUT PULONG SuspendCount);

ZwResumeThreads szOldStub;
int RedirectFunction()
{
	MessageBox(0,L"Successfully Hooked",L"Success!",MB_OK);
	return 0;
}
int NtHook(__in LPVOID TargetAddress, __in LPVOID RedirectAddress , __out LPVOID* OldStub)
{
	if(TargetAddress == 0  || RedirectAddress == 0 || OldStub == 0) return 100;

	DWORD szOldPriv = 0;
	LPVOID tmpStub = VirtualAlloc(0,1024,MEM_RESERVE|MEM_TOP_DOWN|MEM_COMMIT,PAGE_EXECUTE_READWRITE);
	if(VirtualProtect(TargetAddress,5,PAGE_EXECUTE_READWRITE,&szOldPriv) == 0) {
		VirtualFree(tmpStub,0,MEM_RELEASE);
		return 200;
	}
		*(BYTE*)(tmpStub)                   = 0xB8; 
	*(DWORD*)((LPBYTE)tmpStub + 1)      = *(DWORD*)((LPBYTE)RedirectAddress + 1);

	// PUSH <RETURN ADDR> | RET
	*(BYTE*)((LPBYTE)tmpStub +  5)      = 0x68;
	*(DWORD*)((LPBYTE)tmpStub + 6)      = (DWORD)( (LPBYTE)TargetAddress + 5 );
	*(BYTE*)((LPBYTE)tmpStub +  10)     = 0xC3;

	*(BYTE*)(TargetAddress) = 0xE9; //Jump <Address>
	*(DWORD*)((LPBYTE)TargetAddress+1) = ((DWORD) RedirectAddress - ((DWORD)TargetAddress + 5 ));

	*OldStub = tmpStub;

	return 0;
}

int main(){
	ZwResumeThreads ZwThread = (ZwResumeThreads) GetProcAddress(GetModuleHandleW(L"ntdll"), "NtResumeThread");
	ULONG szSuspenLong = 0;

	szOldStub = 0;

	NtHook(ZwThread,RedirectFunction,(LPVOID*)szOldStub);

	ZwThread(((HANDLE)-2),&szSuspenLong);
}



Can someone please help me out.

Thanks!
There are a lot of magic numbers 'n stuff in there. I don't really understand it. But this sticks out as wrong:
 
*(DWORD*)((LPBYTE)tmpStub + 1)      = *(DWORD*)((LPBYTE)RedirectAddress + 1);

As RedirectAddress is the address of some function, I would expect it to be:
 
*(DWORD*)((BYTE*)tmpStub + 1)      = (DWORD*)RedirectAddress;


The same goes for:
 
*(DWORD*)((LPBYTE)tmpStub + 6)      = (DWORD)( (LPBYTE)TargetAddress + 5 );

I would expect to see::
 
*(DWORD*)((LPBYTE)tmpStub + 6)      = (DWORD*)TargetAddress;



Perhaps if you could explain the what you're doing, that might help us to help you.
Last edited on
closed account (G309216C)
Well Okay,

*(DWORD*)((LPBYTE)tmpStub + 1) = *(DWORD*)((LPBYTE)RedirectAddress + 1);

All that does is to move RedirectAddress Location into EAX with 1 as LPBYTE Format add to it. Therefore the MOV instruction will be working rather than if I insert it directly.

so this is how the instruction would look like:

mov eax, (redirectAddress+1)

then *(DWORD*)((LPBYTE)tmpStub + 6) = (DWORD)( (LPBYTE)TargetAddress + 5 );

Is to replace the hot-patch prolouge of the NT function.

and no the expectation was wrong becuase these instruction do not take in full DWORD. That way after the hook callback finished it will return the original function without the hook being active.

If you find Magic Numbers they are Machine Code which has been directly read from memory rather than using __asm becuase it can be executed from memory therefore the hook can work like a charm without reading it everytime.

Of course there can be RACE condition bugs but even if I run it on a VM it still fails.

Any other help

Topic archived. No new replies allowed.