IoAttachDeviceToDeviceStack将Source Device附加到Target Device上。
 
打开windbg
kd> u IoAttachDeviceToDeviceStack l 10
nt!IoAttachDeviceToDeviceStack:
804f1aac 8bff mov edi,edi
804f1aae 55 push ebp
804f1aaf 8bec mov ebp,esp
804f1ab1 6a00 push 0
804f1ab3 ff750c push dword ptr [ebp+0Ch]
804f1ab6 ff7508 push dword ptr [ebp+8]
804f1ab9 e878f6ffff call nt!IopAttachDeviceToDeviceStackSafe (804f1136)
804f1abe 5d pop ebp
804f1abf c20800 ret 8

在其中调用了IopAttachDeviceToDeviceStackSafe。我们知道IoAttachDeviceToDeviceStackSafe第三个参数用来返回真实附加的设备,而函数的返回值是一个NTSTATUS,而IoAttachDeviceToDeviceStack直接返回该设备,所以有了804f1ab1 6a00 push 0。
 
kd> u nt!IopAttachDeviceToDeviceStackSafe l 40
nt!IopAttachDeviceToDeviceStackSafe:
804f1136 8bff mov edi,edi
804f1138 55 push ebp
804f1139 8bec mov ebp,esp
804f113b 53 push ebx
804f113c 56 push esi
804f113d 57 push edi
804f113e 8b7d08 mov edi,dword ptr [ebp+8]
804f1141 8b9fb0000000 mov ebx,dword ptr [edi+0B0h]
804f1147 ff1514874d80 call dword ptr [nt!_imp__KeRaiseIrqlToDpcLevel (804d8714)]
804f114d 803d1cd3548000 cmp byte ptr [nt!IopVerifierOn (8054d31c)],0
804f1154 88450b mov byte ptr [ebp+0Bh],al
804f1157 7409 je nt!IopAttachDeviceToDeviceStackSafe+0x2c (804f1162)
804f1159 ff750c push dword ptr [ebp+0Ch]
804f115c 57 push edi
804f115d e812d81500 call nt!IovAttachDeviceToDeviceStack (8064e974)
804f1162 ff750c push dword ptr [ebp+0Ch]
804f1165 e822e4ffff call nt!IoGetAttachedDevice (804ef58c)
804f116a 8bf0 mov esi,eax
804f116c f6461c80 test byte ptr [esi+1Ch],80h
804f1170 754d jne nt!IopAttachDeviceToDeviceStackSafe+0x89 (804f11bf)
804f1172 8b86b0000000 mov eax,dword ptr [esi+0B0h]
804f1178 f640100f test byte ptr [eax+10h],0Fh
804f117c 7541 jne nt!IopAttachDeviceToDeviceStackSafe+0x89 (804f11bf)
804f117e 8a4630 mov al,byte ptr [esi+30h]
804f1181 66ff86ae000000 inc word ptr [esi+0AEh]
804f1188 fec0 inc al
804f118a 897e10 mov dword ptr [esi+10h],edi
804f118d 884730 mov byte ptr [edi+30h],al
804f1190 8b465c mov eax,dword ptr [esi+5Ch]
804f1193 89475c mov dword ptr [edi+5Ch],eax
804f1196 668b86ac000000 mov ax,word ptr [esi+0ACh]
804f119d 668987ac000000 mov word ptr [edi+0ACh],ax
804f11a4 8b86b0000000 mov eax,dword ptr [esi+0B0h]
804f11aa f6401010 test byte ptr [eax+10h],10h
804f11ae 740a je nt!IopAttachDeviceToDeviceStackSafe+0x84 (804f11ba)
804f11b0 8bbfb0000000 mov edi,dword ptr [edi+0B0h]
804f11b6 834f1010 or dword ptr [edi+10h],10h
804f11ba 897318 mov dword ptr [ebx+18h],esi
804f11bd eb02 jmp nt!IopAttachDeviceToDeviceStackSafe+0x8b (804f11c1)
804f11bf 33f6 xor esi,esi
804f11c1 8b4510 mov eax,dword ptr [ebp+10h]
804f11c4 85c0 test eax,eax
804f11c6 7402 je nt!IopAttachDeviceToDeviceStackSafe+0x94 (804f11ca)
804f11c8 8930 mov dword ptr [eax],esi
804f11ca 8a4d0b mov cl,byte ptr [ebp+0Bh]
804f11cd ff151c874d80 call dword ptr [nt!_imp_KfLowerIrql (804d871c)]
804f11d3 5f pop edi
804f11d4 8bc6 mov eax,esi
804f11d6 5e pop esi
804f11d7 5b pop ebx
804f11d8 5d pop ebp
804f11d9 c20c00 ret 0Ch
这个函数中,先把irql提升到dpc,在看804f1165 e822e4ffff call nt!IoGetAttachedDevice (804ef58c)
kd> u nt!IoGetAttachedDevice l 20
nt!IoGetAttachedDevice:
804ef58c 8bff mov edi,edi
804ef58e 55 push ebp
804ef58f 8bec mov ebp,esp
804ef591 8b4508 mov eax,dword ptr [ebp+8]
804ef594 eb02 jmp nt!IoGetAttachedDevice+0xc (804ef598)
804ef596 8bc1 mov eax,ecx
804ef598 8b4810 mov ecx,dword ptr [eax+10h]
804ef59b 85c9 test ecx,ecx
804ef59d 75f7 jne nt!IoGetAttachedDevice+0xa (804ef596)
804ef59f 5d pop ebp
804ef5a0 c20400 ret 4

