我正在努力让程序使用系统调用而不是dll' s kernel32.dll
,ntdll.dll
)。
我知道例如,Windows 10 64位中的0x2C(44)系统调用是NtTerminateProcess
购买that网页。当我反汇编ntdll.dll
时,我发现了代码:
NtTerminateProcess:
mov r10, rcx
mov eax, 44
test byte [abs 7FFE0308h], 01h ;also what is in that memory address?
jnz label
syscall
ret
label:
int 46 ;and why the 46 (the 2Eh windows NT interrupt) is here
ret
我的问题是如何以这种方式终止程序?
答案 0 :(得分:6)
直接进行系统调用并不是一个好主意,因为这不是一个稳定的ABI。理论上,这些数字可以在服务包之间进行更改,甚至可以更新。
32位Windows上使用的指令在所有系统上都不一样!
Windows NT和2000始终使用int 2e
。在"更新"上运行时,Windows XP开始使用SysEnter
/ SysCall
Intel / AMD CPU(Pentium II,AMD K7及更高版本)。由于Windows XP也支持较旧的CPU,因此它使用了一个小辅助函数(SystemCallStub
)来进入内核模式。此函数(and later, the address of this function)存储在可由位于0x7ffe0000的所有名为_KUSER_SHARED_DATA
的进程访问的内存页中。
仍支持原始int 2e
方法,但我不确定为什么64位Windows无法检查要使用哪种方法,因为它运行的每个CPU都支持SysCall
。我的Windows 8机器没有检查:
0:000> uf ntdll!NtTerminateProcess
ntdll!ZwTerminateProcess:
000007ff`1ad52ea0 4c8bd1 mov r10,rcx
000007ff`1ad52ea3 b82a000000 mov eax,2Ah
000007ff`1ad52ea8 0f05 syscall
000007ff`1ad52eaa c3 ret
无论如何,这些只是实施细节,它们可以随时更改。
int 2e
可能有点慢,所以只需在64位代码中使用SysCall
,在32位代码中使用int 2e
,如果你想保持"可移植&# 34。