assembly Windows中的系统调用和本地API?

axzmvihb  于 2022-12-13  发布在  Windows
关注(0)|答案(5)|浏览(202)

最近我在 *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 APISystem calls for windows是指同一件事的不同术语吗?为了确认,我比较了两个非官方来源
系统调用:http://www.metasploit.com/users/opcode/syscalls.html
原生API:http://undocumented.ntinternals.net/aindex.html
我的观察:
1.所有系统调用都以字母Nt开头,而本地API由许多不以字母Nt开头的函数组成。

  1. System Call of windowsNative API的子集。系统调用只是本机API的一部分。
    有人能证实这一点并加以解释吗?

编辑:

有另一个答案。这是第二个答案。我真的很喜欢它,但我不知道为什么回答者删除了它。我要求他重新发布他的答案。

dwthyt8l

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内部的更多信息之外,这是一个坏主意。不要将系统调用内联到您分发给其他任何人的代码中。

m4pnthwp

m4pnthwp2#

关于windows系统调用约定,你需要知道的另一件事是,据我所知,系统调用表是作为构建过程的一部分生成的。这意味着它们可以简单地更改-没有人跟踪它们。如果有人在列表顶部添加了一个新表,也没有关系。NTDLL仍然工作,所以其他调用NTDLL的人仍然工作。
即使是用于执行系统调用的机制(int或sysenter)也不是一成不变的,在过去也发生了变化,我认为很久以前,同一版本的Windows使用不同的DLL,这些DLL根据机器中的CPU使用不同的入口机制。

bnl4lu3b

bnl4lu3b3#

我对在没有导入的程序集中进行Windows API调用很感兴趣(作为一个教育练习),所以我编写了下面的FASM程序集来完成NtDll!NtCreateFile所做的工作。(Win10 1803版本10.0.17134),并且在调用后崩溃,但系统调用的返回值为零,因此它是成功的。所有内容都是按照Windowsx 64调用约定设置的,然后系统调用号被加载到RAX中,然后是运行调用的syscall汇编指令。我的示例创建了文件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
);
vql8enpb

vql8enpb4#

Windows系统调用是通过调用系统DLL(如kernel32.dllgdi32.dll)来执行的,这是通过普通的子例程调用来完成的。捕获到操作系统特权层的机制没有文档记录,但这是可以的,因为像kernel32.dll这样的DLL会为您执行此操作。
这里的系统调用指的是文档中的Windows API入口点,如CreateProcess()GetWindowText()。设备驱动程序通常使用与Windows DDK不同的API。

gkn4icbw

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

相关问题