systemcalls sistema llamadas calls windows linux assembly kernel nt-native-api

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:

  1. 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 letras Nt .
  2. System Call of windows es un subconjunto de la Native 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.