GNU/Linux >> Tutoriels Linux >  >> Linux

Appels système dans Windows et API native ?

J'étais intéressé à faire un appel d'API Windows en assemblage sans importation (comme exercice pédagogique), j'ai donc écrit l'assemblage FASM suivant pour faire ce que NtDll! NtCreateFile fait. C'est une démonstration approximative sur ma version 64 bits de Windows (Win10 1803 Version 10.0.17134), et il se bloque après l'appel, mais la valeur de retour de l'appel système est zéro, donc il réussit. Tout est configuré selon la convention d'appel Windows x64, puis le numéro d'appel système est chargé dans RAX, puis c'est l'instruction d'assemblage syscall pour exécuter l'appel. Mon exemple crée le fichier c:\HelloWorldFile_FASM, il doit donc être exécuté "en tant qu'administrateur".

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

J'ai utilisé la documentation de Ntdll!NtCreateFile et j'ai également utilisé le débogueur du noyau pour examiner et copier de nombreux paramètres.

__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 vous faites de la programmation en assembleur sous Windows, vous ne faites pas d'appels système manuels. Vous utilisez NTDLL et l'API native pour le faire pour vous.

L'API native est simplement un wrapper autour du côté kernelmode des choses. Tout ce qu'il fait est d'effectuer un appel système pour la bonne API.

Vous ne devriez JAMAIS avoir besoin d'effectuer un appel système manuellement afin que toute votre question soit redondante.

Les codes d'appel système Linux ne changent pas, contrairement à Windows, c'est pourquoi vous devez travailler avec une couche d'abstraction supplémentaire (alias NTDLL).

MODIFIER :

De plus, même si vous travaillez au niveau de l'assemblage, vous avez toujours un accès complet à l'API Win32, il n'y a aucune raison d'utiliser l'API NT pour commencer ! Les importations, les exportations, etc. fonctionnent parfaitement dans les programmes d'assemblage.

EDIT2 :

Si vous voulez VRAIMENT faire des appels système manuels, vous devrez inverser NTDLL pour chaque version Windows pertinente, ajouter la détection de version (via le PEB) et effectuer une recherche d'appel système pour chaque appel.

Cependant, ce serait idiot. NTDLL est là pour une raison.

Les gens ont déjà fait la partie rétro-ingénierie :voir https://j00ru.vexillium.org/syscalls/nt/64/ pour un tableau des numéros d'appel système pour chaque noyau Windows. (Notez que les dernières lignes changent même entre les versions de Windows 10.) Encore une fois, c'est une mauvaise idée en dehors des expériences à usage personnel sur votre propre machine pour en savoir plus sur asm et/ou les composants internes de Windows. N'incorporez pas d'appels système dans le code que vous distribuez à quelqu'un d'autre.


L'autre chose que vous devez savoir sur la convention d'appel système de Windows est que, si j'ai bien compris, les tables d'appel système sont générées dans le cadre du processus de construction. Cela signifie qu'ils peuvent simplement changer - personne ne les suit. Si quelqu'un en ajoute un nouveau en haut de la liste, cela n'a pas d'importance. NTDLL fonctionne toujours, donc tous ceux qui appellent NTDLL fonctionnent toujours.

Même le mécanisme utilisé pour effectuer les appels système (qui int ou sysenter) n'est pas immuable et a changé dans le passé, et je pense qu'il était une fois la même version de Windows utilisait différentes DLL qui utilisaient différents mécanismes d'entrée selon le CPU dans la machine.


Les appels système Windows sont effectués en appelant des DLL système telles que kernel32.dll ou gdi32.dll , ce qui est fait avec des appels de sous-programmes ordinaires. Les mécanismes de piégeage dans la couche privilégiée du système d'exploitation ne sont pas documentés, mais ce n'est pas grave car les DLL comme kernel32.dll fais ça pour toi.

Et par appels système, je fais référence aux points d'entrée documentés de l'API Windows comme CreateProcess() ou GetWindowText() . Les pilotes de périphérique utilisent généralement une API différente de celle du DDK Windows.


Linux
  1. Comprendre les appels système sous Linux avec strace

  2. Linux - Comment trouver les implémentations des appels système du noyau Linux ?

  3. Qu'est-ce que l'API GUI native de Linux ?

  4. Quels sont les appels OS/système natifs Windows et Linux effectués à partir de malloc() ?

  5. Pourquoi mon système de fichiers est-il monté en lecture seule ?

Comment sauver votre système Windows ou Linux avec Rescatux

Sysmon - Un moniteur système Linux (comme le gestionnaire de tâches Windows)

Créer un système hybride Linux-Windows avec Cygwin

Windows vs MacOS vs Linux - Manuel du système d'exploitation

Qu'est-ce que les appels système Linux et les fonctions de bibliothèque ?

Les 15 meilleurs émulateurs Linux pour système Windows