Sistema chiamate in finestre e API nativa?
-
21-09-2019 - |
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:
- Tutte le chiamate di sistema stanno cominciando con le lettere
Nt
dove, come API nativa è composto da molte funzioni che non iniziano con le lettereNt
. -
System Call of windows
sono sottoinsieme diNative 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.
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