如何在 Windows 上找到系统调用?

Yan*_*ang 2 c assembly system-calls windows-11

我是汇编代码的初学者。我从来没有使用过windows汇编代码,所以我真的很困惑。

当我在 Windows 11、Visual Studio 2022 中运行时,我尝试捕获系统调用。printf("hello world!\n")我在最后一段编写了整个代码。

其实我想做的是,捕获工作printf()期间调用的系统调用printf()。这意味着,我想找到c库如何调用系统调用。

嗯,我确实喜欢这样……

  1. 在VS2022上编写printf("hello world!\n");完成的代码。
  2. 在行处设置断点printf()
  3. 使用发布模式、x64 架构运行本地 Windows 调试器。
  4. 在vs2022上打开反汇编窗口和注册窗口。
  5. 按一次仅运行一行F11

我试过了...

  1. findsyscall函数,但是VS2022的反汇编无法搜索syscall
  2. 找到call函数行并尝试搜索 RAX 代码更改为0x0001(windows systemcall) ,但我找不到。
  3. 发现 RAX 代码更改为0x0001,但我发现 RAX 代码更改0x0001add函数之类。
  4. 找到输出出现在终端上的代码行,但我F11在 10 分钟内按下了键。它是否正确?但是,更多的汇编代码仍然存在,没有完成代码运行。

所以,我有一些问题...

  1. 这个捕获系统调用的过程正确吗?如果不是,我该如何尝试?
  2. 我试图搜索哪些汇编函数调用系统调用。答案是syscallor 'call' with RAX values changes like windows system call such as '0x0001',即先查找syscallorcall函数,然后查找 RAX 值。真的吗?
  3. 将 Windowsprintf()函数代码转换为汇编代码。输出代码很长吗?我不明白为什么我尝试花费 10 多分钟来观察终端上的输出。

感谢您的阅读。

#the whole code
#include <stdio.h>

int main() {
    printf("Hello world\n");
}
Run Code Online (Sandbox Code Playgroud)

ima*_*kak 5

printf是 libc 的函数,不映射到任何 Windows 系统调用。

如果你想printf在没有任何库的情况下使用,你必须自己实现它。

以下是syscallWindows 的表格:https://github.com/hfiref0x/SyscallTables

请注意,Microsoft 正在根据 Windows 的不同版本/构建更改系统调用 ID。这意味着即使您可以在不调用 Windows 库的情况下实现printf,它很可能只能在您的本地计算机上运行。


编辑:自从问题更新以来......

不,libc 不syscall直接使用,它调用 API kernel32.dll(以及其他系统库,如user32.dllkernelbase.dll等);所有系统调用最终都在ntdll.dll.

这是因为系统调用 ID 和 API 的调用约定ntdll.dll在不同版本的 Windows 之间不断变化。为了使程序能够在其他 Windows 版本上运行,libc 仅使用 Windows SDK 中记录的 API,这些 API 是由 Microsoft 保证运行的。

所有系统调用/未记录的 API 可能会在任何更新后发生更改,恕不另行通知,因为它们不应在用户程序中使用。如果您正在开发仅适用于特定版本的 Windows 的 shell 脚本、(反)反调试工具等,那么您可以直接使用这些 API。否则你不应该使用它们。

如果你对 Windows API 是如何调用感兴趣的syscall,你可以调试Nt*Rtl*中的 API ntdll.dll,它们实际上是直接使用的。你还可以在这里syscall找到一些关于未记录的 API 的文档或ReactOS等。