Map and projects (the most frequently updated page of this blog)

2010/01/19

You can rock this land, baby

the other subsystems
In your Windows directory, most drivers have many sections, including the PAGE and INIT ones, where the EP is. All this is pretty scary, while, in the end, only a very small amount of information (compared to a GUI PE) is necessary to create a working driver:
as expected, the Subsystem has to be set to NATIVE, then relocations are compulsory since you can't tell in advance where the driver will be loaded, and a correct PE checksum is required to have the driver running.
And that's all!

at IMAGE_OPTIONAL_HEADER32.Subsystem, dw IMAGE_SUBSYSTEM_NATIVE
...
EntryPoint:
reloc1_1:
push helloworld ; PCHAR Format
call DbgPrint
add esp, 4 ; correct the stack

mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
retn 8

reloc2_2:
;%IMPORT ntoskrnl.exe!DbgPrint


Similarly, usual console binaries import Msvcrt to deal with the console, which makes them bloated and complex. While in the end, you don't need anything besides changing the subsystem. You can still call GUI APIs the usual way, and writing to console output is just a matter of getting the OUTPUT handle and writing to it.

at IMAGE_OPTIONAL_HEADER32.Subsystem, dw IMAGE_SUBSYSTEM_WINDOWS_CUI
...
EntryPoint:
push STD_OUTPUT_HANDLE ; DWORD nStdHandle
call GetStdHandle
mov [hConsoleOutput], eax

push 0 ; LPVOID lpReserved
push lpNumbersOfCharsWritten ; LPWORD lpNumbersOfCharsWritten
push HELLOWORLD_LEN ; DWORD nNumbersOfCharsToWrite
push helloworld ; VOID *lpBuffer
push dword [hConsoleOutput] ; HANDLE hConsoleOutput
call WriteConsoleA

Sources and binaries

[...]
les autres subsystems
Dans votre répertoire Windows, la plupart des drivers ont beaucoup de sections, y compris les sections PAGE and INIT, où se trouve l'EP. Tout cela peut sembler compliquè, alors qu'au final, peu de changements sont nécessaires (par rapport à un PE GUI) pour créer un driver fonctionnel :
comme attendu, le Subsystem doit être NATIVE, ensuite les relocations sont obligatoires puisqu'on ne sait pas à l'avance à quelle adresse le driver sera chargé, et une somme de contrôle correcte est requise pour charger le driver.
Et c'est tout!
at IMAGE_OPTIONAL_HEADER32.Subsystem, dw IMAGE_SUBSYSTEM_NATIVE
...
EntryPoint:
reloc1_1:
push helloworld ; PCHAR Format
call DbgPrint
add esp, 4 ; corriger la pile
mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
retn 8

reloc2_2:
;%IMPORT ntoskrnl.exe!DbgPrint


De manière similaire, les binaires console habituels importent Msvcrt pour gérer la console, ce qui les rend gros et complexes. Mais au final, on n'a besoin de rien hormis changer le Subsystem. On peut toujours appeler les APIs graphiques comme d'habitude, et écrire vers la console n'est qu'une affaire d'obtenir le handle OUTPUT et d'y écrire.

at IMAGE_OPTIONAL_HEADER32.Subsystem, dw IMAGE_SUBSYSTEM_WINDOWS_CUI
...
EntryPoint:
push STD_OUTPUT_HANDLE ; DWORD nStdHandle
call GetStdHandle
mov [hConsoleOutput], eax

push 0 ; LPVOID lpReserved
push lpNumbersOfCharsWritten ; LPWORD lpNumbersOfCharsWritten
push HELLOWORLD_LEN ; DWORD nNumbersOfCharsToWrite
push helloworld ; VOID *lpBuffer
push dword [hConsoleOutput] ; HANDLE hConsoleOutput
call WriteConsoleA

Sources et binaires

No comments:

Post a Comment