驅動程式 - Windows Driver Model (WDM) - 使用範例 - Assembly (MASM32) - Handle File IRP - Choose DO_DIRECT_IO



參考資訊:
https://wasm.in/
http://four-f.narod.ru/
https://github.com/steward-fu/ddk

main.asm

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
158
159
.386p
.model flat, stdcall
option casemap:none
      
include c:\masm32\include\w2k\ntstatus.inc
include c:\masm32\include\w2k\ntddk.inc
include c:\masm32\include\w2k\ntoskrnl.inc
include c:\masm32\include\w2k\ntddkbd.inc
include c:\masm32\include\wxp\wdm.inc
include c:\masm32\Macros\Strings.mac
  
includelib c:\masm32\lib\wxp\i386\ntoskrnl.lib
      
public DriverEntry
      
MyDeviceExtension struct
    szBuffer byte 255 dup(?)
    pNextDevice PDEVICE_OBJECT ?
MyDeviceExtension ends
   
.code
IrpOpenClose proc pMyDevice : PDEVICE_OBJECT, pIrp : PIRP
    IoGetCurrentIrpStackLocation pIrp
    movzx eax, (IO_STACK_LOCATION ptr [eax]).MajorFunction
  
    .if eax == IRP_MJ_CREATE
        invoke DbgPrint, $CTA0("IRP_MJ_CREATE")
    .elseif eax == IRP_MJ_CLOSE
        invoke DbgPrint, $CTA0("IRP_MJ_CLOSE")
    .endif
   
    mov eax, pIrp
    and (_IRP ptr [eax]).IoStatus.Information, 0
    mov (_IRP ptr [eax]).IoStatus.Status, STATUS_SUCCESS
    fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
    mov eax, STATUS_SUCCESS
    ret
IrpOpenClose endp
   
IrpReadWrite proc uses esi edi pMyDevice : PDEVICE_OBJECT, pIrp : PIRP
    local len : dword
       
    and len, 0
    mov eax, pMyDevice
    mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
    lea edi, (MyDeviceExtension ptr [eax]).szBuffer
 
    mov eax, pIrp
    MmGetSystemAddressForMdlSafe (_IRP ptr [eax]).MdlAddress, LowPagePriority
    mov esi, eax
 
    IoGetCurrentIrpStackLocation pIrp
    movzx eax, (IO_STACK_LOCATION ptr [eax]).MajorFunction
    .if eax == IRP_MJ_WRITE
        invoke DbgPrint, $CTA0("IRP_MJ_WRITE")
           
        mov eax, pIrp
        MmGetMdlByteCount (_IRP ptr [eax]).MdlAddress
        mov len, eax
 
        invoke memcpy, edi, esi, len
        invoke DbgPrint, $CTA0("Buffer: %s, Length: %d"), edi, len
    .elseif eax == IRP_MJ_READ
        invoke DbgPrint, $CTA0("IRP_MJ_READ")
           
        mov eax, pIrp
        MmGetMdlByteCount (_IRP ptr [eax]).MdlAddress
        mov len, eax
   
        invoke strcpy, esi, edi
        invoke strlen, edi
        mov len, eax
    .endif
       
    mov eax, pIrp
    push len
    pop (_IRP ptr [eax]).IoStatus.Information
    mov (_IRP ptr [eax]).IoStatus.Status, STATUS_SUCCESS
    fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
    mov eax, STATUS_SUCCESS
    ret
IrpReadWrite endp
   
AddDevice proc pMyDriver : PDRIVER_OBJECT, pPhyDevice : PDEVICE_OBJECT
    local pMyDevice : PDEVICE_OBJECT
    local szDevName : UNICODE_STRING
    local szSymName : UNICODE_STRING
   
    invoke RtlInitUnicodeString, addr szDevName, $CTW0("\\Device\\MyDriver")
    invoke RtlInitUnicodeString, addr szSymName, $CTW0("\\DosDevices\\MyDriver")
    invoke IoCreateDevice, pMyDriver, sizeof MyDeviceExtension, addr szDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pMyDevice
    .if eax == STATUS_SUCCESS
        invoke IoAttachDeviceToDeviceStack, pMyDevice, pPhyDevice
        .if eax != NULL
            push eax
            mov eax, pMyDevice
            mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
            pop (MyDeviceExtension ptr [eax]).pNextDevice
               
            mov eax, pMyDevice
            or (DEVICE_OBJECT ptr [eax]).Flags, DO_DIRECT_IO
            and (DEVICE_OBJECT ptr [eax]).Flags, not DO_DEVICE_INITIALIZING
            invoke IoCreateSymbolicLink, addr szSymName, addr szDevName
        .endif
    .endif
    ret
AddDevice endp
   
Unload proc pMyDriver : PDRIVER_OBJECT
    ret
Unload endp
   
IrpPnp proc pMyDevice : PDEVICE_OBJECT, pIrp : PIRP
    local pDevExt : ptr
    local szSymName : UNICODE_STRING
       
    mov eax, pMyDevice
    push (DEVICE_OBJECT ptr [eax]).DeviceExtension
    pop pDevExt
       
    IoGetCurrentIrpStackLocation pIrp
    movzx eax, (IO_STACK_LOCATION ptr [eax]).MinorFunction
  
    .if eax == IRP_MN_START_DEVICE
        mov eax, pIrp
        mov (_IRP ptr [eax]).IoStatus.Status, STATUS_SUCCESS
    .elseif eax == IRP_MN_REMOVE_DEVICE
        invoke RtlInitUnicodeString, addr szSymName, $CTW0("\\DosDevices\\MyDriver")
        invoke IoDeleteSymbolicLink, addr szSymName        
        mov eax, pIrp
        mov (_IRP ptr [eax]).IoStatus.Status, STATUS_SUCCESS
       
        mov eax, pDevExt
        invoke IoDetachDevice, (MyDeviceExtension ptr [eax]).pNextDevice
        invoke IoDeleteDevice, pMyDevice
        fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
        ret
    .endif
    IoSkipCurrentIrpStackLocation pIrp
       
    mov eax, pDevExt
    invoke IoCallDriver, (MyDeviceExtension ptr [eax]).pNextDevice, pIrp
    ret
IrpPnp endp
   
DriverEntry proc pMyDriver : PDRIVER_OBJECT, pMyRegistry : PUNICODE_STRING
    mov eax, pMyDriver
    mov (DRIVER_OBJECT ptr [eax]).MajorFunction[IRP_MJ_PNP    * (sizeof PVOID)], offset IrpPnp
    mov (DRIVER_OBJECT ptr [eax]).MajorFunction[IRP_MJ_CREATE * (sizeof PVOID)], offset IrpOpenClose
    mov (DRIVER_OBJECT ptr [eax]).MajorFunction[IRP_MJ_CLOSE  * (sizeof PVOID)], offset IrpOpenClose
    mov (DRIVER_OBJECT ptr [eax]).MajorFunction[IRP_MJ_WRITE  * (sizeof PVOID)], offset IrpReadWrite
    mov (DRIVER_OBJECT ptr [eax]).MajorFunction[IRP_MJ_READ   * (sizeof PVOID)], offset IrpReadWrite
    mov (DRIVER_OBJECT ptr [eax]).DriverUnload, offset Unload
    mov eax, (DRIVER_OBJECT ptr [eax]).DriverExtension
    mov (DRIVER_EXTENSION ptr [eax]).AddDevice, AddDevice
    mov eax, STATUS_SUCCESS
    ret
DriverEntry endp
end

完成