mov ecx,dword ptr [eax+10h],干了什么?
kd> dt _DEVICE_OBJECT
ntdll!_DEVICE_OBJECT
   +0x000 Type : Int2B
   +0x002 Size : Uint2B
   +0x004 ReferenceCount : Int4B
   +0x008 DriverObject : Ptr32 _DRIVER_OBJECT
   +0x00c NextDevice : Ptr32 _DEVICE_OBJECT
   +0x010 AttachedDevice : Ptr32 _DEVICE_OBJECT
   +0x014 CurrentIrp : Ptr32 _IRP
   +0x018 Timer : Ptr32 _IO_TIMER
   +0x01c Flags : Uint4B
   +0x020 Characteristics : Uint4B
   +0x024 Vpb : Ptr32 _VPB
   +0x028 DeviceExtension : Ptr32 Void
   +0x02c DeviceType : Uint4B
   +0x030 StackSize : Char
   +0x034 Queue : __unnamed
   +0x05c AlignmentRequirement : Uint4B
   +0x060 DeviceQueue : _KDEVICE_QUEUE
   +0x074 Dpc : _KDPC
   +0x094 ActiveThreadCount : Uint4B
   +0x098 SecurityDescriptor : Ptr32 Void
   +0x09c DeviceLock : _KEVENT
   +0x0ac SectorSize : Uint2B
   +0x0ae Spare1 : Uint2B
   +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
   +0x0b4 Reserved : Ptr32 Void

我们看到+10的位置是AttachedDevice,AttachedDevice即该设备上层的设备。所以IoGetAttachedDevice就是不断循环,直到找到最顶端的设备。之后将我们得到的最顶端设备的AttachedDevice指向要附加的SourceDevice。然后对SourceDevice的一些区域做一些处理,如StackSize = 顶端设备的StackSize+1,拷贝一些区域。之后返回最顶端的设备。

