calls - ¿Llamadas al sistema en Windows y API nativa?
llamadas al sistema(< system calls>) (5)
Recientemente he estado usando mucho lenguaje ensamblador en los sistemas operativos * NIX. Me preguntaba sobre el dominio de Windows.
Convención de llamadas en linux:
mov $SYS_Call_NUM, %eax
mov $param1 , %ebx
mov $param2 , %ecx
int $0x80
Eso es. Así es como deberíamos hacer una llamada al sistema en Linux.
Referencia de todas las llamadas al sistema en Linux:
Con respecto a qué $ SYS_Call_NUM y qué parámetros podemos usar esta referencia: http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
Referencia OFICIAL: http://kernel.org/doc/man-pages/online/dir_section_2.html
Convención de llamadas en Windows:
???
Referencia de todas las llamadas al sistema en Windows:
???
No oficial: http://www.metasploit.com/users/opcode/syscalls.html , pero cómo los uso en ensamblaje a menos que conozca la convención de llamadas.
OFICIAL: ???
- Si dices, no lo documentaron. Entonces, ¿cómo se va a escribir libc para Windows sin conocer las llamadas al sistema? ¿Cómo va uno a hacer la programación de la Asamblea de Windows? Al menos en la programación del controlador uno necesita saber esto. ¿derecho?
Ahora, ¿qué pasa con la llamada API nativa? ¿ Native API
& System calls for windows
ambos son términos diferentes que hacen referencia a lo mismo? Para confirmar, comparé estos datos de dos fuentes NO OFICIALES
Llamadas al sistema: http://www.metasploit.com/users/opcode/syscalls.html
API nativa: http://undocumented.ntinternals.net/aindex.html
Mis observaciones:
- Todas las llamadas al sistema están comenzando con las letras
Nt
donde la API nativa consiste en muchas funciones que no comienzan con las letrasNt
. -
System Call of windows
es un subconjunto de laNative API
. Las llamadas al sistema son solo parte de la API nativa.
¿Alguien puede confirmar esto y explicarlo?
EDITAR:
Hubo otra respuesta. Fue una segunda respuesta. Realmente me gustó, pero no sé por qué el que responde lo ha eliminado. Le solicito que vuelva a publicar su respuesta.
Convención OFICIAL de llamadas en Windows: http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
(Espero que este enlace sobreviva en el futuro; si no lo hace, solo busque "Convenciones de software x64" en MSDN).
La convención de llamadas a funciones difiere en Linux y Windows x86_64. En ambos ABI, los parámetros se pasan preferiblemente a través de registros, pero los registros utilizados difieren. Se puede encontrar más información sobre el ABI de Linux en http://www.x86-64.org/documentation/abi.pdf
Estaba interesado en hacer una llamada a la API de Windows en ensamblado sin importar (como un ejercicio educativo), así que escribí el siguiente ensamblado de FASM para hacer lo que hace NtDll! NtCreateFile. Es una demostración aproximada en mi versión de 64 bits de Windows (Win10 1803 Versión 10.0.17134), y se cuelga después de la llamada, pero el valor de retorno de la llamada de sistema es cero, por lo que es exitoso. Todo está configurado según la convención de llamadas de Windows x64, luego el número de la llamada del sistema se carga en RAX, y luego es la instrucción de ensamblaje de syscall para ejecutar la llamada. Mi ejemplo crea el archivo c: / HelloWorldFile_FASM, por lo que debe ejecutarse "como administrador".
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
Usé la documentación para Ntdll! NtCreateFile, y también utilicé el depurador del kernel para ver y copiar muchos de los 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
);
La otra cosa que necesita saber sobre la convención de syscall de Windows es que, según tengo entendido, las tablas de syscall se generan como parte del proceso de compilación. Esto significa que simplemente pueden cambiar, nadie los rastrea. Si alguien agrega uno nuevo en la parte superior de la lista, no importa. NTDLL todavía funciona, por lo que todos los que llaman NTDLL todavía funcionan.
Incluso el mecanismo utilizado para realizar syscalls (que int, o sysenter) no está fijo en piedra y ha cambiado en el pasado, y creo que alguna vez la misma versión de Windows usaba diferentes DLL que usaban diferentes mecanismos de entrada dependiendo de la CPU en la máquina.
Las llamadas al sistema de Windows se realizan llamando a las DLL del sistema, como kernel32.dll
o gdi32.dll
, que se realiza con llamadas de subrutinas normales. Los mecanismos para atrapar en la capa con privilegios del sistema operativo no están documentados, pero eso está bien porque las DLL como kernel32.dll
hacen esto por usted.
Y por llamadas al sistema, me refiero a los puntos de entrada documentados de Windows API como CreateProcess()
o GetWindowText()
. Los controladores de dispositivos generalmente usarán una API diferente del DDK de Windows.
Si está realizando una programación de ensamblaje en Windows, no realiza llamadas de sistema manuales. Utiliza NTDLL y la API nativa para hacer eso por usted.
La API nativa es simplemente una envoltura alrededor del lado kernelmode. Todo lo que hace es realizar un syscall para la API correcta.
NUNCA debe tener que realizar una llamada de forma manual para que toda su pregunta sea redundante.
Los códigos de syscall de Linux no cambian, Windows sí, por eso es necesario trabajar a través de una capa de abstracción adicional (también conocida como NTDLL).
EDITAR:
Además, incluso si está trabajando en el nivel de ensamblaje, todavía tiene acceso completo a la API de Win32, ¡no hay ninguna razón para usar la API de NT para empezar! Las importaciones, exportaciones, etc. funcionan bien en los programas de ensamblaje.
EDIT2:
Si REALMENTE desea realizar llamadas de sistema manuales, necesitará revertir NTDLL para cada versión relevante de Windows, agregar detección de versión (a través del PEB) y realizar una búsqueda de llamada de sistema para cada llamada.
Sin embargo, eso sería una tontería. NTDLL está ahí por una razón.