Domanda

Recentemente ho usato molto il linguaggio Assembly nei sistemi operativi * nix. Mi chiedevo circa il dominio di Windows.


convenzione di chiamata in linux:

mov $SYS_Call_NUM, %eax
mov $param1 , %ebx
mov $param2 , %ecx
int $0x80

Ecco fatto. Ecco come dovremmo fare una chiamata di sistema in linux.

Riferimento di tutto chiamate di sistema in Linux:

Per quanto riguarda cui $ SYS_Call_NUM e che parametri possiamo usare questo riferimento: http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html

UFFICIALE Riferimento: http://kernel.org/doc/man-pages /online/dir_section_2.html


convenzione di chiamata in Windows:

???

Riferimento di tutto chiamate di sistema in Windows:

???

Unofficial: http://www.metasploit.com/users/opcode/syscalls. html , ma come faccio ad usare questi in assemblea a meno che non conosco la convenzione di chiamata.

UFFICIALE: ???

  • Se si dice, non hanno documentato. Allora come si fa intenzione di scrivere libc per le finestre senza sapere chiamate di sistema? Come si gonna fare programmazione Assembly di Windows? Atleast nella programmazione conducente si ha la necessità di conoscere questi. giusto?

Ora, cosa è in su con la cosiddetta API nativa? E 'Native API & System calls for windows entrambi sono termini diversi riferiscono alla stessa cosa? Per confermare ho confrontato questi provenienti da due fonti non ufficiali

chiamate di sistema: http://www.metasploit.com/users/opcode/syscalls .html

API Native: http://undocumented.ntinternals.net/aindex.html

Le mie osservazioni:

  1. Tutte le chiamate di sistema stanno cominciando con le lettere Nt dove, come API nativa è composto da molte funzioni che non iniziano con le lettere Nt.
  2. System Call of windows sono sottoinsieme di Native API. Le chiamate di sistema sono solo una parte di API nativa.

Può qualunque confermare e spiegare.

Modifica

Ci fu un'altra risposta. E 'stata una seconda risposta. Mi è piaciuto molto, ma io non so perché risposto ha eliminato. Io gli chiedo di pubblicare la sua risposta.

È stato utile?

Soluzione

Se stai facendo la programmazione assembly sotto Windows non fare chiamate di sistema manuale. Si utilizza NTDLL e l'API nativa di farlo per voi.

L'API Native è semplicemente un wrapper intorno al lato KernelMode delle cose. Tutto ciò che fa è eseguire una chiamata di sistema per l'API corretta.

È MAI dovrebbe essere necessario syscall manualmente in modo da tutta la tua domanda è superflua.

codici syscall Linux non cambiano, fare di Windows è per questo che è necessario lavorare con un livello di astrazione più (aka NTDLL).

EDIT:

Inoltre, anche se si sta lavorando a livello di assieme, è ancora pieno accesso alle API di Win32, non c'è motivo di essere utilizzando l'API NT per cominciare! Le importazioni, esportazioni, ecc tutti funzionano bene nei programmi di montaggio.

EDIT2:

Se si vuole veramente fare chiamate di sistema manuali, si sta andando ad avere bisogno di invertire NTDLL per ogni versione di Windows rilevante, aggiungere il rilevamento di versione (attraverso il PEB), ed eseguire una ricerca chiamata di sistema per ogni chiamata.

Tuttavia, sarebbe sciocco. NTDLL è lì per un motivo.

La gente ha già fatto la parte reverse-engineering: vedi https: //j00ru.vexillium .org / chiamate di sistema / nt / 64 / per una tabella di numeri sistema di chiamata per ogni kernel di Windows. (Si noti che le righe successive cambiano anche tra le versioni di Windows 10.) Ancora una volta, questa è una cattiva idea al di fuori del personale-uso-solo esperimenti sulla propria macchina per saperne di più su asm e / o interne di Windows. Non sistema in linea chiama in codice che si distribuisce a nessun altro.

Altri suggerimenti

L'altra cosa che dovete sapere sulla Convenzione di Windows chiamata di sistema è che se ho capito bene le tabelle syscall sono generate come parte del processo di generazione. Questo significa che si può semplicemente cambiare - nessuno li segue. Se qualcuno aggiunge uno nuovo in cima alla lista, non importa. NTDLL funziona ancora, in modo da tutti gli altri che chiama NTDLL funziona ancora.

Anche il meccanismo utilizzato per effettuare chiamate di sistema (che int o SYSENTER) non viene risolto in pietra e è cambiato nel passato, e ritengo che una volta la stessa versione di finestre utilizzato diverse DLL che utilizzavano differenti meccanismi di entrata a seconda della CPU nella macchina.

chiamate di sistema di Windows sono eseguite da rimettere in DLL di sistema, come kernel32.dll o gdi32.dll, che è fatto con le chiamate di subroutine ordinarie. I meccanismi per intrappolare nello strato privilegiato OS è documentato, ma che è bene perché DLL come kernel32.dll fare questo per voi.

E per chiamate di sistema, mi riferisco a punti di ingresso API di Windows documentati come CreateProcess() o GetWindowText(). I driver di periferica in genere utilizzare un'API diversa da quella di Windows DDK.

ero interessato a fare una chiamata API di Windows in assemblaggio con nessuna importazione (come un esercizio didattico), così ho scritto il seguente FASM assemblaggio di fare ciò che ntdll! Fa NtCreateFile. Si tratta di una dimostrazione di massima sulla mia versione a 64 bit di Windows (Win10 1803 versione 10.0.17134), e si blocca dopo la chiamata, ma il valore di ritorno della chiamata di sistema è pari a zero quindi è successo. Tutto è impostato per la convenzione di chiamata x64 di Windows, quindi il numero di chiamata di sistema viene caricato in RAX, e poi è le istruzioni di montaggio syscall per eseguire la chiamata. Il mio esempio crea il file C:. \ HelloWorldFile_FASM, quindi deve essere gestito "come amministratore"

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

Ho usato la documentazione per Ntdll! NtCreateFile, e ho anche usato il debugger del kernel di guardare e copiare un sacco di params.

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

UFFICIALE convenzione di chiamata in Windows: http://msdn.microsoft.com /en-us/library/7kcdt6fy.aspx

(spero questo link sopravvive in futuro; se così non fosse, basta cercare "convenzioni x64 software" a MSDN).

La convenzione funzione chiamante si differenzia in Linux e Windows x86_64. In entrambi ABI, i parametri sono preferibilmente trasmessi tramite i registri, ma i registri utilizzati differiscono. Maggiori informazioni sul Linux ABI può essere trovato alla http://www.x86-64.org /documentation/abi.pdf

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top