IRP的創建

  1. 自己在編寫驅動程序的時候 遇到一些疑問: IoBuildSynchronousFsdRequest 和IoBuildAsynchronousFsdRequest之間創建的同步異步IRP有什麼區別?
  2. 爲什麼這兩個函數只能創建幾種IRP?調用IoAllocateIrp後 初始化IRP時哪些域是要填充的  哪些是不要填充的?
  3. 偏偏書上講的都很模糊  驅動新手  一切只能自己動手。
  4. 先來看下 IoBuildSynchronousFsdRequest
  5. .text:004191D6 _IoBuildSynchronousFsdRequest@28 proc near
  6. .text:004191D6                                         ; CODE XREF: HalExamineMBR(x,x,x,x)+70p
  7. .text:004191D6                                         ; IopShutdownBaseFileSystems(x)+7Ap ...
  8. .text:004191D6
  9. .text:004191D6 MajorFunction   = dword ptr  8
  10. .text:004191D6 DeviceObject    = dword ptr  0Ch
  11. .text:004191D6 Buffer          = dword ptr  10h
  12. .text:004191D6 Length          = dword ptr  14h
  13. .text:004191D6 StartingOffset  = dword ptr  18h
  14. .text:004191D6 Event           = dword ptr  1Ch
  15. .text:004191D6 IoStatusBlock   = dword ptr  20h
  16. .text:004191D6
  17. .text:004191D6                 mov     edi, edi
  18. .text:004191D8                 push    ebp
  19. .text:004191D9                 mov     ebp, esp
  20. .text:004191DB                 push    edi
  21. .text:004191DC                 push    [ebp+IoStatusBlock] ; IoStatusBlock
  22. .text:004191DF                 push    [ebp+StartingOffset] ; StartingOffset
  23. .text:004191E2                 push    [ebp+Length]    ; Length
  24. .text:004191E5                 push    [ebp+Buffer]    ; Buffer
  25. .text:004191E8                 push    [ebp+DeviceObject] ; DeviceObject
  26. .text:004191EB                 push    [ebp+MajorFunction] ; MajorFunction
  27. .text:004191EE                 call    _IoBuildAsynchronousFsdRequest@24 ; 創建同步IRP  實質上還是創建異步IRP
  28. .text:004191F3                 mov     edi, eax        ; pIrp送EDI 檢驗IRP是否創建成功
  29. .text:004191F5                 test    edi, edi        ; pIrp
  30. .text:004191F7                 jz      short loc_41922D
  31. .text:004191F9                 mov     eax, [ebp+Event] ; event
  32. .text:004191FC                 push    ebx
  33. .text:004191FD                 push    esi
  34. .text:004191FE                 mov     cl, 1
  35. .text:00419200                 mov     [edi+2Ch], eax  ; pIrp->UserEvent = event
  36. .text:00419203                 call    ds:__imp_@KfRaiseIrql@4 ; movzx   edx,cl
  37. .text:00419203                                         ; movzx   ecx,byte ptr [edx-7F92EDA8h]
  38. .text:00419203                                         ; mov     eax,dword ptr ds:[FFFE0080h];TPR寄存器中當前任務優先級送eax
  39. .text:00419203                                         ; mov     dword ptr ds:[0FFFE0080h],ecx;裝入新的任務優先級
  40. .text:00419203                                         ; shr     eax,4;任務優先級/16
  41. .text:00419203                                         ; movzx   eax,byte ptr [eax-7F923F78h]返回優先級
  42. .text:00419203                                         ; ret 中斷級和任務優先級的換算 還要依靠806D1258和806DC088這兩個地方的表或者結構
  43. .text:00419203                                         ; 對任務優先級不甚明白  以後有時間再仔細看看
  44. .text:00419203                                         ;
  45. .text:00419209                 mov     edx, [edi+50h]  ; pIrp->Tail.overlay.Thread
  46. .text:00419209                                         ; edx值爲ETHREAD的指針
  47. .text:0041920C                 add     edx, 210h       ; &ETHREAD.IrpList
  48. .text:0041920C                                         ; edx值爲ETHREAD.IrpList的指針
  49. .text:00419212                 mov     ebx, [edx]      ; ETHREAD.IrpList.flink
  50. .text:00419214                 lea     esi, [edi+10h]  ; &pIrp->ThreadFlink
  51. .text:00419217                 mov     [esi], ebx      ; pIrp->ThreadListEntry.flink = ETHREAD.IrpList.flink
  52. .text:00419219                 mov     [esi+4], edx    ; pIrp->ThreadListEntry.blink = &ETHREAD.IrpList
  53. .text:0041921C                 mov     [ebx+4], esi    ; ETHREAD.IrpList.flink = &pIrp->ThreadListEntry.flink
  54.                                ;IRP與線程關聯
  55. .text:0041921F                 mov     cl, al
  56. .text:00419221                 mov     [edx], esi
  57. .text:00419223                 call    ds:__imp_@KfLowerIrql@4 ; 恢復原IRQL
  58. .text:00419229                 pop     esi
  59. .text:0041922A                 mov     eax, edi
  60. .text:0041922C                 pop     ebx
  61. .text:0041922D
  62. .text:0041922D loc_41922D:                             ; CODE XREF: IoBuildSynchronousFsdRequest(x,x,x,x,x,x,x)+21j
  63. .text:0041922D                 pop     edi
  64. .text:0041922E                 pop     ebp
  65. .text:0041922F                 retn    1Ch
  66. .text:0041922F _IoBuildSynchronousFsdRequest@28 endp
  67. 從上面可以看出同步IRP和異步IRP 區別不是很大 IoBuildSynchronousFsdRequest內部調用了IoBuildAsynchronousFsdRequest 雖然同步IRP填充了IRP.UserEvent
  68. 但是  在編寫驅動時 爲了知道異步IRP操作什麼時候真正完成 有時候同樣要手動填充irp.UserEvent域。真正有點區別的估計就是同步IRP與線程關聯了
  69. 而異步IRP沒有。
  70. 再來看下IoBuildAsynchronousFsdRequest
  71. .text:00418E96 _IoBuildAsynchronousFsdRequest@24 proc near
  72. .text:00418E96                                         ; CODE XREF: IoBuildSynchronousFsdRequest(x,x,x,x,x,x,x)+18p
  73. .text:00418E96                                         ; IovBuildAsynchronousFsdRequest(x,x,x,x,x,x)+22p
  74. .text:00418E96
  75. .text:00418E96 var_20          = dword ptr -20h
  76. .text:00418E96 Irp             = dword ptr -1Ch
  77. .text:00418E96 ms_exc          = CPPEH_RECORD ptr -18h
  78. .text:00418E96 MajorFunction   = dword ptr  8
  79. .text:00418E96 DeviceObject    = dword ptr  0Ch
  80. .text:00418E96 VirtualAddress  = dword ptr  10h
  81. .text:00418E96 Length          = dword ptr  14h
  82. .text:00418E96 StartingOffset  = dword ptr  18h
  83. .text:00418E96 IoStatusBlock   = dword ptr  1Ch
  84. .text:00418E96
  85. .text:00418E96                 push    10h
  86. .text:00418E98                 push    offset stru_401748
  87. .text:00418E9D                 call    __SEH_prolog
  88. .text:00418EA2                 mov     edi, [ebp+DeviceObject]
  89. .text:00418EA5                 mov     al, [edi+30h]   ; pDeviceObject->StackSize 送al
  90. .text:00418EA8                 mov     byte ptr [ebp+var_20], al
  91. .text:00418EAB                 push    0               ; FALSE
  92. .text:00418EAD                 push    [ebp+var_20]
  93. .text:00418EB0                 call    _pIoAllocateIrp ; 分配IRP 通過調用IopAllocateIrpPrivate
  94. .text:00418EB6                 mov     esi, eax        ; pIrp送esi
  95. .text:00418EB8                 mov     [ebp+Irp], esi
  96. .text:00418EBB                 test    esi, esi
  97. .text:00418EBD                 jz      loc_418FCC
  98. .text:00418EC3                 mov     eax, large fs:124h ; &_KPCR.KPRCB.CurrentThread
  99. .text:00418EC9                 mov     [esi+50h], eax  ; pIrp->Thread = &KTHREAD KTHREAD 的地址就是ETHREAD地址
  100. .text:00418ECC                 mov     ebx, [esi+60h]  ; pIrp->IoStackLocation
  101. .text:00418ECF                 sub     ebx, 24h        ; IoStackLocation指向一個IO_STACK_LOCATION數組
  102. .text:00418ECF                                         ; -24h 就是當前IO_STACK_LOCATION[i-1] 這裏開始初始
  103. .text:00418ECF                                         ; 下一層驅動的IO_STACK_LOCATION
  104. .text:00418ED2                 mov     eax, [ebp+MajorFunction]
  105. .text:00418ED5                 mov     [ebx], al       ; IO_STACK_LOCATION.MajorFunction
  106. .text:00418ED7                 cmp     eax, 9          ; IRP_MJ_FLUSH_BUFFERS
  107. .text:00418EDA                 jz      loc_418F62
  108. .text:00418EE0                 cmp     eax, 10h        ; IRP_MJ_SHUTDOWN
  109. .text:00418EE3                 jz      short loc_418F62
  110. .text:00418EE5                 cmp     eax, 1Bh        ; IRP_MJ_PNP
  111. .text:00418EE8                 jz      short loc_418F62
  112. .text:00418EEA                 cmp     eax, 16h        ; IRP_MJ_POWER
  113. .text:00418EED                 jz      short loc_418F62
  114. .text:00418EEF                 mov     eax, [edi+1Ch]  ; pDeviceObject->flag 初始flag是C8H
  115. .text:00418EF2                 test    al, 4           ; DO_BUFFER_IO置位 是CCH
  116. .text:00418EF4                 jz      short loc_418F72
  117. .text:00418EF6                 push    20206F49h       ; Tag
  118. .text:00418EFB                 push    [ebp+Length]    ; NumberOfBytes
  119. .text:00418EFE                 push    4               ; PoolType
  120. .text:00418F00                 call    _ExAllocatePoolWithTag@12 ; ExAllocatePoolWithTag(x,x,x)
  121. .text:00418F05                 mov     [esi+0Ch], eax  ; pIrp->AssociatedIrp.SystemBuffer
  122. .text:00418F08                 test    eax, eax
  123. .text:00418F0A                 jnz     short loc_418F17
  124. .text:00418F0C
  125. .text:00418F0C loc_418F0C:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+F5j
  126. .text:00418F0C                 push    esi             ; Irp
  127. .text:00418F0D                 call    _IoFreeIrp@4    ; IoFreeIrp(x)
  128. .text:00418F12                 jmp     loc_418FCC
  129. .text:00418F17 ; ---------------------------------------------------------------------------
  130. .text:00418F17
  131. .text:00418F17 loc_418F17:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+74j
  132. .text:00418F17                 cmp     [ebp+MajorFunction], 4 ; IRP_MJ_WRITE
  133. .text:00418F1B                 jnz     short loc_418F41
  134. .text:00418F1D                 mov     ecx, [ebp+Length] ; 如果是寫請求的話
  135. .text:00418F20                 mov     esi, [ebp+VirtualAddress]
  136. .text:00418F23                 mov     edi, eax        ; 把 參數中PVOID提供的內存 複製到 分配出來的內存中的內容 中去
  137. .text:00418F25                 mov     eax, ecx
  138. .text:00418F27                 shr     ecx, 2
  139. .text:00418F2A                 rep movsd
  140. .text:00418F2C                 mov     ecx, eax
  141. .text:00418F2E                 and     ecx, 3
  142. .text:00418F31                 rep movsb
  143. .text:00418F33                 mov     eax, [ebp+Irp]
  144. .text:00418F36                 mov     dword ptr [eax+8], 30h ; pIrp->Flags
  145. .text:00418F3D                 mov     esi, eax
  146. .text:00418F3F                 jmp     short loc_418F4E
  147. .text:00418F41 ; ---------------------------------------------------------------------------
  148. .text:00418F41
  149. .text:00418F41 loc_418F41:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+85j
  150. .text:00418F41                 mov     dword ptr [esi+8], 70h
  151. .text:00418F48
  152. .text:00418F48 loc_418F48:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+DEj
  153. .text:00418F48                 mov     eax, [ebp+VirtualAddress]
  154. .text:00418F4B                 mov     [esi+3Ch], eax
  155. .text:00418F4E
  156. .text:00418F4E loc_418F4E:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+A9j
  157. .text:00418F4E                                         ; IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+113j
  158. .text:00418F4E                 mov     eax, [ebp+Length]
  159. .text:00418F4B                 mov     [esi+3Ch], eax  ; pIrp->UserBuffer  IRP_MJ_READ 時 DO_BUFFERED_IO模式下保存參數中的內存首地址
  160. .text:00418F4B                                         ; 看了下整個函數只有這裏 和IRP_MJ_READ提供的內存有關 猜測驅動在完成IRP後
  161. .text:00418F4B                                         ; 系統會尋找UserBuffer域然後 複製systembuffer裏的東西
  162. .text:00418F4E
  163. .text:00418F4E loc_418F4E:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+A9j
  164. .text:00418F4E                                         ; IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+113j
  165. .text:00418F4E                 mov     eax, [ebp+Length]
  166. .text:00418F51                 mov     [ebx+4], eax    ; IO_STACK_LOCATION.Write.Length
  167. .text:00418F51                 mov     [ebx+4], eax    ; IO_STACK_LOCATION.Write.Length
  168. .text:00418F54                 mov     eax, [ebp+StartingOffset]
  169. .text:00418F57                 mov     ecx, [eax]
  170. .text:00418F59                 mov     [ebx+0Ch], ecx  ; IO_STACK_LOCATION.Write.ByteOffset.u.LowPart
  171. .text:00418F5C                 mov     eax, [eax+4]
  172. .text:00418F5F                 mov     [ebx+10h], eax  ; IO_STACK_LOCATION.Write.ByteOffset.u.HighPart
  173. .text:00418F62
  174. .text:00418F62 loc_418F62:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+44j
  175. .text:00418F62                                         ; IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+4Dj ...
  176. .text:00418F62                 mov     eax, [ebp+IoStatusBlock]
  177. .text:00418F65                 mov     [esi+28h], eax  ; pIrp->UserIosb
  178. .text:00418F68                 mov     eax, esi
  179. .text:00418F6A
  180. .text:00418F6A loc_418F6A:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+138j
  181. .text:00418F6A                 call    __SEH_epilog
  182. .text:00418F6F                 retn    18h
  183. .text:00418F72 ; ---------------------------------------------------------------------------
  184. .text:00418F72
  185. .text:00418F72 loc_418F72:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+5Ej
  186. .text:00418F72                 test    al, 10h         ; DO_DIRECT_IO
  187. .text:00418F74                 jz      short loc_418F48
  188. .text:00418F76                 xor     edi, edi
  189. .text:00418F78                 push    edi             ; Irp
  190. .text:00418F79                 push    edi             ; ChargeQuota
  191. .text:00418F7A                 push    edi             ; SecondaryBuffer
  192. .text:00418F7B                 push    [ebp+Length]    ; Length
  193. .text:00418F7E                 push    [ebp+VirtualAddress] ; VirtualAddress
  194. .text:00418F81                 call    _IoAllocateMdl@20 ; 分配一個MDL
  195. .text:00418F86                 mov     [esi+4], eax    ; pIrp->MdlAddress
  196. .text:00418F89                 cmp     eax, edi
  197. .text:00418F8B                 jz      loc_418F0C
  198. .text:00418F91                 mov     [ebp+ms_exc.disabled], edi
  199. .text:00418F94                 xor     ecx, ecx
  200. .text:00418F96                 cmp     [ebp+MajorFunction], 3 ; IRP_MJ_READ
  201. .text:00418F9A                 setz    cl              ; 如果是IRP_MJ_READ cl置位
  202. .text:00418F9D                 push    ecx             ; Operation
  203. .text:00418F9E                 push    edi             ; AccessMode
  204. .text:00418F9F                 push    eax             ; MemoryDescriptorList
  205. .text:00418FA0                 call    _MmProbeAndLockPages@12 ; 鎖定MDL
  206. .text:00418FA5                 or      [ebp+ms_exc.disabled], 0FFFFFFFFh
  207. .text:00418FA9                 jmp     short loc_418F4E
  208. .text:00418FAB ; ---------------------------------------------------------------------------
  209. .text:00418FAB
  210. .text:00418FAB loc_418FAB:                             ; DATA XREF: .text:stru_401748o
  211. .text:00418FAB                 xor     eax, eax
  212. .text:00418FAD                 inc     eax
  213. .text:00418FAE                 retn
  214. .text:00418FAF ; ---------------------------------------------------------------------------
  215. .text:00418FAF
  216. .text:00418FAF loc_418FAF:                             ; DATA XREF: .text:stru_401748o
  217. .text:00418FAF                 mov     esp, [ebp+ms_exc.old_esp]
  218. .text:00418FB2                 mov     esi, [ebp+Irp]
  219. .text:00418FB5                 mov     eax, [esi+4]
  220. .text:00418FB8                 test    eax, eax
  221. .text:00418FBA                 jz      short loc_418FC2
  222. .text:00418FBC                 push    eax             ; Mdl
  223. .text:00418FBD                 call    _IoFreeMdl@4    ; IoFreeMdl(x)
  224. .text:00418FC2
  225. .text:00418FC2 loc_418FC2:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+124j
  226. .text:00418FC2                 push    esi             ; Irp
  227. .text:00418FC3                 call    _IoFreeIrp@4    ; IoFreeIrp(x)
  228. .text:00418FC8                 or      [ebp+ms_exc.disabled], 0FFFFFFFFh
  229. .text:00418FCC
  230. .text:00418FCC loc_418FCC:                             ; CODE XREF: IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+27j
  231. .text:00418FCC                                         ; IoBuildAsynchronousFsdRequest(x,x,x,x,x,x)+7Cj
  232. .text:00418FCC                 xor     eax, eax
  233. .text:00418FCE                 jmp     short loc_418F6A
  234. .text:00418FCE _IoBuildAsynchronousFsdRequest@24 endp
  235. IoBuildAsynchronousFsdRequest內部不算很複雜 通過調用IoAllocateIrp來分配IRP
  236. 對於IRP_MJ_SHUTDOWN,IRP_MJ_PNP,IRP_MJ_POWER,IRP_MJ_FLUSH_BUFFERS 這樣的不對設備讀寫的請求
  237. MajorFunction送入IO_STACK_LOCATION後就直接返回了。。。
  238. 而對於IRP_MJ_READ或者IRP_MJ_WRITE還要對緩衝區進行處理
  239. 對於緩衝區讀寫的設備 MajorFunction爲IRP_MJ_WRITE時IoBuildAsynchronousFsdRequest調用ExAllocatePoolWithTag分配內存 填充到
  240. pIrp->AssociatedIrp.SystemBuffer域中  同時複製要寫入的數據到SystemBuffer中去(看到這裏  估計就明白IO管理器是怎麼管理SystemBuffer
  241. 的) MajorFunction爲IRP_MJ_READ時 只分配好內存,最後IO_STACK_LOCATION域填充好 返回
  242. 對於直接讀寫的設備 爲參數中提供的內存創建一個MDL  MmProbeAndLockPages函數校驗那個數據緩衝區是否有效,是否可以按適當模式訪問。
  243. 如果我們向設備寫數據,我們必須能讀緩衝區。如果我們從設備讀數據,我們必須能寫緩衝區。
  244. 分析到這裏其實已經差不多了  IoBuildAsynchronousFsdRequest和IoBuildSynchronousFsdRequest之所以只能分配少數幾種IRP 只是因爲內部
  245. 只對這幾種IRP進行了 封裝(廢話啊)至於調用IoAllocateIrp後應該填充的域顯然 應該和IoBuildAsynchronousFsdRequest中做的差不多(當然根據
  246. 具體的MajorFunction具體填充) 比如:IoStackLocation,UserIosb
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章