GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Systemaufrufe in Windows und nativer API?

Ich war daran interessiert, einen Windows-API-Aufruf in Assembly ohne Importe durchzuführen (als pädagogische Übung), also habe ich die folgende FASM-Assembly geschrieben, um das zu tun, was NtDll!NtCreateFile tut. Es ist eine grobe Demonstration auf meiner 64-Bit-Version von Windows (Win10 1803 Version 10.0.17134) und stürzt nach dem Aufruf ab, aber der Rückgabewert des Systemaufrufs ist Null, sodass er erfolgreich ist. Alles wird gemäß der Windows x64-Aufrufkonvention eingerichtet, dann wird die Systemaufrufnummer in RAX geladen, und dann ist es die Syscall-Assembler-Anweisung, um den Aufruf auszuführen. Mein Beispiel erstellt die Datei c:\HelloWorldFile_FASM, also muss sie "als Administrator" ausgeführt werden.

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

Ich habe die Dokumentation für Ntdll!NtCreateFile verwendet, und ich habe auch den Kernel-Debugger verwendet, um viele Parameter anzusehen und zu kopieren.

__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
);

Wenn Sie unter Windows Assembler programmieren, führen Sie keine manuellen Systemaufrufe durch. Sie verwenden NTDLL und die native API, um das für Sie zu erledigen.

Die native API ist einfach ein Wrapper um die Kernelmode-Seite der Dinge. Es führt lediglich einen Systemaufruf für die richtige API durch.

Sie sollten NIEMALS einen manuellen Systemaufruf durchführen müssen, damit Ihre gesamte Frage überflüssig ist.

Syscall-Codes von Linux ändern sich nicht, die von Windows tun es, deshalb müssen Sie sich durch eine zusätzliche Abstraktionsschicht (auch bekannt als NTDLL) arbeiten.

BEARBEITEN:

Auch wenn Sie auf Assembly-Ebene arbeiten, haben Sie immer noch vollen Zugriff auf die Win32-API, es gibt keinen Grund, zunächst die NT-API zu verwenden! Importe, Exporte usw. funktionieren in Assemblerprogrammen einwandfrei.

BEARBEITEN2:

Wenn Sie WIRKLICH manuelle Syscalls durchführen wollen, müssen Sie NTDLL für jede relevante Windows-Version umkehren, eine Versionserkennung (über das PEB) hinzufügen und für jeden Aufruf eine Syscall-Suche durchführen.

Das wäre allerdings albern. NTDLL gibt es aus einem bestimmten Grund.

Leute haben den Reverse-Engineering-Teil bereits durchgeführt:siehe https://j00ru.vexillium.org/syscalls/nt/64/ für eine Tabelle mit Systemrufnummern für jeden Windows-Kernel. (Beachten Sie, dass sich die späteren Zeilen sogar zwischen den Versionen von Windows 10 ändern.) Auch dies ist eine schlechte Idee außerhalb von Experimenten nur für den persönlichen Gebrauch auf Ihrem eigenen Computer, um mehr über asm und/oder Windows-Interna zu erfahren. Fügen Sie keine Systemaufrufe in Code ein, den Sie an andere weitergeben.


Die andere Sache, die Sie über die Windows-Syscall-Konvention wissen müssen, ist, dass die Syscall-Tabellen meines Wissens als Teil des Build-Prozesses generiert werden. Das bedeutet, dass sie sich einfach ändern können – niemand verfolgt sie. Wenn jemand oben in der Liste ein neues hinzufügt, spielt es keine Rolle. NTDLL funktioniert immer noch, also funktioniert jeder andere, der NTDLL aufruft, immer noch.

Sogar der Mechanismus, der zum Ausführen von Systemaufrufen verwendet wird (also int oder sysenter), ist nicht in Stein gemeißelt und hat sich in der Vergangenheit geändert, und ich denke, dass einst dieselbe Windows-Version verschiedene DLLs verwendete, die je nach unterschiedliche Eingabemechanismen verwendeten CPU in der Maschine.


Windows-Systemaufrufe werden durch Aufrufen von System-DLLs wie kernel32.dll ausgeführt oder gdi32.dll , was mit gewöhnlichen Unterprogrammaufrufen erfolgt. Die Mechanismen zum Einfangen in die privilegierte Ebene des Betriebssystems sind nicht dokumentiert, aber das ist in Ordnung, da DLLs wie kernel32.dll mach das für dich.

Und mit Systemaufrufen beziehe ich mich auf dokumentierte Windows-API-Einstiegspunkte wie CreateProcess() oder GetWindowText() . Gerätetreiber verwenden im Allgemeinen eine andere API als das Windows DDK.


Linux
  1. Befehl zum Ausgeben von Dateiinhalten an Stdout?

  2. Unterschied zwischen statvfs() und statfs() Systemaufrufen?

  3. Installieren von Tomcat 7 auf einem Linux-System mit Native Library

  4. Was sind die nativen Betriebssystem-/Systemaufrufe von Windows und Linux, die von malloc() ausgeführt werden?

  5. Warum ist mein Dateisystem schreibgeschützt gemountet?

So retten Sie Ihr Windows- oder Linux-System mit Rescatux

Sysmon – Ein Linux-Systemmonitor (wie Windows Task-Manager)

Erstellen eines Linux-Windows-Hybridsystems mit Cygwin

Windows vs. MacOS vs. Linux – Betriebssystemhandbuch

Was sind Linux-Systemaufrufe und Bibliotheksfunktionen?

Die 15 besten Linux-Emulatoren für Windows-Systeme