最近我在 *NIX操作系统中使用了很多汇编语言。我想知道Windows领域。
Linux中的调用约定:
mov $SYS_Call_NUM, %eax
mov $param1 , %ebx
mov $param2 , %ecx
int $0x80
这就是我们在Linux中应该如何进行系统调用。
Linux中所有系统调用的参考:
关于哪些$SYS_Call_NUM和哪些参数我们可以使用此参考:http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
官方参考:http://kernel.org/doc/man-pages/online/dir_section_2.html
Windows中的调用约定:
???
Windows中所有系统调用的引用:
???
非官方的:http://www.metasploit.com/users/opcode/syscalls.html,但是如果我不知道调用约定,我如何在汇编中使用这些。
官员:???
- 如果你说,他们没有记录下来。那么一个人怎么能在不知道系统调用的情况下为windows写libc呢?一个人怎么能做Windows汇编编程呢?至少在驱动程序编程中,一个人需要知道这些。对吗?
现在,所谓的原生API是怎么回事?Native API
和System calls for windows
是指同一件事的不同术语吗?为了确认,我比较了两个非官方来源
系统调用:http://www.metasploit.com/users/opcode/syscalls.html
原生API:http://undocumented.ntinternals.net/aindex.html
我的观察:
1.所有系统调用都以字母Nt
开头,而本地API由许多不以字母Nt
开头的函数组成。
System Call of windows
是Native API
的子集。系统调用只是本机API的一部分。
有人能证实这一点并加以解释吗?
编辑:
有另一个答案。这是第二个答案。我真的很喜欢它,但我不知道为什么回答者删除了它。我要求他重新发布他的答案。
5条答案
按热度按时间dwthyt8l1#
如果你在Windows下进行汇编编程,你不用手动进行系统调用,你可以使用NTDLL和Native API来完成。
Native API只是一个围绕内核模式的 Package 器,它所做的只是为正确的API执行一个系统调用。
您不应该需要手动进行系统调用,因此整个问题都是多余的。
Linux系统调用代码不会改变,Windows的代码会改变,这就是为什么你需要通过一个额外的抽象层(又名NTDLL)工作。
编辑:
而且,即使您在汇编级工作,您仍然可以完全访问Win32 API,没有理由从使用NT API开始!导入、导出等操作在汇编程序中都可以正常工作。
编辑2:
如果您真的想进行手动系统调用,您将需要为每个相关的Windows版本反转NTDLL,添加版本检测(通过PEB),并为每个调用执行系统调用查找。
然而,这将是愚蠢的。NTDLL是有原因的。
人们已经完成了逆向工程部分:请参阅https://j00ru.vexillium.org/syscalls/nt/64/以获得每个Windows内核的系统调用编号表。(请注意,后面的行即使在Windows 10的不同版本之间也会发生变化。)同样,除了在您自己的计算机上进行仅供个人使用的实验以了解有关asm和/或Windows内部的更多信息之外,这是一个坏主意。不要将系统调用内联到您分发给其他任何人的代码中。
m4pnthwp2#
关于windows系统调用约定,你需要知道的另一件事是,据我所知,系统调用表是作为构建过程的一部分生成的。这意味着它们可以简单地更改-没有人跟踪它们。如果有人在列表顶部添加了一个新表,也没有关系。NTDLL仍然工作,所以其他调用NTDLL的人仍然工作。
即使是用于执行系统调用的机制(int或sysenter)也不是一成不变的,在过去也发生了变化,我认为很久以前,同一版本的Windows使用不同的DLL,这些DLL根据机器中的CPU使用不同的入口机制。
bnl4lu3b3#
我对在没有导入的程序集中进行Windows API调用很感兴趣(作为一个教育练习),所以我编写了下面的FASM程序集来完成NtDll!NtCreateFile所做的工作。(Win10 1803版本10.0.17134),并且在调用后崩溃,但系统调用的返回值为零,因此它是成功的。所有内容都是按照Windowsx 64调用约定设置的,然后系统调用号被加载到RAX中,然后是运行调用的syscall汇编指令。我的示例创建了文件c:\HelloWorldFile_FASM,因此必须“以管理员身份”运行它。
我使用了Ntdll!NtCreateFile的文档,还使用内核调试器查看和复制了大量参数。
vql8enpb4#
Windows系统调用是通过调用系统DLL(如
kernel32.dll
或gdi32.dll
)来执行的,这是通过普通的子例程调用来完成的。捕获到操作系统特权层的机制没有文档记录,但这是可以的,因为像kernel32.dll
这样的DLL会为您执行此操作。这里的系统调用指的是文档中的Windows API入口点,如
CreateProcess()
或GetWindowText()
。设备驱动程序通常使用与Windows DDK不同的API。gkn4icbw5#
Windows中的官方调用约定:http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
(hope这种链接在未来仍然存在;如果没有,只需在MSDN上搜索“x64软件约定”)。
Linux和Windows x86_64中的函数调用约定不同。在这两种ABI中,参数最好通过寄存器传递,但使用的寄存器不同。有关Linux ABI的更多信息,请访问http://www.x86-64.org/documentation/abi.pdf