zoukankan      html  css  js  c++  java
  • 【旧文章搬运】调试没有符号的驱动时如何断在入口点处

    原文发表于百度空间,2009-04-17
    ==========================================================================

    关于调试没有符号的驱动时如何断在入口点处这个问题,先说一个我听来的很挫的方法:用C32ASM修改DriverEntry处为0xCC,就是int 3,修正校验和后加载,执行到DriverEntry时产生int 3异常自然就会中断在调试器了,这时再把原来的指令改回去继续跑就行了.改来改去的,确实比较挫~~.
    那么怎么做比较好一点呢?
    我们都知道有符号时直接bu drivername!DriverEntry就可以了,加载时就会停在入口点.但是没有符号时,调试器不知道DriverEntry到底指向哪个位置,但是谁知道呢?谁调用谁知道啊~~没错,就是IopLoadDriver()啦~~(关于该函数的具体实现,请自行参考WRK).
    下面我就直接在IopLoadDriver函数中找调用DriverEntry的地方.
    找啊找啊,终于找到了,在我的Xp sp2上如下:

    lkd> 
    nt!IopLoadDriver+0x65a:
    805a9787 83e103          and     ecx,3
    805a978a f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
    805a978c 8b7d80          mov     edi,dword ptr [ebp-80h]
    805a978f ffb570ffffff    push    dword ptr [ebp-90h] //指向RegistryPath
    805a9795 57              push    edi                  //edi指向DriverObject
    805a9796 ff572c          call    dword ptr [edi+2Ch] //edi+2C,指向DriverObject->DriverInit,即入口点DriverEntry
    805a9799 3bc3            cmp     eax,ebx
    805a979b 8b8d68ffffff    mov     ecx,dword ptr [ebp-98h] 

    顺便贴个DRIVER_OBJECT的结构,这样两个放一起看起来比较容易理解

    lkd> dt _DRIVER_OBJECT 8a884e30
    nt!_DRIVER_OBJECT
        +0x000 Type              : 4
        +0x002 Size              : 168
        +0x004 DeviceObject      : 0x898ef450 _DEVICE_OBJECT
        +0x008 Flags             : 0x92
        +0x00c DriverStart       : 0xf7b52000 
        +0x010 DriverSize        : 0x8c480
        +0x014 DriverSection     : 0x8a960ae8 
        +0x018 DriverExtension   : 0x8a884ed8 _DRIVER_EXTENSION
        +0x01c DriverName        : _UNICODE_STRING "FileSystemNtfs"
        +0x024 HardwareDatabase : 0x80696810 _UNICODE_STRING "REGISTRYMACHINEHARDWAREDESCRIPTIONSYSTEM"
        +0x028 FastIoDispatch    : 0xf7b71820 _FAST_IO_DISPATCH
        +0x02c DriverInit        : 0xf7bd7204     long   +fffffffff7bd7204  //这就是入口点了,代码中的edi+2C处
        +0x030 DriverStartIo     : (null) 
        +0x034 DriverUnload      : (null) 
        +0x038 MajorFunction     : [28] 0xf7b77e37     long   +fffffffff7b77e37

    这个call特征很明显的.就是:

    push reg
    call dword ptr [reg+2Ch]
    不同的内核版本这里使用的寄存器可能是不一样的,找到后把这个偏移记下来
    只要我们把断点下在这个call之前,比如我直接下bp nt!IopLoadDriver+0x65a
    然后单步几下到805a9796,这个call dword ptr [reg+2Ch]单步进去,就是DriverEntry了,很简单!
    如果你跟我一样使用WinXP Sp2,那么直接下断点bp nt!IopLoadDriver+0x65a就可以了
    Vista系统下直接下断点 bp nt!IopLoadDriver+0x801
    我提供的偏移可能不适用于你的系统,请自行查找适合你自己的偏移量,只需查找一次,以后就可以随便用了.
    此法在Win2000/WinXP/Win2003/WinVista上均适用,对SoftIce,Syser当然也是可以用的.
    不过SoftIce好像有专用的命令,而Syser有没有符号都可以自动断在入口点处,所以使用Windbg但仍不会这个方法的可以记录一下.

  • 相关阅读:
    主流编程语言
    计算机语言
    IT(Information technology)
    设计模式-学习
    Java 执行顺序
    学习大纲
    Springboot注解整理 二《自定义注解》
    IntelliJ IDE 基础经验备案三
    IntelliJ IDE 基础经验备案二
    Mybatis使用经验归档
  • 原文地址:https://www.cnblogs.com/achillis/p/10181595.html
Copyright © 2011-2022 走看看