GNU/Linux >> Znalost Linux >  >> Linux

Systémová volání ve Windows a nativní API?

Měl jsem zájem provést volání Windows API v sestavení bez importu (jako vzdělávací cvičení), a tak jsem napsal následující sestavení FASM, abych udělal to, co dělá NtDll! NtCreateFile. Je to hrubá ukázka na mé 64bitové verzi Windows (Win10 1803 verze 10.0.17134) a po volání se zhroutí, ale návratová hodnota syscall je nula, takže je úspěšný. Vše je nastaveno podle konvence volání systému Windows x64, poté se do RAX načte číslo systémového volání a poté se volání spustí pomocí instrukce sestavení syscall. Můj příklad vytvoří soubor c:\HelloWorldFile_FASM, takže musí být spuštěn "jako správce".

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

Použil jsem dokumentaci k Ntdll!NtCreateFile a také jsem použil ladicí program jádra, abych si prohlédl a zkopíroval spoustu parametrů.

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

Pokud programujete sestavení pod Windows, neprovádíte ruční systémová volání. K tomu používáte NTDLL a Native API.

Nativní API je prostě obal kolem věci v režimu jádra. Jediné, co dělá, je provést systémové volání pro správné API.

NIKDY byste neměli muset provádět systémové volání ručně, takže celá vaše otázka je nadbytečná.

Kódy syscall Linuxu se nemění, Windows ano, proto musíte pracovat s extra abstraktní vrstvou (aka NTDLL).

EDIT:

Také, i když pracujete na úrovni sestavení, stále máte plný přístup k Win32 API, není důvod používat NT API pro začátek! Importy, exporty atd. všechny v montážních programech fungují dobře.

EDIT2:

Pokud OPRAVDU chcete provádět ruční systémová volání, budete muset obrátit NTDLL pro každou relevantní verzi Windows, přidat detekci verze (prostřednictvím PEB) a pro každé volání provést vyhledávání systémových volání.

To by však bylo hloupé. NTDLL existuje z nějakého důvodu.

Lidé již provedli část reverzního inženýrství:viz https://j00ru.vexillium.org/syscalls/nt/64/ pro tabulku čísel systémových volání pro každé jádro Windows. (Všimněte si, že pozdější řádky se mění i mezi verzemi Windows 10.) Opět je to špatný nápad mimo experimenty pouze pro osobní použití na vašem vlastním počítači, abyste se dozvěděli více o asm a/nebo interních systémech Windows. Nevkládejte systémová volání do kódu, který distribuujete komukoli jinému.


Další věc, kterou potřebujete vědět o konvenci syscall systému Windows, je, že jak tomu rozumím, tabulky syscall jsou generovány jako součást procesu sestavení. To znamená, že se mohou jednoduše změnit – nikdo je nesleduje. Pokud někdo přidá nový na začátek seznamu, nevadí. NTDLL stále funguje, takže všichni ostatní, kteří volají NTDLL, stále fungují.

Dokonce i mechanismus používaný k provádění systémových volání (což je int nebo sysenter) není pevně stanoven a v minulosti se změnil a myslím, že kdysi stejná verze systému Windows používala různé knihovny DLL, které používaly různé mechanismy zadávání v závislosti na CPU v počítači.


Systémová volání Windows se provádějí voláním do systémových knihoven DLL, jako je kernel32.dll nebo gdi32.dll , což se provádí pomocí běžných volání podprogramů. Mechanismus pro zachycení do privilegované vrstvy OS není zdokumentován, ale to je v pořádku, protože knihovny DLL jako kernel32.dll udělejte to za vás.

A systémovými voláními mám na mysli zdokumentované vstupní body Windows API jako CreateProcess() nebo GetWindowText() . Ovladače zařízení budou obecně používat jiné API než Windows DDK.


Linux
  1. Pochopení systémových volání na Linuxu pomocí strace

  2. Prozkoumejte napadený server Windows

  3. Rozdíl mezi systémovými voláními statvfs() a statfs()?

  1. Instalace Tomcat 7 na systém Linux s Native Library

  2. Jaká jsou nativní volání OS/systému Windows a Linuxu prováděná z malloc()?

  3. Windows PowerShell ekvivalentní Unix/Linux `pwd`?

  1. Linux – Jak najít implementace systémových volání jádra Linuxu?

  2. Příkaz pro výstup obsahu souboru do Stdout?

  3. Co je nativní GUI API Linuxu?