|
忽然发现,Win64上针对NTDLL.DLL的Ring 3 Inline Hook基本上是无效的。。。
随便找个函数u一下:
lkd> u ntdll!ZwCreateUserProcess
ntdll!ZwCreateUserProcess:
00000000`77c90980 4c8bd1 mov r10,rcx
00000000`77c90983 b8aa000000 mov eax,0AAh
00000000`77c90988 0f05 syscall
00000000`77c9098a c3 ret
NTDLL.DLL里几乎所有Zw*函数(除了ZwQuerySystemTime)都是这个样子,唯一不同的地方就是index(染红处)。
所以可以使用“山寨法”。。。
把上述机器码复制到一个字节数组里,然后用VirtualProtect修改内存属性,最后直接把字节数组当作函数来调用即可。
例子(调用ZwTerminateProcess):
- typedef NTSTATUS (__fastcall *SCTERMINATEPROCESS)(HANDLE,NTSTATUS);
- NTSTATUS MyTerminateProcess(HANDLE ProcessHandle, NTSTATUS ExitStatus)
- {
- SCTERMINATEPROCESS ScTerminateProcess;
- UCHAR strShellCode[]="\x4c\x8b\xd1\xb8\x29\x00\x00\x00\x0f\x05\xc3";
- /*
- 00000000`775a0110 4c8bd1 mov r10,rcx
- 00000000`775a0113 b829000000 mov eax,29h
- 00000000`775a0118 0f05 syscall
- 00000000`775a011a c3 ret
- */
- DWORD xxx;
- strShellCode[11]=0x90;
- VirtualProtect(strShellCode,12,PAGE_EXECUTE_READWRITE,&xxx);
- PVOID p=strShellCode;
- ScTerminateProcess=(SCTERMINATEPROCESS)p;
- return ScTerminateProcess(ProcessHandle, ExitStatus);
- }
- int main()
- {
- DWORD pid=0;
- printf("[KILL PROCESS] Input process id: ");
- scanf("%ld", &pid);
- HANDLE hProcess=OpenProcess(PROCESS_TERMINATE,0,pid);
- printf("status: 0x%x\n",MyTerminateProcess(hProcess,0));
- return 0;
- }
复制代码 唯一不爽的是index可能需要硬编码,因为别人可能禁止你重载NTDLL.DLL,这样你就无法动态获得index了。
注:经KindOf提示,上面这句话作废!绕过Ring 3 Inline Hook可以完全不用硬编码!
另外,你是全局吗?不是的话,我跨进程读取另外一个进程的ntdll
见6楼。 |
|