关于IoAttachDeviceToDeviceStack的更多相关文章

  1. WDM驱动加载方式理解

    当PC得知有新设备插入时,总线驱动会创建相应的物理驱动PDO,然后提示有新设备插入,这时候调用相应Driver的AddDevice方法创建功能驱动FDO 下面是一个典型的AddDevice方法 #pr ...

  2. [转]C/C++ 实现文件透明加解密

    今日遇见一个开超市的朋友,真没想到在高校开超市一个月可以达到月净利润50K,相比起我们程序员的工资,真是不可同日而语,这个世道啊,真是做程序员不如经商开超市, 我们高科技的从业者,真是造原子弹不如卖茶 ...

  3. Windows内核 WDM驱动程序的基本结构和实例

    WDM驱动的基本结构: WDM驱动模型是建立在NT式驱动程序模型基础之上的.对于WDM驱动程序来说,一般都是基于分层的,即完成一个设备的操作,至少要由两个驱动设备共同完成. 1)物理设备对象和功能设备 ...

  4. [windows驱动]标准驱动例程

    [注]routine:例行程序. 1.标准驱动例程简介: 每一个内核态驱动程序都是由一系列系统定义的,标准的驱动例程组成.内核态驱动在这些标准例程中通过调用系统提供的驱动支持函数处理I/O请求包.为了 ...

  5. 和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧。因为,很多PCI的例子都是对S5933,就连微软出版的《Programming the Microsoft Windows Driver Model》都提供了一个完整的S5933的例子。 在这篇有关DDK的开发论文里。

    和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧.因为,很多PCI的例子都是对S5933,就连微软出版的<Programming the Microsoft Wi ...

  6. 键盘过滤第一个例子ctrl2cap(4.1~4.4)汇总,测试

    键盘过滤第一个例子ctrl2cap(4.1~4.4)汇总,测试 完整源代码 /// /// @file ctrl2cap.c /// @author wowocock /// @date 2009-1 ...

  7. 《Windows驱动开发技术详解》之分层驱动程序

    分层驱动程序概念 分层的目的是将功能复杂的驱动程序分解成多个简单的驱动程序.一般来说,他们是指两个或两个 以上的驱动程序,它们分别创建设备对象,并且形成一个由高到低的设备对象栈.IRP请求一般会被传送 ...

  8. 用DDK开发的9054驱动 .

    和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧.因为,很多PCI的例子都是对S5933,就连微软出版的<Programming the Microsoft Wi ...

  9. USB转串口驱动代码分析

    1.USB插入时,创建设备 [plain] view plaincopy DriverObject->DriverExtension->AddDevice = USB2COM_PnPAdd ...

随机推荐

  1. 用DIV+Css+Jquery 实现的旧版微信飞机大战。

    用jquery 实现的旧版微信飞机大战. 以前一直都是做后台和业务逻辑,前端很少去做, 现在个小游戏. 方向键控制方向,Ctrl 键 放炸弹(当然你的有炸弹,哈哈)! 主要都是用div+Css实现的, ...

  2. Power(int base, int exponent) 函数实现

    这个是个高效的算法,时间复杂度为 O(logn) 原理: a的n次方: #include<iostream> #include<cmath> using namespace s ...

  3. Ubuntu 12.04 搭建Android开发环境

    Ubuntu 12.04 搭建Android开发环境 2013/7/29 Linux环境下搭建Android开发环境 大部分开发人员可能都在Windows下做开发,可能是感觉在Windows下比较方便 ...

  4. redis 源代码分析(一) 内存管理

    一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...

  5. IT English Collection(16) of Message

    1 前言 本文介绍了关于Objective-C中的消息机制,详情如下. 转载请注明出处:http://blog.csdn.net/developer_zhang 2 详述 2.1 原文 A messa ...

  6. Android Studio 初体验

    Google在I/O */

  7. 简易浏览器App webview

    使用 public class MainActivity extends Activity {     @Override     protected void onCreate(Bundle sav ...

  8. 重学《C#高级编程》(序)

    小生码农一枚,以前只是看别人写博客,从来没有想过要自己写博文,突然之间“脑抽”想自己也写点什么,遂在博客园开通这个博客. 简单介绍下自己吧,本人90后,父母对我没有大的想法,只是希望我平安成长,多学习 ...

  9. C#,.net获取字符串中指定字符串的个数、所在位置与替换字符串

    方法一: public static int indexOf (字符串/字符,int从第几位开始,int共查几位) string tests = "1absjjkcbfka2rsbcfak2 ...

  10. ActiveReport 9手把手搭建环境及实战

    本文借鉴葡萄城空间产品,纯属分享,无任何营利目的 下载ActiveReports 9 专业版 打开下面的网站,点击立即下载,请您填写真实电子邮件地址,以获取ActiveReports产品试用版---系 ...