我正在跟踪具有以下功能的hello世界风格可执行文件:-
int (*dyncode)(int);
dyncode = (int(*)*int)) VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
我经历了正在被调用的系统调用,在我看来,似乎并没有调用NTProtectVirtualMemory系统调用。知道在调用VirtualAlloc函数时调用了哪些系统调用会很有帮助。从到目前为止的结果来看,即使可以看到对
VirtualAlloc
的调用也没有出现针对VirtualFree
的系统调用。我想做的是拦截所有分配区域的系统调用具有可执行权限。
[EDIT]
更多上下文。我试图拦截系统调用的原因是因为我最初为Linux编写了pintool,并且我求助于钩住系统调用而不是libc调用(因为我不想错过直接的mprotect系统调用)。但是,这种方法似乎不适用于Windows,因此我不得不使用IMG_Instrument PIN函数来查找和配置VirtualAlloc。
#1 楼
NtProtectVirutalMemory不是VirtualAlloc调用的一部分,而是VirtualProtect调用的一部分您可以使用此windbg条件断点在分配内存的任何可执行文件上验证pintool跟踪
0: 000> bl
0 e 7c809af1 0001(0001)0:**** kernel32!VirtualAlloc“ bp / 1 @ $ ra \” g \“; wt”
0:000> $$ break on valloc set a one time condtional break on return address on the stack (condition == keep executing as is) and trace the call
0:000> g
结果
Tracing kernel32!VirtualAlloc to return address 76fdc3ac
9 0 [ 0] kernel32!VirtualAlloc
3 0 [ 1] kernel32!VirtualAllocEx
19 0 [ 2] kernel32!_SEH_prolog
16 19 [ 1] kernel32!VirtualAllocEx
1 0 [ 2] ntdll!ZwAllocateVirtualMemory
2 0 [ 2] ntdll!NtAllocateVirtualMemory
2 0 [ 3] ntdll!KiFastSystemCall
1 0 [ 2] ntdll!NtAllocateVirtualMemory
22 25 [ 1] kernel32!VirtualAllocEx
9 0 [ 2] kernel32!_SEH_epilog
23 34 [ 1] kernel32!VirtualAllocEx
11 57 [ 0] kernel32!VirtualAlloc
68 instructions were executed in 67 events (0 from other threads)
Function Name Invocations MinInst MaxInst AvgInst
kernel32!VirtualAlloc 1 11 11 11
kernel32!VirtualAllocEx 1 23 23 23
kernel32!_SEH_epilog 1 9 9 9
kernel32!_SEH_prolog 1 19 19 19
ntdll!KiFastSystemCall 1 2 2 2
ntdll!NtAllocateVirtualMemory 2 1 2 1
ntdll!ZwAllocateVirtualMemory 1 1 1 1
1 system call was executed
Calls System Call
1 ntdll!KiFastSystemCall
编辑
带有调用堆栈和esp的原始Dword转储的VirtualProtect跟踪结果
0:001> bl
0 e 7c801ad4 0001(0001)0:**** kernel32!VirtualProtect“ dd esp l8; kb 3; bp / 1 @ $ ra \” g \“; wt “
dd esp l8
009df560 03042c08 00b10000 00002ab0 00000002
009df570 009df588 00000440 00832758 009df54c
kb 3
ChildEBP RetAddr Args to Child
009df55c 03042c08 00b10000 00002ab0 00000002 kernel32!VirtualProtect
009df58c 030420f7 008124b0 0084a610 00832758 dbghelp!idd2me+0x3d8
009dfa3c 03041c5a 00000440 00832758 00832758 dbghelp!modload+0x367
wt
Tracing kernel32!VirtualProtect to return address 03042c08
9 0 [ 0] kernel32!VirtualProtect
14 0 [ 1] kernel32!VirtualProtectEx
1 0 [ 2] ntdll!ZwProtectVirtualMemory
2 0 [ 2] ntdll!NtProtectVirtualMemory
2 0 [ 3] ntdll!KiFastSystemCall
1 0 [ 2] ntdll!NtProtectVirtualMemory
23 6 [ 1] kernel32!VirtualProtectEx
11 29 [ 0] kernel32!VirtualProtect
40 instructions were executed in 39 events (0 from other threads)
Function Name Invocations MinInst MaxInst AvgInst
kernel32!VirtualProtect 1 11 11 11
kernel32!VirtualProtectEx 1 23 23 23
ntdll!KiFastSystemCall 1 2 2 2
ntdll!NtProtectVirtualMemory 2 1 2 1
ntdll!ZwProtectVirtualMemory 1 1 1 1
1 system call was executed
Calls System Call
1 ntdll!KiFastSystemCall
评论
请注意:用户区中的系统调用ID有所不同(可能不是内核级别),因此该表对您无济于事。如果要捕获特定进程对VirtualAlloc的调用,请在其中注入DLL,并钩住VirtualAlloc(如下所示;您可以在运行时使用GetProcAddress(kernel32_handle,“ VirtualAlloc”)作为偏移量)并进行拦截。如果要在系统范围内执行此操作,则可以使用驱动程序来执行操作...或将DLL注入每个进程中。请告诉我您是否需要在单个过程中进行帮助。非常感谢您,这会有所帮助。我尚未使用DLL进行挂钩,但是我修改了pintool以便在加载新的IMG并挂钩时查找VirtualAlloc。就目前而言,这似乎可行。再次谢谢你。
@AcidShout我也在问题中添加了更多上下文。我只是很好奇,当您说“用户区中的系统调用ID有所不同”时,您的意思是针对Windows的不同版本(也跨服务包)吗?谢谢。
是的,即使在不同的Service Pack中,它们也有所不同。我不知道您的系统是什么,但是我的Windows 7 x64 Ultimate SP1和ZwResumeThread的syscall ID为0x4F(ntdll.dll,x64)。您的系统上可能有所不同。尽管ID可能相同,但是如果您希望具有可移植性,则不要依赖于此。不过,我不确定ring0。