Windows 和本机 API 中的系统调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2489889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
System Calls in windows & Native API?
提问by claws
Recently I've been using lot of Assembly language in *NIX operating systems. I was wondering about the windows domain.
最近我在 *NIX 操作系统中使用了很多汇编语言。我想知道 Windows 域。
Calling convention in linux:
linux中的调用约定:
mov $SYS_Call_NUM, %eax
mov $param1 , %ebx
mov $param2 , %ecx
int 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
x80
Thats it. That is how we should make a system call in linux.
就是这样。这就是我们应该如何在 linux 中进行系统调用。
Reference of all system calls in linux:
linux中所有系统调用的参考:
Regarding which $SYS_Call_NUM & which parameters we can use this reference : http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
关于哪些 $SYS_Call_NUM 和哪些参数我们可以使用这个参考:http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
OFFICIAL Reference : http://kernel.org/doc/man-pages/online/dir_section_2.html
官方参考:http: //kernel.org/doc/man-pages/online/dir_section_2.html
Calling convention in Windows:
Windows 中的调用约定:
???
???
Reference of all system calls in Windows:
Windows中所有系统调用的参考:
???
???
Unofficial : http://www.metasploit.com/users/opcode/syscalls.html, but how do I use these in assembly unless I know the calling convention.
非官方:http: //www.metasploit.com/users/opcode/syscalls.html,但是除非我知道调用约定,否则我如何在程序集中使用这些。
OFFICIAL : ???
官方的 : ???
- If you say, they didn't documented it. Then how is one going to write libc for windows without knowing system calls? How is one gonna do Windows Assembly programming? Atleast in the driver programming one needs to know these. right?
- 如果你说,他们没有记录下来。那么如何在不知道系统调用的情况下为 Windows 编写 libc 呢?如何进行 Windows 汇编编程?至少在驱动程序编程中需要了解这些。对?
Now, whats up with the so called Native API? Is Native API
& System calls for windows
both are different terms referring to same thing? In order to confirm I compared these from two UNOFFICIAL Sources
现在,所谓的原生 API 怎么样了?是Native API
与System calls for windows
二者都是指同一事物的不同方面?为了确认我比较了来自两个非官方来源的这些
System Calls: http://www.metasploit.com/users/opcode/syscalls.html
系统调用:http: //www.metasploit.com/users/opcode/syscalls.html
Native API: http://undocumented.ntinternals.net/aindex.html
原生 API:http: //undocumented.ntinternals.net/aindex.html
My observations:
我的观察:
- All system calls are beginning with letters
Nt
where as Native API is consisting of lot of functions which are not beginning with lettersNt
. System Call of windows
are subset ofNative API
. System calls are just part of Native API.
- 所有系统调用都以字母开头
Nt
,而 Native API 由许多不以字母开头的函数组成Nt
。 System Call of windows
是 的子集Native API
。系统调用只是 Native API 的一部分。
Can any one confirm this and explain.
任何人都可以证实这一点并解释一下。
EDIT:
编辑:
There was another answer. It was a 2nd answer. I really liked it but I don't know why answerer has deleted it. I request him to repost his answer.
还有另一个答案。这是第二个答案。我真的很喜欢它,但我不知道为什么回答者删除了它。我要求他重新发布他的回答。
采纳答案by RaptorFactor
If you're doing assembly programming under Windows you don't do manual syscalls. You use NTDLL and the Native API to do that for you.
如果您在 Windows 下进行汇编编程,则不会进行手动系统调用。您可以使用 NTDLL 和本机 API 来为您做到这一点。
The Native API is simply a wrapper around the kernelmode side of things. All it does is perform a syscall for the correct API.
Native API 只是内核模式方面的一个包装器。它所做的只是为正确的 API 执行系统调用。
You should NEVER need to manually syscall so your entire question is redundant.
您永远不需要手动系统调用,因此您的整个问题都是多余的。
Linux syscall codes do not change, Windows's do, that's why you need to work through an extra abstraction layer (aka NTDLL).
Linux 系统调用代码不会改变,Windows 会改变,这就是为什么您需要通过额外的抽象层(又名 NTDLL)工作的原因。
EDIT:
编辑:
Also, even if you're working at the assembly level, you still have full access to the Win32 API, there's no reason to be using the NT API to begin with! Imports, exports, etc all work just fine in assembly programs.
此外,即使您在程序集级别工作,您仍然可以完全访问 Win32 API,没有理由一开始就使用 NT API!导入、导出等在汇编程序中都可以正常工作。
EDIT2:
编辑2:
If you REALLY want to do manual syscalls, you're going to need to reverse NTDLL for each relevant Windows version, add version detection (via the PEB), and perform a syscall lookup for each call.
如果您真的想进行手动系统调用,您将需要为每个相关的 Windows 版本反转 NTDLL,添加版本检测(通过 PEB),并为每个调用执行系统调用查找。
However, that would be silly. NTDLL is there for a reason.
然而,那将是愚蠢的。NTDLL 的存在是有原因的。
People have already done the reverse-engineering part: see https://j00ru.vexillium.org/syscalls/nt/64/for a table of system-call numbers for each Windows kernel. (Note that the later rows do change even between versions of Windows 10.) Again, this is a bad idea outside of personal-use-only experiments on your own machine to learn more about asm and/or Windows internals. Don't inline system calls into code that you distribute to anyone else.
人们已经完成了逆向工程部分:请参阅https://j00ru.vexillium.org/syscalls/nt/64/以获得每个 Windows 内核的系统调用号表。(请注意,即使在 Windows 10 版本之间,后面的行也会发生变化。)同样,在您自己的机器上进行仅供个人使用的实验之外,这是一个坏主意,可以了解有关 asm 和/或 Windows 内部结构的更多信息。不要将系统调用内联到您分发给其他任何人的代码中。
回答by Stewart
The other thing you need to know about the windows syscall convention is that as I understand it the syscall tables are generated as part of the build process. This means that they can simply change - no one tracks them. If someone adds a new one at the top of the list, it doesn't matter. NTDLL still works, so everyone else who calls NTDLL still works.
您需要了解的关于 windows 系统调用约定的另一件事是,据我所知,系统调用表是作为构建过程的一部分生成的。这意味着他们可以简单地改变——没有人跟踪他们。如果有人在列表的顶部添加了一个新的,也没有关系。NTDLL 仍然有效,所以其他调用 NTDLL 的人仍然有效。
Even the mechanism used to perform syscalls (which int, or sysenter) is not fixed in stone and has changed in the past, and I think that once upon a time the same version of windows used different DLLs which used different entry mechanisms depending on the CPU in the machine.
甚至用于执行系统调用(int 或 sysenter)的机制也不是一成不变的,而且在过去也发生了变化,我认为曾几何时,同一版本的 windows 使用不同的 DLL,这些 DLL 使用不同的入口机制,具体取决于机器中的 CPU。
回答by Elliot
I was interested in doing a windows API call in assembly with no imports (as an educational exercise), so I wrote the following FASM assembly to do what NtDll!NtCreateFile does. It's a rough demonstration on my 64-bit version of Windows (Win10 1803 Version 10.0.17134), and it crashes out after the call, but the return value of the syscall is zero so it is successful. Everything is set up per the Windows x64 calling convention, then the system call number is loaded into RAX, and then it's the syscall assembly instruction to run the call. My example creates the file c:\HelloWorldFile_FASM, so it has to be run "as administrator".
我有兴趣在没有导入的情况下在程序集中执行 Windows API 调用(作为教育练习),因此我编写了以下 FASM 程序集来完成 NtDll!NtCreateFile 所做的事情。在我的64位版本的Windows(Win10 1803 Version 10.0.17134)上粗略演示,调用后就崩溃了,但是syscall的返回值为零所以成功了。一切都按照 Windows x64 调用约定进行设置,然后将系统调用号加载到 RAX 中,然后是 syscall 汇编指令来运行调用。我的示例创建了文件 c:\HelloWorldFile_FASM,因此它必须以“管理员身份”运行。
__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
);
I used the documentation for Ntdll!NtCreateFile, and I also used the kernel debugger to look at and copy a lot of the params.
我使用了 Ntdll!NtCreateFile 的文档,我还使用了内核调试器来查看和复制很多参数。
##代码##回答by Will
Windows system calls are performed by calling into system DLLs such as kernel32.dll
or gdi32.dll
, which is done with ordinary subroutine calls. The mechanisms for trapping into the OS privileged layer is undocumented, but that is okay because DLLs like kernel32.dll
do this for you.
Windows 系统调用是通过调用系统 DLL 来执行的,例如kernel32.dll
或gdi32.dll
,这是通过普通子例程调用完成的。陷入操作系统特权层的机制没有记录,但没关系,因为 DLL 喜欢kernel32.dll
为你做这件事。
And by system calls, I'm referring to documented Windows API entry points like CreateProcess()
or GetWindowText()
. Device drivers will generally use a different API from the Windows DDK.
通过系统调用,我指的是记录在案的 Windows API 入口点,例如CreateProcess()
或GetWindowText()
。设备驱动程序通常会使用与 Windows DDK 不同的 API。
回答by claws
OFFICIAL Calling convention in Windows: http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
Windows 中的官方调用约定:http: //msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
(hope this link survives in the future; if it doesn't, just search for "x64 Software Conventions" on MSDN).
(希望此链接在未来继续存在;如果没有,只需在 MSDN 上搜索“x64 软件约定”)。
The function calling convention differs in Linux & Windows x86_64. In both ABIs, parameters are preferably passed via registers, but the registers used differ. More on the Linux ABI can be found at http://www.x86-64.org/documentation/abi.pdf
函数调用约定在 Linux 和 Windows x86_64 中有所不同。在这两种 ABI 中,参数最好通过寄存器传递,但使用的寄存器不同。有关 Linux ABI 的更多信息,请访问 http://www.x86-64.org/documentation/abi.pdf