Windows 中的系统调用和本机 API?
- 2024-10-18 09:00:00
- admin 原创
- 82
问题描述:
最近我在 *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 汇编编程?至少在驱动程序编程中,人们需要知道这些。对吗?
那么所谓的 Native API 是怎么回事?Native API
这System calls for windows
两者是指同一件事的不同术语吗?为了确认,我比较了两个非官方来源的这些内容
系统调用: http: //www.metasploit.com/users/opcode/syscalls.html
本机 API:http://undocumented.ntinternals.net/aindex.html
我的观察:
所有系统调用都以字母开头
Nt
,而 Native API 由许多不以字母开头的函数组成Nt
。System Call of windows
是 的子集Native API
。系统调用只是 Native API 的一部分。
有人可以证实并解释这一点吗?
编辑:
还有另一个答案。这是第二个答案。我真的很喜欢它,但我不知道为什么回答者删除了它。我请求他重新发布他的答案。
解决方案 1:
如果您在 Windows 下进行汇编编程,则无需进行手动系统调用。您可以使用 NTDLL 和 Native API 来为您完成此操作。
Native API 只是内核模式方面的包装器。它所做的就是对正确的 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 内部的更多信息之外,这不是一个好主意。不要将系统调用内联到您分发给其他人的代码中。
解决方案 2:
关于 Windows 系统调用约定,您需要了解的另一件事是,据我所知,系统调用表是作为构建过程的一部分生成的。这意味着它们可以简单地更改 - 没有人跟踪它们。如果有人在列表顶部添加了一个新的,那也没关系。NTDLL 仍然有效,因此调用 NTDLL 的其他人仍然有效。
即使用于执行系统调用的机制(int 或 sysenter)也不是一成不变的,并且在过去已经发生了变化,我认为曾几何时,同一版本的 Windows 使用不同的 DLL,这些 DLL 根据机器中的 CPU 使用不同的进入机制。
解决方案 3:
我对在不导入的情况下在汇编中执行 Windows API 调用很感兴趣(作为一项教育练习),因此我编写了以下 FASM 汇编来执行 NtDll!NtCreateFile 所做的事情。这是我在 64 位版本的 Windows(Win10 1803 版本 10.0.17134)上进行的粗略演示,它在调用后崩溃,但系统调用的返回值为零,因此它是成功的。一切都按照 Windows x64 调用约定进行设置,然后将系统调用号加载到 RAX 中,然后是运行调用的系统调用汇编指令。我的示例创建了文件 c:\HelloWorldFile_FASM,因此必须“以管理员身份”运行它。
format PE64 GUI 4.0
entry start
section '.text' code readable executable
start:
;puting the first four parameters into the right registers
mov rcx, _Handle
mov rdx, [_access_mask]
mov r8, objectAttributes
mov r9, ioStatusBlock
;I think we need 1 stack word of padding:
push 0x0DF0AD8B
;pushing the other params in reverse order:
push [_eaLength]
push [_eaBuffer]
push [_createOptions]
push [_createDisposition]
push [_shareAcceses]
push [_fileAttributes]
push [_pLargeInterger]
;adding the shadow space (4x8)
; push 0x0
; push 0x0
; push 0x0
; push 0x0
;pushing the 4 register params into the shadow space for ease of debugging
push r9
push r8
push rdx
push rcx
;now pushing the return address to the stack:
push endOfProgram
mov r10, rcx ;copied from ntdll!NtCreateFile, not sure of the reason for this
mov eax, 0x55
syscall
endOfProgram:
retn
section '.data' data readable writeable
;parameters------------------------------------------------------------------------------------------------
_Handle dq 0x0
_access_mask dq 0x00000000c0100080
_pObjectAttributes dq objectAttributes ; at 00402058
_pIoStatusBlock dq ioStatusBlock
_pLargeInterger dq 0x0
_fileAttributes dq 0x0000000000000080
_shareAcceses dq 0x0000000000000002
_createDisposition dq 0x0000000000000005
_createOptions dq 0x0000000000000060
_eaBuffer dq 0x0000000000000000 ; "optional" param
_eaLength dq 0x0000000000000000
;----------------------------------------------------------------------------------------------------------
align 16
objectAttributes:
_oalength dq 0x30
_rootDirectory dq 0x0
_objectName dq unicodeString
_attributes dq 0x40
_pSecurityDescriptor dq 0x0
_pSecurityQualityOfService dq securityQualityOfService
unicodeString:
_unicodeStringLength dw 0x34
_unicodeStringMaxumiumLength dw 0x34, 0x0, 0x0
_pUnicodeStringBuffer dq _unicodeStringBuffer
_unicodeStringBuffer du '??c:HelloWorldFile_FASM' ; may need to "run as adinistrator" for the file create to work.
ioStatusBlock:
_status_pointer dq 0x0
_information dq 0x0
securityQualityOfService:
_sqlength dd 0xC
_impersonationLevel dd 0x2
_contextTrackingMode db 0x1
_effectiveOnly db 0x1, 0x0, 0x0
我使用了 Ntdll!NtCreateFile 的文档,还使用了内核调试器来查看和复制许多参数。
__kernel_entry NTSTATUS NtCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
解决方案 4:
Windows 系统调用是通过调用系统 DLL(例如kernel32.dll
或gdi32.dll
)来执行的,这可以通过普通的子程序调用来完成。进入操作系统特权层的机制尚未记录,但没关系,因为 DLL 会kernel32.dll
为您完成此操作。
我所说的系统调用指的是已记录的 Windows API 入口点,例如CreateProcess()
或GetWindowText()
。设备驱动程序通常会使用与 Windows DDK 不同的 API。
解决方案 5:
Windows 中的官方调用约定: http: //msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
(希望此链接将来能够保留;如果没有,只需在 MSDN 上搜索“x64 软件约定”)。
Linux 和 Windows x86_64 中的函数调用约定有所不同。在这两种 ABI 中,参数最好通过寄存器传递,但使用的寄存器不同。有关 Linux ABI 的更多信息,请访问http://www.x86-64.org/documentation/abi.pdf
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件