GNU/Linux >> Tutoriales Linux >  >> Linux

¿Llamadas al sistema en Windows y API nativa?

Estaba interesado en hacer una llamada a la API de Windows en ensamblado sin importaciones (como un ejercicio educativo), así que escribí el siguiente ensamblado FASM para hacer lo que hace NtDll!NtCreateFile. Es una demostración aproximada en mi versión de Windows de 64 bits (Win10 1803, versión 10.0.17134), y se bloquea después de la llamada, pero el valor de retorno de la llamada al sistema es cero, por lo que tiene éxito. Todo está configurado según la convención de llamadas de Windows x64, luego el número de llamada del sistema se carga en RAX y luego es la instrucción de ensamblaje 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 usé el depurador del kernel para ver y copiar muchos de los parámetros.

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

Si está haciendo programación de ensamblaje en Windows, no realiza llamadas al sistema manuales. Utiliza NTDLL y la API nativa para hacerlo por usted.

La API nativa es simplemente un envoltorio alrededor del lado del modo kernel de las cosas. Todo lo que hace es realizar una llamada al sistema para la API correcta.

NUNCA debería necesitar llamar al sistema manualmente para que toda su pregunta sea redundante.

Los códigos de llamada al sistema de Linux no cambian, los de Windows sí, es por eso que necesita 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 razón para usar la API de NT para empezar! Las importaciones, exportaciones, etc. funcionan muy bien en los programas de ensamblaje.

EDIT2:

Si REALMENTE desea realizar llamadas de sistema manuales, necesitará invertir NTDLL para cada versión relevante de Windows, agregar detección de versión (a través de 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.

La gente ya ha hecho la parte de ingeniería inversa:consulte https://j00ru.vexillium.org/syscalls/nt/64/ para obtener una tabla de números de llamadas al sistema para cada kernel de Windows. (Tenga en cuenta que las últimas filas cambian incluso entre versiones de Windows 10). Nuevamente, esta es una mala idea fuera de los experimentos de uso personal en su propia máquina para aprender más sobre asm y/o las partes internas de Windows. No incorpores llamadas al sistema en código que distribuyas a nadie más.


La otra cosa que necesita saber sobre la convención de llamada al sistema de Windows es que, según tengo entendido, las tablas de llamada al sistema se generan como parte del proceso de compilación. Esto significa que simplemente pueden cambiar, nadie los rastrea. Si alguien agrega uno nuevo al principio de la lista, no importa. NTDLL todavía funciona, por lo que todos los demás que llamen a NTDLL seguirán funcionando.

Incluso el mecanismo utilizado para realizar syscalls (que int, o sysenter) no está fijado 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 según el CPU en la máquina.


Las llamadas al sistema de Windows se realizan llamando a archivos DLL del sistema como kernel32.dll o gdi32.dll , que se realiza con llamadas a subrutinas ordinarias. Los mecanismos para atrapar en la capa privilegiada del sistema operativo no están documentados, pero está bien porque las DLL como kernel32.dll hacer esto por ti.

Y por llamadas al sistema, me refiero a puntos de entrada documentados de la API de Windows como CreateProcess() o GetWindowText() . Los controladores de dispositivos generalmente usarán una API diferente del DDK de Windows.


Linux
  1. Comprender las llamadas al sistema en Linux con strace

  2. ¿Comando para enviar el contenido del archivo a la salida estándar?

  3. ¿Qué es la API GUI nativa de Linux?

  4. ¿Cuáles son las llamadas al sistema operativo/sistema nativo de Windows y Linux realizadas desde malloc()?

  5. ¿Por qué mi sistema de archivos está montado como de solo lectura?

Cómo rescatar su sistema Windows o Linux con Rescatux

Sysmon:un monitor de sistema Linux (como el Administrador de tareas de Windows)

Creando un sistema híbrido Linux-Windows con Cygwin

Windows vs MacOS vs Linux – Manual del sistema operativo

¿Qué son las llamadas al sistema Linux y las funciones de biblioteca?

Los 15 mejores emuladores de Linux para sistemas Windows