IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

[NASM]Compilation driver en mode kernel windows NT


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut [NASM]Compilation driver en mode kernel windows NT
    Bonjour,

    Quelqu'un saurait-il comment compiler un driver en mode kernel sous nasm ? La documentation reste très vague à ce sujet et ne semble faire référence qu'au mode réel 16 bits:

    http://www.nasm.us/doc/nasmdoc8.html (section 8.3)

    J'ai récupéré les includes du kmdkit pour masm et écrit un script python pour convertir "equates" et autres structures dans un format lisible par nasm. Cela fait plusieurs jours que je suis coincé, des exemples de codes, il n'en manque pas sur la toile, mais ils sont tous écrits pour masm, fasm. J'ignore comment compiler mon fichier et quelles sont les directives à inclure pour indiquer à nasm le format à utiliser (Format natif PE) et définir l'adresse de base (0x10000)

    Merci d'avance.

  2. #2
    Membre émérite
    Avatar de supersnail
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 719
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 719
    Points : 2 793
    Points
    2 793
    Par défaut
    Bonjour,

    Ton tuto est un peu "outdated", étant donné qu'il parle des .exe de MS-DOS et non de Windows (bien que techniquement, un .exe Windows a toujours un header MS-DOS).

    Pour compiler, le mieux est d'utiliser un linker (je te recommande d'utiliser alink). Tu demandes à nasm de te sortir un .obj (avec -f coff si je me souviens bien), que tu link avec alink.

    Ensuite, je te conseille de te familiariser avec l'assembleur en userland, avant d'entreprendre le grand saut vers le kernel-land
    Toute question technique envoyée en MP ira directement à la poubelle

    Un code ne marchera jamais, il n'a jamais reçu la capacité de se déplacer.
    Inutile donc de dire "ça marche pas", donnez plutôt des informations précises afin de mieux pouvoir vous aider.


    Grand gourou de la -attitude

  3. #3
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par supersnail Voir le message
    Bonjour,

    Ton tuto est un peu "outdated", étant donné qu'il parle des .exe de MS-DOS et non de Windows (bien que techniquement, un .exe Windows a toujours un header MS-DOS).

    Pour compiler, le mieux est d'utiliser un linker (je te recommande d'utiliser alink). Tu demandes à nasm de te sortir un .obj (avec -f coff si je me souviens bien), que tu link avec alink.

    Ensuite, je te conseille de te familiariser avec l'assembleur en userland, avant d'entreprendre le grand saut vers le kernel-land
    C'est le linker que j'utilise, j'ai fait mes premiers pas y a pas mal de temps déjà, j'ai bien assimilé les principes de bases, les fonctions en user-land sont très bien documentés sur le site de microsoft (du moins pour ceux qui ont pas trop de problèmes avec la langue de Shakespeare). Les modules fonctionnent quasiment tous de la même manière, le reste, c'est juste une question d'ordonnancement et de mode d'adressage (corrigez-moi, si je me trompe).

    Pour ce qui est du mode noyau, les fonctions ne sont pas documentés, mais en faisant correctement ses devoirs sur google, on trouve rapidement. J'aurais juste voulu éviter de passer par le wdk pour coder un simple pilote. Pour les BSoD, virtualbox et windebug viennent à la rescousse

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Bonjour,

    J'ai finalement trouvé une solution pour compiler et linker mon driver avec nasm, alink ne produisant pas de fichier sys, avec le linker de microsoft, les APIs natives sont reconnus, mais toujours un problème d'unresolved external : NtProcessStartup venu de chaipaou... donc poubelle. Golink, quant à lui fonctionne (presque) bien.

    Cependant, je me heurte au problème suivant : ma fonction unload ne "unloade" rien du tout, ... nada.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    ;===================================================================
    ; compilation : nasm -f win32 file.asm
    ; link : golink /wdm file.obj ntoskrnl.exe 
    ; code testé avec windbg et virtualbox (winxp sp3 32)
    ;===================================================================
     
    BITS	32
     
    ;===================================================================
    ; APIs ntoskrnl.exe
    ;===================================================================
     
    extern	DbgPrint
    ;extern DbgBreakPoint
    extern	RtlInitUnicodeString
    extern 	IoCreateDevice
    extern  IoCreateSymbolicLink
    extern 	IoDeleteDevice
    extern 	IoDeleteSymbolicLink
     
     
    ;===================================================================
    ; Define
    ;===================================================================
     
    %define pDeviceName		PUNICODE_STRING	
    %define pSymbolicLinkName	PUNICODE_STRING
    %define	pDriverObject		ebp+8
     
    ;===================================================================
    ; Equate
    ;===================================================================
     
    STATUS_SUCCESS				equ 	0h
    FILE_DEVICE_UNKNOWN			equ	22h
    STATUS_DEVICE_CONFIGURATION_ERROR	equ	00c0000182h
    IRP_MJ_MAXIMUM_FUNCTION			equ 	1bh
    IO_NO_INCREMENT 			equ 	0h
    IRP_MJ_CREATE				equ 	0h
    IRP_MJ_CLOSE				equ 	2h
    IRP_MJ_DEVICE_CONTROL			equ 	0eh
     
    ;===================================================================
    ; DriverEntry
    ;===================================================================
    segment .code
     
    start:
    push	ebp
    mov	ebp, esp
     
    push 	dword msg_drv
    call 	DbgPrint
    ; initialisation chaîne unicode
    push	dword DeviceName
    push	dword pDeviceName
    call	RtlInitUnicodeString
    ; fonction iocreatedevice
    push	dword pDeviceObject
    push	dword 0h
    push	dword 0h
    push	dword FILE_DEVICE_UNKNOWN
    push	dword pDeviceName
    push	dword 0h
    push	dword [pDriverObject]
    call	IoCreateDevice
    ; if eax = non zéro
    cmp 	eax, STATUS_SUCCESS
    jne	err_IoCreateDevice
    ; else
    push 	dword IoCD_ok
    call  	DbgPrint
    ; initialisation chaîne unicode
    push	dword SymbolicLinkName
    push	dword pSymbolicLinkName
    call	RtlInitUnicodeString
    ; fonction iocreatesymboliclink
    push	dword pDeviceName
    push	dword pSymbolicLinkName
    call	IoCreateSymbolicLink
    ; if eax non zéro 
    cmp 	eax, STATUS_SUCCESS
    jne	err_IoCreateSymbolicLink
    ; else
    push 	dword IoCSL_ok
    call  	DbgPrint
    mov 	eax, dword [pDriverObject] ; ebp+8
    mov 	dword [eax+DRIVER_OBJECT.DriverUnload], UnloadRoutine 
    xor	eax, eax ; return status_success
    jmp 	drv_exit
    ; gestion erreur
    err_IoCreateDevice:
    push 	dword IoCD_err
    call  	DbgPrint
    mov	eax, STATUS_DEVICE_CONFIGURATION_ERROR
     
    err_IoCreateSymbolicLink:
    mov	eax, dword [pDriverObject]
    push	dword [eax+DRIVER_OBJECT.DeviceObject]
    call	IoDeleteDevice
    push 	dword IoCSL_err
    call  	DbgPrint
    ; fin de procédure
    drv_exit:	
    mov	esp, ebp
    pop 	ebp
    ret	8h
    ; fonction unload
    UnloadRoutine:
    push	ebp
    mov	ebp, esp
    push	SymbolicLinkName
    call	IoDeleteSymbolicLink
     
    mov	eax, dword [pDriverObject] ;ebp+8h
    push	dword [eax+DRIVER_OBJECT.DeviceObject] ; eax+34h
    call	IoDeleteDevice
    jmp   drv_exit
    ;===================================================================
    ; data
    ;===================================================================
    segment .Data 		align 4
     
    DeviceName		dw 		__utf16__('\Device\TEST_driver66'), 0h
    SymbolicLinkName	dw 		__utf16__('\DosDevices\TEST_driver66'), 0h
     
    msg_drv			db 		'Driver : ok.', 0ah, 0h
    IoCD_err		db 		'Driver : IoCreateDevice Failed.',0ah, 0h
    IoCD_ok			db 		'Driver : IoCreateDevice Success.', 0ah, 0h
    IoCSL_err 		db 		'Driver : IoCreateSymbolicLink failed.', 0ah, 0h
    IoCSL_ok 		db 		'Driver : IoCreateSymbolicLink Success', 0ah, 0h
     
    ;===================================================================
    ; bss
    ;===================================================================
    segment .bss		align 4
     
    PUNICODE_STRING 			resd	2
    pDeviceObject				resd	1
     
    struc DRIVER_OBJECT
    	.Type:				resw	1
    	.Size:				resw	1
    	.DeviceObject			resd	1
    	.Flags:				resd	1
    	.DriverStart:			resd	1
    	.DriverSize:			resd	1
    	.DriverSection:			resd	1	
    	.DriverExtension:		resd	1
    	.DriverName:			resb	8
    	.HardwareDatabase:		resd	1
    	.FastIoDispatch:		resd	1
    	.DriverInit:			resd	1
    	.DriverStartIo:			resd	1
    	.DriverUnload:			resd	1
    	.MajorFunction:			resd	IRP_MJ_MAXIMUM_FUNCTION + 1
    endstruc
    Un peu d'aide serait la bienvenue...
    Merci d'avance.

  5. #5
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Bonjour.

    J'uilise MASM pour créer des drivers sous Win XP, et je ne connais pas la syntaxe NASM.
    Il me semble néammoins avoir repéré deux erreurs dans ce code.

    La première erreur consiste a utiliser la même variable pour stocker l'adresse de pDeviceName et celle de pSymbolicLinkName.

    En effet, dans la section Define, on trouve :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    %define    pDeviceName        PUNICODE_STRING	
    %define    pSymbolicLinkName  PUNICODE_STRING
    et dans la section bss :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PUNICODE_STRING                  resd 2
    Dans le code lui-même, on trouve d'abord :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    push	dword DeviceName
    push	dword pDeviceName
    call	RtlInitUnicodeString
    puis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    push	dword SymbolicLinkName
    push	dword pSymbolicLinkName
    call	RtlInitUnicodeString
    A ce moment, la variable PUNICODE_STRING ne contient plus pDeviceName mais pSymbolicLinkName.

    La création du lien symbolique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    push	dword pDeviceName
    push	dword pSymbolicLinkName
    call	IoCreateSymbolicLink
    doit normalement échouer ...

    C'est là qu'intervient la seconde erreur que j'ai répérée : les gestions d'erreurs ne sont pas dans le bon ordre :
    err_IoCreateDevice: a été placé dans le code avant err_IoCreateSymbolicLink:

    C'est l'inverse qu'il faut faire !

    De plus, en cas d'erreur, il faut sortir avec eax = STATUS_DEVICE_CONFIGURATION_ERROR, ce que ce code ne fait pas lorsque IoCreateSymbolicLink échoue.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Juste pour info, au cas où tu ne serais pas attaché à Nasm.

    Sous Fasm:

    format PE native

    Point barre.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Prof Voir le message
    Bonjour.

    J'uilise MASM pour créer des drivers sous Win XP, et je ne connais pas la syntaxe NASM.
    Bonsoir,

    Merci de ton intervention prof, les deux "define" pointe bien vers la même structure, mais je n'ai pas de problème avec la création du périphérique et de son lien symbolique, j'ai tracé chaque instruction sous windbg, les appels de ces fonctions ne me retourne aucune erreur (eax = 0), le lien est bien crée et présent sous "quickview".

    Citation Envoyé par n5Rzn1D9dC Voir le message
    Juste pour info, au cas où tu ne serais pas attaché à Nasm.

    Sous Fasm:

    format PE native

    Point barre.
    Je te rejoins là dessus, même plus simple : le WDK, hélas je suis mon propre tortionnaire, je veux y arriver avec nasm, ni masm, ni fasm, ni tasm, ni goasm, ni WDK, etc... après avoir fouillé des lustres, je n'ai jamais trouvé un seul semblant de réponse sur le net. Si c'est pour bêtement recopier un bout de code sans comprendre ce qu'il se passe et ce que je suis entrain de coder, ça ne m'intéresse pas

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Nen mais t'as raison. C'est ce que je fais aussi. C'est un moyen d'apprendre très rapidement et efficacement.

  9. #9
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Bonjour.

    En re-examinant le code, j'ai trouvé une erreur dans la procédure UnloadRoutine :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    push	SymbolicLinkName
    call	IoDeleteSymbolicLink
    Ce n'est pas SymbolicLinkName mais pSymbolicLinkName qu'il faut utiliser ici.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Après tu peux regarder la macro Fasm pour comprendre comment créer le format pe native.

    Pour les equates ou les structures, c'est normalement simple pour les convertir de Fasm à Nasm.

    Exemple:

    Fasm:
    Nasm:
    (un truc dans ce genre là).

    Je ne comprend pas où tu bloques en faite.
    Quand tu choisies "format pe native" sous Fasm, ça te compilera un ".sys" directement.
    Ca doit être facilement adaptable pour Nasm, si tu cherches à comprendre comment créer le format .sys en plus de ta création de driver, ça t'aidera à trouver la solution.

    Pour contre " NtProcessStartup", ce n'est pas une api mais le nom du point d'entrée des drivers .sys.

    Pour les equates et structures, donne un exemple, j'essaierais de te le traduire au format Nasm, et ensuite tu pourras sans doute te débrouiller tout seul.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par n5Rzn1D9dC Voir le message
    Après tu peux regarder la macro Fasm pour comprendre comment créer le format pe native.

    Pour les equates ou les structures, c'est normalement simple pour les convertir de Fasm à Nasm.

    Exemple:

    Fasm:
    Nasm:
    (un truc dans ce genre là).

    Je ne comprend pas où tu bloques en faite.
    Quand tu choisies "format pe native" sous Fasm, ça te compilera un ".sys" directement.
    Ca doit être facilement adaptable pour Nasm, si tu cherches à comprendre comment créer le format .sys en plus de ta création de driver, ça t'aidera à trouver la solution.

    Pour contre " NtProcessStartup", ce n'est pas une api mais le nom du point d'entrée des drivers .sys.

    Pour les equates et structures, donne un exemple, j'essaierais de te le traduire au format Nasm, et ensuite tu pourras sans doute te débrouiller tout seul.
    J'ai pas vraiment de problème pour les equates et les sructures, j'arrive à produire mon fichier sys et même à utiliser les fonctions natives, la création du device et de son lien symbolique, là ou ça coince, c'est ma procédure unloadroutine (passé en ligne 88 à la structure DRIVER_OBJECT, je souhaiterais pouvoir stopper le service de façon dynamique sans être obligé de rebooter ma machine virtuelle, pour résumer le point d'entrée de cette procédure ne semble pas être reconnu lorsque le service à été démarré, voilà ce que ça donne via un utilitaire scmmanager :
    register service : ok
    start service :ok
    stop service : échec
    unregister service : ok
    Quelque chose m'échappe et je m'arrache les cheveux là dessus ...

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Effectivement, je n'avais pas vu ton post avec le code : /

    Pour "IoDeleteDevice", tu mets un pointeur vers "pDriverObject", pourtant d'après la msdn c'est censé pointer vers la structure "device_object":

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Et je vois que tu n'utilise pas cette structure.
    Normalement ça ne devrait pas plutôt être ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    push    DeviceObject ;structure base
    call	IoDeleteDevice

  13. #13
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 12
    Points : 12
    Points
    12
    Par défaut
    Merci Prof et n5, je suis toujours planté avec cette fonction unload, le reste fonctionne (un problème de gestion avec la pile sans doute), je trouverais une solution quand j'aurais le temps, en attendant pour résoudre le topic principal,
    voici comment compiler et linker un driver avec nasm :

    Avec golink
    nasm -f win32 myfile.asm
    golink /wdm /[mes_options(voir le manuel)] %myfile% obj ntoskrnl.exe

    Avec le linker de microdaube
    link /driver:wdm /base:0x10000 /subsystem:native /align:32 /[mes autres options RTFM] %myfile%.obj ntoskrnl.lib

    Sans oublier de déclarer l'entry point dans le code principal à l'aide de la directive :

    global start

    segment .code
    start:
    mon_code

    discussion résolue

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/12/2008, 20h47
  2. [mono] Compilation sous linux, erreur dans windows
    Par AlexandreP dans le forum Mono
    Réponses: 6
    Dernier message: 18/08/2006, 19h56
  3. Thread Kernel Windows
    Par loupin dans le forum Windows
    Réponses: 5
    Dernier message: 12/07/2006, 19h35
  4. Réponses: 13
    Dernier message: 14/10/2005, 11h01
  5. [Création OS] Comment compiler un bootsector + un kernel ???
    Par Damian dans le forum Programmation d'OS
    Réponses: 3
    Dernier message: 05/07/2005, 22h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo