IofCallDriver函数汇编解析

0: kd> uf nt!IofCallDriver

Flow analysis was incomplete, some code may be missing

nt!IofCallDriver:

fffff800`03ed1c10 4883ec28        sub     rsp,28h

fffff800`03ed1c14 488b05fda62200  mov     rax,qword ptr [nt!pIofCallDriver (fffff800`040fc318)]

fffff800`03ed1c1b 4885c0          test    rax,rax

fffff800`03ed1c1e 0f85b8050700    jne     nt! ?? ::FNODOBFM::`string'+0x3f3d0 (fffff800`03f421dc)

栈指针移动5字节位置

将nt!pIofCallDriver地址赋值给RAX

判断nt!pIofCallDriver地址是否是0

如果不相等(判断的是ZF标志位是否为1,如果test结果是0,那么ZF为1),跳转到这个地址,(test是and操作,所以只要不是0就跳)

正常是要跳转的,也就是说执行到下面这些代码肯定出问题了。

nt!IofCallDriver+0x14:

fffff800`03ed1c24 fe4a43          dec     byte ptr [rdx+43h]

fffff800`03ed1c27 384243          cmp     byte ptr [rdx+43h],al

fffff800`03ed1c2a 0f8eb8050700    jle     nt! ?? ::FNODOBFM::`string'+0x3f3dc (fffff800`03f421e8)

RDX是IRP的栈地址指针,rdx+43h是保存当IRP前的栈地址指针,所以减一后jle必定跳转,导致蓝屏

所以如果nt!pIofCallDriver地址是0,肯定蓝屏

执行到这里是有问题的,nt!pIofCallDriver地址是0

这个地址的值 堆栈状态信息-当前位置 irp->CurrentLocation-1得到下一个irp堆栈信息(1字节,8位 0000 0000)减少1

判断这个值和RDX的低8位的值的大小(80000000)

如果小于或等于,就跳转(判断IRP->当前位置 是不是当前位置?这里不能跳,跳了就蓝屏)(没有下一个IRP栈信息)

nt!IofCallDriver+0x20:

fffff800`03ed1c30 488b82b8000000  mov     rax,qword ptr [rdx+0B8h]

fffff800`03ed1c37 4883e848        sub     rax,48h

fffff800`03ed1c3b 488982b8000000  mov     qword ptr [rdx+0B8h],rax

fffff800`03ed1c42 440fb608        movzx   r9d,byte ptr [rax]

fffff800`03ed1c46 48894828        mov     qword ptr [rax+28h],rcx

fffff800`03ed1c4a 4180f916        cmp     r9b,16h

fffff800`03ed1c4e 0f84a4050700    je      nt! ?? ::FNODOBFM::`string'+0x3f3ec (fffff800`03f421f8)

B8是什么?将这个地址赋值给RAX(应该是IRP地址偏移184字节处 位于tail)

减去48h

然后再将结果赋值回这个地址

无符号将RAX地址处的第一个字节扩展到32位,然后赋值到r9的低32位

将RCX的值移动到RAX+28h字节处

判断r9的值和16h,如果r9的值是16h就跳转

nt!IofCallDriver+0x44:

fffff800`03ed1c54 4c8b4108        mov     r8,qword ptr [rcx+8]

fffff800`03ed1c58 410fb6c1        movzx   eax,r9b

fffff800`03ed1c5c 4883c428        add     rsp,28h

fffff800`03ed1c60 49ff64c070      jmp     qword ptr [r8+rax*8+70h]

将该驱动对象地址赋值给r8

无符号的将r9的低8位扩展到32位,然后赋值给EAX

恢复栈顶指针到原来的位置

跳转到设备对象的设备所对象结构 DISPATCHER_HEADER

nt! ?? ::FNODOBFM::`string'+0x3f3d0:

fffff800`03f421dc 4c8b442428      mov     r8,qword ptr [rsp+28h]

fffff800`03f421e1 4883c428        add     rsp,28h

fffff800`03f421e5 48ffe0          jmp     rax

正常情况下如果IofCallDriver正确就会在第一个判断时跳转到这里

将栈顶5字节处的值赋值给R8,然后栈地址加40字节

最后跳转到nt!pIofCallDriver执行,本函数是nt!IofCallDriver

nt! ?? ::FNODOBFM::`string'+0x3f3dc:

fffff800`03f421e8 4533c9          xor     r9d,r9d

fffff800`03f421eb 4533c0          xor     r8d,r8d

fffff800`03f421ee 418d4935        lea     ecx,[r9+35h]

fffff800`03f421f2 e8e93cf8ff      call    nt!KiBugCheck3 (fffff800`03ec5ee0)

fffff800`03f421f7 cc              int     3

如果IofCallDriver地址为0,则跳转到这里,蓝屏了。

首先清空r8和r9的低32位为0

然后获得r9+53字节处的值到ECX(这里保存的应该是用户显示的错误信息吧)

调用nt!KiBugCheck3函数,错误原因:没有更多的IRP堆栈位置,最底层驱动对象是没有IofCallDriver的。

nt! ?? ::FNODOBFM::`string'+0x3f3ec:

fffff800`03f421f8 440fb64001      movzx   r8d,byte ptr [rax+1]

fffff800`03f421fd 4180f802        cmp     r8b,2

fffff800`03f42201 7417            je      nt! ?? ::FNODOBFM::`string'+0x3f40e (fffff800`03f4221a)

这个函数都是跳到执行nt!IopPoHandleIrp函数代码段处。[rax+1]大概是执行完nt!pIofCallDriver的结果

然后根据返回值进行处理

nt! ?? ::FNODOBFM::`string'+0x3f3f7:

fffff800`03f42203 4180f803        cmp     r8b,3

fffff800`03f42207 7411            je      nt! ?? ::FNODOBFM::`string'+0x3f40e (fffff800`03f4221a)

这个函数都是跳到执行nt!IopPoHandleIrp函数代码段处

nt! ?? ::FNODOBFM::`string'+0x3f3fd:

fffff800`03f42209 4c8b4108        mov     r8,qword ptr [rcx+8]

fffff800`03f4220d 410fb6c1        movzx   eax,r9b

fffff800`03f42211 4883c428        add     rsp,28h

fffff800`03f42215 49ff64c070      jmp     qword ptr [r8+rax*8+70h]

如果返回值不是2或者3,就执行这里

设备对象调度对象 DISPATCHER_HEADER

首先获得驱动对象指针,赋值给R8

将R9低8位扩展到32位,赋值到EAX

栈地址加40字节

跳转DISPATCHER_HEADER

nt! ?? ::FNODOBFM::`string'+0x3f40e:

fffff800`03f4221a 488bca          mov     rcx,rdx

fffff800`03f4221d 4883c428        add     rsp,28h

fffff800`03f42221 e9aa520800      jmp     nt!IopPoHandleIrp (fffff800`03fc74d0)

这部分是用来执行nt!IopPoHandleIrp函数的了

将RDX赋值给RCX,RDX是IRP指针

栈地址加40字节

跳转执行nt!IopPoHandleIrp

nt!IopPoHandleIrp:

fffff800`03fc74d0 fff3            push    rbx

fffff800`03fc74d2 4883ec20        sub     rsp,20h

fffff800`03fc74d6 488d542438      lea     rdx,[rsp+38h]

fffff800`03fc74db 488bd9          mov     rbx,rcx

fffff800`03fc74de e8ddfeffff      call    nt!PoHandleIrp (fffff800`03fc73c0)

fffff800`03fc74e3 84c0            test    al,al

fffff800`03fc74e5 751d            jne     nt!IopPoHandleIrp+0x34 (fffff800`03fc7504)

将RBX压栈

栈顶减少32字节

获得栈顶+56字节的内容到RDX

将RCX赋值给RDX

跳转到PoHandleIrp

判断返回值是否是0,如果不是0,短跳

nt!IopPoHandleIrp+0x17:

fffff800`03fc74e7 488b83b8000000  mov     rax,qword ptr [rbx+0B8h]

fffff800`03fc74ee 488bd3          mov     rdx,rbx

fffff800`03fc74f1 488b4828        mov     rcx,qword ptr [rax+28h]

fffff800`03fc74f5 440fb600        movzx   r8d,byte ptr [rax]

fffff800`03fc74f9 4c8b4908        mov     r9,qword ptr [rcx+8]

fffff800`03fc74fd 43ff54c170      call    qword ptr [r9+r8*8+70h]

fffff800`03fc7502 eb04            jmp     nt!IopPoHandleIrp+0x38 (fffff800`03fc7508)

否则如果返回值是0,RBX不知道是什么参数,反正是赋值给RAX,这里假定是IRP地址?

RBX=RCX=RDX

[rax+28h] 可能是设备对象的Timer?

...

nt!IopPoHandleIrp+0x34:

fffff800`03fc7504 8b442438        mov     eax,dword ptr [rsp+38h]

将栈中的结果赋值到RAX返回值中

nt!IopPoHandleIrp+0x38:

fffff800`03fc7508 4883c420        add     rsp,20h

fffff800`03fc750c 5b              pop     rbx

fffff800`03fc750d c3              ret

恢复栈指针

RBX出栈

返回函数

看来IofCallDriver并不是函数的实现,而是调用pIofCallDriver执行,并做一些错误处理。

kd> uf nt!pIofCallDriver

Flow analysis was incomplete, some code may be missing

nt!pIofCallDriver:

fffff800`04105318 0000            add     byte ptr [rax],al

fffff800`0410531a 0000            add     byte ptr [rax],al

fffff800`0410531c 0000            add     byte ptr [rax],al

fffff800`0410531e 0000            add     byte ptr [rax],al

fffff800`04105320 001e            add     byte ptr [rsi],bl

fffff800`04105322 0000            add     byte ptr [rax],al

fffff800`04105324 0000            add     byte ptr [rax],al

fffff800`04105326 0000            add     byte ptr [rax],al

fffff800`04105328 8047f130        add     byte ptr [rdi-0Fh],30h

fffff800`0410532c 80faff          cmp     dl,0FFh

fffff800`0410532f ff00            inc     dword ptr [rax]

fffff800`04105331 d9f0            f2xm1

fffff800`04105333 3080faffff08    xor     byte ptr [rax+8FFFFFAh],al

fffff800`04105339 420040fc        add     byte ptr [rax-4],al

fffff800`0410533d f6ff            idiv    bh

fffff800`0410533f ff00            inc     dword ptr [rax]

fffff800`04105341 0001            add     byte ptr [rcx],al

fffff800`04105343 0000            add     byte ptr [rax],al

fffff800`04105345 f9              stc

这个明显是错的。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容