驅動程式 - Windows Driver Model (WDM) - 使用範例 - Assembly (ObjAsm) - Handle IOCTL IRP - Choose METHOD_IN_DIRECT、METHOD_OUT_DIRECT



參考資訊:
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
%include @Environ(OBJASM_PATH)/Code/Macros/Model.inc
 
SysSetup OOP, WDK_WDM, ANSI_STRING
 
MakeObjects Primer, KDriver, KPnpDevice, KPnpLowerDevice
 
IOCTL_GET equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
IOCTL_SET equ CTL_CODE(FILE_DEVICE_UNKNOWN, 801h, METHOD_IN_DIRECTFILE_ANY_ACCESS)
 
Object MyDriver, , KDriver
    RedefineMethod Unload
    RedefineMethod AddDevice, PDEVICE_OBJECT
    RedefineMethod DriverEntry, PUNICODE_STRING
    RedefineMethod DriverIrpDispatch, PIRP
ObjectEnd
 
Object MyDevice, , KPnpDevice
    RedefineMethod Close, PKIrp
    RedefineMethod Create, PKIrp
    RedefineMethod DeviceControl, PKIrp
 
    RedefineMethod Init, PDEVICE_OBJECT
    RedefineMethod DefaultPnp, PKIrp
    RedefineMethod DeviceIrpDispatch, PIRP
 
    Embed m_pMyLowerDevice, KPnpLowerDevice
 
    DefineVariable m_Buffer, BYTE, 255 dup(0)
ObjectEnd
 
DECLARE_DRIVER_CLASS MyDriver, $OfsCStr("MyDriver")
 
Method MyDriver.DriverEntry, uses esi, pMyRegistry : PUNICODE_STRING
    mov eax, STATUS_SUCCESS
MethodEnd
 
Method MyDriver.AddDevice, uses esi, pPhyDevice : PDEVICE_OBJECT
    New MyDevice
    push eax
    OCall eax::MyDevice.Init, pPhyDevice
    pop eax
MethodEnd
 
Method MyDriver.DriverIrpDispatch, uses esi, pMyIrp : PIRP
    SetObject esi
    OCall DriverObject
    mov eax, (DRIVER_OBJECT ptr [eax]).DeviceObject
    mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
    OCall eax::MyDevice.DeviceIrpDispatch, pMyIrp
MethodEnd
 
Method MyDriver.Unload, uses esi
    ACall Unload
MethodEnd
 
Method MyDevice.Init, uses esi, pPhyDevice : PDEVICE_OBJECT
    ACall Init, $OfsCStrW("\Device\MyDriver"), FILE_DEVICE_UNKNOWN, $OfsCStrW("\DosDevices\MyDriver"), 0, DO_BUFFERED_IO
 
    SetObject esi
    OCall [esi].m_pMyLowerDevice::KPnpLowerDevice.Initialize, [esi].m_pMyDevice, pPhyDevice
    OCall SetLowerDevice, addr [esi].m_pMyLowerDevice
MethodEnd
 
Method MyDevice.DeviceIrpDispatch, uses esi, pMyIrp : PIRP
    ACall DeviceIrpDispatch, pMyIrp
MethodEnd
 
Method MyDevice.DefaultPnp, uses esi, I : PKIrp
    SetObject esi
    OCall I::KIrp.ForceReuseOfCurrentStackLocationInCalldown
    OCall [esi].m_pMyLowerDevice::KLowerDevice.PnpCall, I
MethodEnd
 
Method MyDevice.Create, uses esi, I : PKIrp
    T $OfsCStr("IRP_MJ_CREATE")
 
    OCall I::KIrp.PnpComplete, STATUS_SUCCESS, IO_NO_INCREMENT
MethodEnd
 
Method MyDevice.DeviceControl, uses esi, I : PKIrp
    local pMdl : POINTER
    local code : DWORD
    local dwSize : DWORD
    local pBuffer : POINTER
 
    and dwSize, 0
 
    OCall I::KIrp.IoctlCode
    mov code, eax
    .if code == IOCTL_SET
        OCall I::KIrp.IoctlBuffer
        mov pBuffer, eax
 
        SetObject esi
        OCall I::KIrp.IoctlInputBufferSize
        push dword ptr [eax]
        pop dwSize
        invoke memcpy, addr [esi].m_Buffer, pBuffer, dwSize
 
        T $OfsCStr("Buffer: %s, Length: %d"), addr [esi].m_Buffer, dwSize
    .elseif code == IOCTL_GET
        OCall I::KIrp.Mdl
        mov pMdl, eax
        MmGetSystemAddressForMdlSafe pMdl, LowPagePriority
        mov pBuffer, eax
 
        SetObject esi
        invoke strlen, pBuffer
        mov dwSize, eax
        invoke memcpy, pBuffer, addr [esi].m_Buffer, dwSize
    .endif
 
    OCall I::KIrp.Information
    push dwSize
    pop dword ptr [eax]
 
    OCall I::KIrp.PnpComplete, STATUS_SUCCESS, IO_NO_INCREMENT
MethodEnd
 
Method MyDevice.Close, uses esi, I : PKIrp
    T $OfsCStr("IRP_MJ_CLOSE")
 
    OCall I::KIrp.PnpComplete, STATUS_SUCCESS, IO_NO_INCREMENT
MethodEnd
end

完成