Windows 系统调用后如何进行反汇编
How to get disassembly after syscall in Windows
我想获取 NtDelayExecution()
的汇编程序源代码,以了解什么是 Sleep()
及其内部工作原理。
但只有我在 Visual Studio 2017 调试器中得到的是:
NtDelayExecution:
mov r10,rcx
mov eax,34h
test byte ptr [........],1
jne NtDelayExecution+15h
syscall
ret
NtDelayExecution+15h:
int 2Eh
ret
它通过 syscall
指令就像它是常规的 mov
而不是 call
(即使我按 F11)。结果只是 "magically" 出现,没有提供它的可见代码,也没有办法找到它在哪里的痕迹或提示。似乎它的工作方式类似于旧 DOS 操作系统时代的 int 21h
中断。而它放入eax的是一个函数号。
进一步拆解正在发生的事情的最简单方法是什么?
也许可以阅读有关该主题的一些文献?
(我的 OS 是 Windows 10 x64,IDE 是 Visual Studio 2017 社区)
不确定,是否确实需要内核调试会话本身。如果你只需要反汇编,没有内核调试经验,你可以选择更简单的方法。
Mark Russinovich 的 Process Explorer 是一个简单易用的工具,可以帮助获得线索并调查正在发生的事情。例如,它可以显示线程调用堆栈,并以人类可读的名称公开堆栈的内核部分:
ntoskrnl.exe!KeSynchronizeExecution+0x3f26
ntoskrnl.exe!KeWaitForMultipleObjects+0x109c
ntoskrnl.exe!KeWaitForMultipleObjects+0xb3f
ntoskrnl.exe!KeWaitForMutexObject+0x377
ntoskrnl.exe!KeUnstackDetachProcess+0x2230
ntoskrnl.exe!ObDereferenceObjectDeferDelete+0x28a
ntoskrnl.exe!KeWaitForMultipleObjects+0x1283
ntoskrnl.exe!KeWaitForMultipleObjects+0xb3f
ntoskrnl.exe!KeDelayExecutionThread+0x106
ntoskrnl.exe!CcUnpinData+0xfe
ntoskrnl.exe!setjmpex+0x3aa3
ntdll.dll!NtDelayExecution+0x14
test.exe!main+0x1f
test.exe!__scrt_common_main_seh+0x11d
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll!RtlUserThreadStart+0x21
下一步可能只是用一些反汇编程序反汇编 ntoskrnl.exe
,例如 x64dbg, or IDA Pro,您会收到反汇编请求,然后从 KeDelayExecutionThread()
条目开始调查。
关于文学,我可以向您推荐 Mark Russinovich 的书,Windows Internals。
祝你好运!
例程正在执行系统调用。
mov eax, 34h
上面的部分是将系统调用索引(又名。标识符)放入 EAX 寄存器,这是 Windows 内核稍后将依赖其内部 table 系统进行查找的内容服务程序。换句话说,这就是让 Windows 内核知道系统调用是针对 NtDelayExecution 的。
syscall
上面的部分实际上是让系统调用发生,这是从用户模式到内核模式的转换。 SYSCALL 指令是 x86 指令集的一部分。
然后 Windows 内核将获取 NtDelayExecution 的地址,该地址将出现在 NTOSKRNL(内核模式内存)下,调用它,然后将 return 状态传回给用户-模式版本的 NtDelayExecution 由 NTDLL 导出(除了系统调用让内核执行操作什么都不做)。
通俗地说,在用户模式下是查不到你要找的信息的; NtDelayExecution (NTDLL) 通过系统调用向内核发出信号,以便内核执行操作。您需要研究内核模式调试或在 NTOSKRNL 上进行静态逆向工程。
如果您可以研究一下内核模式调试,请在 NtDelayExecution (NTOSKRNL) 上设置一个断点,以便在它被用户模式调用者(通过系统调用)或内核模式调用者(不需要系统调用——因为在这种情况下,调用者已经处于内核模式)。
我想获取 NtDelayExecution()
的汇编程序源代码,以了解什么是 Sleep()
及其内部工作原理。
但只有我在 Visual Studio 2017 调试器中得到的是:
NtDelayExecution:
mov r10,rcx
mov eax,34h
test byte ptr [........],1
jne NtDelayExecution+15h
syscall
ret
NtDelayExecution+15h:
int 2Eh
ret
它通过 syscall
指令就像它是常规的 mov
而不是 call
(即使我按 F11)。结果只是 "magically" 出现,没有提供它的可见代码,也没有办法找到它在哪里的痕迹或提示。似乎它的工作方式类似于旧 DOS 操作系统时代的 int 21h
中断。而它放入eax的是一个函数号。
进一步拆解正在发生的事情的最简单方法是什么? 也许可以阅读有关该主题的一些文献? (我的 OS 是 Windows 10 x64,IDE 是 Visual Studio 2017 社区)
不确定,是否确实需要内核调试会话本身。如果你只需要反汇编,没有内核调试经验,你可以选择更简单的方法。
Mark Russinovich 的 Process Explorer 是一个简单易用的工具,可以帮助获得线索并调查正在发生的事情。例如,它可以显示线程调用堆栈,并以人类可读的名称公开堆栈的内核部分:
ntoskrnl.exe!KeSynchronizeExecution+0x3f26
ntoskrnl.exe!KeWaitForMultipleObjects+0x109c
ntoskrnl.exe!KeWaitForMultipleObjects+0xb3f
ntoskrnl.exe!KeWaitForMutexObject+0x377
ntoskrnl.exe!KeUnstackDetachProcess+0x2230
ntoskrnl.exe!ObDereferenceObjectDeferDelete+0x28a
ntoskrnl.exe!KeWaitForMultipleObjects+0x1283
ntoskrnl.exe!KeWaitForMultipleObjects+0xb3f
ntoskrnl.exe!KeDelayExecutionThread+0x106
ntoskrnl.exe!CcUnpinData+0xfe
ntoskrnl.exe!setjmpex+0x3aa3
ntdll.dll!NtDelayExecution+0x14
test.exe!main+0x1f
test.exe!__scrt_common_main_seh+0x11d
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll!RtlUserThreadStart+0x21
下一步可能只是用一些反汇编程序反汇编 ntoskrnl.exe
,例如 x64dbg, or IDA Pro,您会收到反汇编请求,然后从 KeDelayExecutionThread()
条目开始调查。
关于文学,我可以向您推荐 Mark Russinovich 的书,Windows Internals。
祝你好运!
例程正在执行系统调用。
mov eax, 34h
上面的部分是将系统调用索引(又名。标识符)放入 EAX 寄存器,这是 Windows 内核稍后将依赖其内部 table 系统进行查找的内容服务程序。换句话说,这就是让 Windows 内核知道系统调用是针对 NtDelayExecution 的。
syscall
上面的部分实际上是让系统调用发生,这是从用户模式到内核模式的转换。 SYSCALL 指令是 x86 指令集的一部分。
然后 Windows 内核将获取 NtDelayExecution 的地址,该地址将出现在 NTOSKRNL(内核模式内存)下,调用它,然后将 return 状态传回给用户-模式版本的 NtDelayExecution 由 NTDLL 导出(除了系统调用让内核执行操作什么都不做)。
通俗地说,在用户模式下是查不到你要找的信息的; NtDelayExecution (NTDLL) 通过系统调用向内核发出信号,以便内核执行操作。您需要研究内核模式调试或在 NTOSKRNL 上进行静态逆向工程。
如果您可以研究一下内核模式调试,请在 NtDelayExecution (NTOSKRNL) 上设置一个断点,以便在它被用户模式调用者(通过系统调用)或内核模式调用者(不需要系统调用——因为在这种情况下,调用者已经处于内核模式)。