View previous topic :: View next topic |
Author |
Message |
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Mon Dec 19, 2011 8:17 am Post subject: Hooking Nt/Zw functions in 64 bit |
|
|
Hello,
I'm trying to find a few things on how a program works. I wanna see how it calls different API with what kind of parameters. If i do hook usermode API, they never get hitted. So what I'm trying to do is hook the nt/zw variant. Is this even possible to do in usermode (64 bit) ? And else is it possible to do in the kernel? And what way would be best (or easiest).
Also if you hook a Nt/Zw variant, does this means you get all cals, also from other processes and you've to filter this yourself?
Thanks for reading,
NM
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Mon Dec 19, 2011 9:03 am Post subject: |
|
|
In kernelmode you could try editing the undocumented KThread structure of every thread and change the service descriptor table address in there to a different address (untested)
Or use dbvm to edit the syscall msr to point to your own code
Also, is your target 64-bit or 32-bit ?
About the not getting hit:
Are you sure about that?
ZwOpenProcess is 64-bit code even in 32-bit apps (the 64-bit code segment is used for that: 33 instead of 23) So make sure your hooking code is 64-bit as well
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Mon Dec 19, 2011 9:11 am Post subject: |
|
|
Dark Byte wrote: | In kernelmode you could try editing the undocumented KThread structure of every thread and change the service descriptor table address in there to a different address (untested)
Or use dbvm to edit the syscall msr to point to your own code
Also, is your target 64-bit or 32-bit ?
About the not getting hit:
Are you sure about that?
ZwOpenProcess is 64-bit code even in 32-bit apps (the 64-bit code segment is used for that) So make sure your hooking code is 64-bit as well |
Not getting hit:
It's a anti hack program, wchich starts a driver and communicates with DeviceIocontrol. Hooking this + OpenSerivce, gives me 0 results. I used detours with this. I think it uses a trampoline bypass? or perhaps the nt variant?
And I would like to target 64 bit, since that is what I'm running on.
Is it not possible to find the nt functions address and make a jmp to my own code and use asm to find out the parameters etcetc?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Mon Dec 19, 2011 10:20 am Post subject: |
|
|
Sure it's possible to hook those functions, just not with detours as it probably doesn't know that it needs to assemble a 64-bit trampoline in a 32-bit app. And the code that is executed from the trmpoline should be 64-bit as well.
Problem is that windows by default doesn't load 64-bit dll's inside a 32-bit app so you will probably have to load the dll by hand instead of loadlibrary
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8516 Location: 127.0.0.1
|
Posted: Mon Dec 19, 2011 4:09 pm Post subject: |
|
|
I also doubt you have the professional version(s) of Detours as they cost ~$10k, the normal versions don't come with x64 support either. So you'll need to find a hooking library that supports x64. (There are a few around the net that are open source / free.)
_________________
- Retired. |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Mon Dec 19, 2011 4:45 pm Post subject: |
|
|
But the program works also fine on 32 bit. I still have to use a 64 bit hook library? Since when I use detours on my own project with MessageBoxA, it works fine.
Also can't I write myself one in pure assembly to hook kernel API fom usermode? Or do I've to be in the kernel for this?
- With GetProcAddress()?
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8516 Location: 127.0.0.1
|
Posted: Mon Dec 19, 2011 4:56 pm Post subject: |
|
|
NoMercy wrote: | But the program works also fine on 32 bit. I still have to use a 64 bit hook library? Since when I use detours on my own project with MessageBoxA, it works fine.
Also can't I write myself one in pure assembly to hook kernel API fom usermode? Or do I've to be in the kernel for this?
- With GetProcAddress()? |
If you are hooking 32bit Detours is fine, but he wants to target x64, which without the full version of Detours you can't. (Assuming he is meaning Microsoft Detours when he says Detours.)
_________________
- Retired. |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Tue Dec 20, 2011 4:46 am Post subject: |
|
|
Wiccaan wrote: |
If you are hooking 32bit Detours is fine, but he wants to target x64, which without the full version of Detours you can't. (Assuming he is meaning Microsoft Detours when he says Detours.) |
I mean microsoft detours, and yes: I don't have the full version. But if a program is workin on 64/32 bit, does it matter that I hook for 32 bit?
Also is it possible in pure asm to hook Nt functions without touching patchguard at all?
EDIT:
When I use GetProcAddress, I get this address:
Code: | NtDeviceIoControlFile - B8 04000000 - mov eax,00000004
NtDeviceIoControlFile+5 - B9 1B000000 - mov ecx,0000001B
NtDeviceIoControlFile+A - 8D 54 24 04 - lea edx,[esp+04]
NtDeviceIoControlFile+E - 64 FF 15 C0000000 - call fs:[000000C0]
NtDeviceIoControlFile+15 - 83 C4 04 - add esp,04
NtDeviceIoControlFile+18 - C2 2800 - ret 0028
NtDeviceIoControlFile+1B - 90 - nop
|
EDIT*:
This is the zw part.
Code: | ZwDeviceIoControlFile - 4C - dec esp
ZwDeviceIoControlFile+1 - 8B D1 - mov edx,ecx
ZwDeviceIoControlFile+3 - B8 04000000 - mov eax,00000004
ZwDeviceIoControlFile+8 - 0F05 - syscall
ZwDeviceIoControlFile+A - C3 - ret
ZwDeviceIoControlFile+B - 0F1F 44 00 00 - nop [eax+eax+00]
|
The syscall seems 64 bit variant to call the kernel. Is it possible for me to hook the ZwDevice + 3? and then nop the remaining byte? Would this make me see all calls from usermode to DeviceIocontrol?
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8516 Location: 127.0.0.1
|
Posted: Tue Dec 20, 2011 8:10 am Post subject: |
|
|
As long as you use the 32bit version of the program yes. If you use the 64bit version it wont work unless you get the full version or get another detouring library that supports 64bit.
_________________
- Retired. |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Tue Dec 20, 2011 9:43 am Post subject: |
|
|
Oki, I've got it working nowf or my I own process I guess. But when I inject it inside my target process it calls the function ones and it crashes after that. Is there something idiot in my code?
Code: | void ShowHook()
{
OutputDebugStringX(TEXT("NtDIC called, Handle: %X, CCode: %X "), dwDriverHandle, dwIoControlCode);
}
// this part is my own hook, not much on the internet about it? It seems //allright to me?
__declspec(naked) void hookNtDIC ()
{
__asm
{
push ebx
mov ebx, [esp + 0x08]
mov dwDriverHandle, ebx
mov ebx, [esp + 0x1c]
mov dwIoControlCode, ebx
pop ebx
// hier eventjes kijken wat wat is.
call ShowHook
// finish it
call fs:[0x0C0]
}
}
void HookNtDeviceIoControl()
{
HMODULE module = GetModuleHandle(TEXT("Ntdll.dll"));
if(!module)
//cout << "module not found, error:" << GetLastError() << endl;
MessageBoxA(0,"no module","",0);
DWORD Address = (DWORD)GetProcAddress(module,"NtDeviceIoControlFile");
if(Address)
//cout << hex << "Found address: " << Address << endl;
{
OutputDebugStringX(TEXT("address: %X"), Address);
MessageBoxA(0,"works so far","",0);
}
else
//cout << "Error: " << GetLastError() << endl;
MessageBoxA(0,"erro","",0);
DWORD Buffer = 0;
DWORD NtDIC = Address + 14;
VirtualProtect((LPVOID)NtDIC,7,PAGE_EXECUTE_READWRITE,&Buffer);
*(BYTE*)NtDIC = 0xe9;
*(DWORD*)(NtDIC+1) = jmp(NtDIC,hookNtDIC);
*(WORD*)(NtDIC+5) = 0x9090;
VirtualProtect((LPVOID)NtDIC,7,Buffer,0); |
EDIT:
Where I hook?
Code: | NtDeviceIoControlFile - B8 04000000 - mov eax,00000004
NtDeviceIoControlFile+5 - B9 1B000000 - mov ecx,0000001B
NtDeviceIoControlFile+A - 8D 54 24 04 - lea edx,[esp+04]
Hook here -> NtDeviceIoControlFile+E - 64 FF 15 C0000000 - call fs:[000000C0] |
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Tue Dec 20, 2011 11:00 am Post subject: |
|
|
Interesting, the same symbol is located at two locations (one 32 and one 64-bit)
anyhow, my NtDeviceIoControlFile (32-bit one) looks like this:
Code: |
ntdll.dll+1F8FC - B8 04000000 - mov eax,00000004
ntdll.dll+1F901 - B9 1B000000 - mov ecx,0000001B
ntdll.dll+1F906 - 8D 54 24 04 - lea edx,[esp+04]
ntdll.dll+1F90A - 64 FF 15 C0000000 - call fs:[000000C0]
ntdll.dll+1F911 - 83 C4 04 - add esp,04
ntdll.dll+1F914 - C2 2800 - ret 0028
|
I'd say that the crash is coming from missing the last 2 instructions after the call
also:
Code: |
*(WORD*)(NtDIC+5) = 0x9090;
|
WHY?
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Tue Dec 20, 2011 11:44 am Post subject: |
|
|
Euhm the 2 nops are , 64 FF 15 C0000000 = 7 bytes, while a jmp is 5 bytes? 2 remaining ones I nop? Isn't this right?
Also
added:
Code: |
RetAddr = NtDIC + 7;
//
call fs:[0x0C0]
jmp [RetAddr] |
Still it crashes?
Last edited by NoMercy on Tue Dec 20, 2011 11:54 am; edited 1 time in total |
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Tue Dec 20, 2011 11:52 am Post subject: |
|
|
ah yes, I didn't notice you hook 14 bytes after the function starts. (but still not needed as you never return)
That it doesn't break behind the call can have different reasons (eflags related delaying the breakpoint) but if it works for your own app then I guess it's ok
Have you tried hooking with just this?
Code: |
__asm
{
call fs:[0x0C0]
}
|
Does that crash as well ?
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Tue Dec 20, 2011 11:56 am Post subject: |
|
|
Dark Byte wrote: |
Code: |
__asm
{
call fs:[0x0C0]
}
|
Does that crash as well ? |
This crashes to, I'll add the jmp and see what happens
Thanks a lot, it seems to work now with the jmp. But what could be wrong with my own made asm code? It's my first time that I actually dive into this kind of things on my own.
Edit: It seems the call to my own function is wrong, lets see if i can find out what
|
|
Back to top |
|
|
NoMercy Master Cheater Reputation: 1
Joined: 09 Feb 2009 Posts: 289
|
Posted: Fri Dec 23, 2011 3:46 pm Post subject: |
|
|
I know what the error is now, it is only a weird one.
It's the call to my own function which crashes
Code: | void Show()
{
return;
}
__asm
...
..
Call Show <<---
Call fs:..
.... |
That line crashes? Anyone has an idea how that can be possible, there is nothing in it.
EDIT: It's not a "real" crash, but the program gives me an Initialize error.
|
|
Back to top |
|
|
|