Windows 中的系统调用和本机 API?

2024-10-18 09:00:00
admin
原创
81
摘要:问题描述:最近我在 *NIX 操作系统中使用了很多汇编语言。我对 Windows 域感到疑惑。Linux中的调用约定:mov $SYS_Call_NUM, %eax mov $param1 , %ebx mov $param2 , %ecx int $0x80 就是这样。这就是我们在 Linux 中进行系统调...

问题描述:

最近我在 *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 APISystem calls for windows两者是指同一件事的不同术语吗?为了确认,我比较了两个非官方来源的这些内容

系统调用: http: //www.metasploit.com/users/opcode/syscalls.html

本机 API:http://undocumented.ntinternals.net/aindex.html

我的观察:

  1. 所有系统调用都以字母开头Nt,而 Native API 由许多不以字母开头的函数组成Nt

  2. 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.dllgdi32.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

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用