使用WinDBG进行双机内核调试

来源:互联网 发布:单片机编程器的作用 编辑:程序博客网 时间:2024/05/22 12:10

由于我没有物理的两台机器,因此我这里使用虚拟机来进行讲解(虚拟机真是个好东西)。我将先讲述如何设置,然后以一个实例来讲述如何进行内核驱动的调试。

Target环境:
Virtual PC 2004、Win2000 sp 4 en

Host环境:
WinXP sp2, WinDBG 6.6.07.5, SUDT SerialNull 1.6 试用版

一) 设置篇
SUDT SerialNull是一个虚拟串口软件,用于模拟RS232串口的虚拟连接,SerialNull可以在不占用真实串口的情况下,创建任意数量并互为连接的纯虚拟串口对。
我们将用这个软件虚拟一个串口对出来供HostTarget使用。

如图:

 

我们虚拟了一个串口对,COM2-COM3,这对串口是联通的。

在VirtualPC中设置:

进行入虚拟机系统(Win2k),打开boot.ini文件,添加一行,如下:
multi(0)disk(0)rdisk(0)partition(1)\WINNT=”Microsoft Windows 2000 Professional”/fastdetect /debug /debugport=com1 /baudrate=115200
意思是以Debug模式起动系统,调试端口为COM1,波特率为115200

重新以Debug模式启动系统:

在Host端,启动WinDBG,选File->KernelDebug…,COM页,在BaudRate输入115200,Port输入我们建立的虚拟串口对的COM2口,钩上Reconnected:

点击“OK”之后在COMMAND窗口出现:
Opened \\.\com2
Waiting to reconnect…
此时按Ctrl+Break,会出现如下画面:

调试器显示:“Connected to Windows 2000 2195 x86 compatible target, ptr64 FALSE”,此时代表连接目标成功,处于中断状态,我们
可以在File->Symbol File Path…中设置符号路径,我习惯于使用Symbol Server,因此我在这里设置了:

SRV*f:\symbols*http://msdl.microsoft.com/download/symbols

 到此时我们的双机调试环境搭建完成。此环境已经可以工作了。

 二) 实例讲解

接着上面的步骤,我将以一个软件做为实例进行讲解,做为练习目标的软件是国产软件,在此隐去软件名称,我使用A软件代替。

在command窗口输入:G,此命令跟SoftICE中的G一样,让程序继续运行。

将A软件安装在虚拟机中,安装完成后,运行A软件,进入注册界面,此时我们在WinDBG中再次按Ctrl+Break,让Target中断下来,A软件的注册算法在驱动程序snbus.sys中DeviceControl例程中(为什么在snbus中的DeviceControl例程中,请自行跟踪应用程序并查看DDK的相关文档就知道了,这里的重点不是Crack软件,而是讲内核驱动的调试),在Command窗口中输入:
!drvobj snbus 2

!drvobj命令类似于SoftICE中的driver命令,用于显示驱动对象的相关信息,具体的用法请参看WinDBG的帮助文档,当我们输入!drvobj snbus 2时,我们将得到这个驱动的Dispatch routines信息:

kd> !drvobj snbus 2

  1. Driver     object (81454a70) is for:
  1.  \Driver\SnBus    
  2. Dispatch     routines:
  3. [00]     IRP_MJ_CREATE                          f7353aa0 +0xf7353aa0
  4. [01]     IRP_MJ_CREATE_NAMED_PIPE               80423f0c nt!IopInvalidDeviceRequest
  5. [02]     IRP_MJ_CLOSE                           f7353aa0 +0xf7353aa0
  6. [03]     IRP_MJ_READ                            80423f0c nt!IopInvalidDeviceRequest
  7. [04]     IRP_MJ_WRITE                           80423f0c nt!IopInvalidDeviceRequest
  8. [05]     IRP_MJ_QUERY_INFORMATION               80423f0c nt!IopInvalidDeviceRequest
  9. [06]     IRP_MJ_SET_INFORMATION                 80423f0c nt!IopInvalidDeviceRequest
  10. [07]     IRP_MJ_QUERY_EA                        80423f0c nt!IopInvalidDeviceRequest
  11. [08]     IRP_MJ_SET_EA                          80423f0c nt!IopInvalidDeviceRequest
  12. [09]     IRP_MJ_FLUSH_BUFFERS                   80423f0c nt!IopInvalidDeviceRequest
  13. [0a]     IRP_MJ_QUERY_VOLUME_INFORMATION        80423f0c nt!IopInvalidDeviceRequest
  14. [0b]     IRP_MJ_SET_VOLUME_INFORMATION          80423f0c nt!IopInvalidDeviceRequest
  15. [0c]     IRP_MJ_DIRECTORY_CONTROL               80423f0c nt!IopInvalidDeviceRequest
  16. [0d]     IRP_MJ_FILE_SYSTEM_CONTROL             80423f0c nt!IopInvalidDeviceRequest
  17. [0e]     IRP_MJ_DEVICE_CONTROL                  f7353b1a +0xf7353b1a
  18. [0f]     IRP_MJ_INTERNAL_DEVICE_CONTROL         80423f0c nt!IopInvalidDeviceRequest
  19. [10]     IRP_MJ_SHUTDOWN                        80423f0c nt!IopInvalidDeviceRequest
  20. [11]     IRP_MJ_LOCK_CONTROL                    80423f0c nt!IopInvalidDeviceRequest
  21. [12]     IRP_MJ_CLEANUP                         80423f0c nt!IopInvalidDeviceRequest
  22. [13]     IRP_MJ_CREATE_MAILSLOT                 80423f0c nt!IopInvalidDeviceRequest
  23. [14]     IRP_MJ_QUERY_SECURITY                  80423f0c nt!IopInvalidDeviceRequest
  24. [15]     IRP_MJ_SET_SECURITY                    80423f0c nt!IopInvalidDeviceRequest
  25. [16]     IRP_MJ_POWER                           f735065e +0xf735065e
  26. [17]     IRP_MJ_SYSTEM_CONTROL                  f7354db8 +0xf7354db8
  27. [18]     IRP_MJ_DEVICE_CHANGE                   80423f0c nt!IopInvalidDeviceRequest
  28. [19]     IRP_MJ_QUERY_QUOTA                     80423f0c nt!IopInvalidDeviceRequest
  29. [1a]     IRP_MJ_SET_QUOTA                       80423f0c nt!IopInvalidDeviceRequest
  30. [1b]     IRP_MJ_PNP                             f7354590 +0xf7354590

我们找到了

[0e]IRP_MJ_DEVICE_CONTROL             f7353b1a +0xf7353b1a
知道DeviceControl例程的入口在0xf7353b1a处,于是我们在0xf7353b1a处设下断点,在Command窗口中输入:

bp 0xf7353b1a

bp指令相当于softice的bpx,后面跟“地址”即可在指定地址设下断点,具体用法请参加WinDBG的帮助。

输入G,让Target继续跑起来,此时我们在注册窗口中输入我们的注册用户名与假码:
xIkUg
aaaaaaaa-bbbbbbbb-cccccccc-dddddddd

点“确定”,此时WinDBG把Target中断了下来,中断之处正是我们刚才设置的DeviceControl的例程处0xf7353b1a:

  1. f7353b1a     8bff                mov         edi,edi                                ; 这里断下
  1. f7353b1c     55                  push    ebp
  2. f7353b1d     8bec                mov     ebp,esp
  3. f7353b1f     51                  push    ecx
  4. f7353b20     8b4508              mov     eax,dword ptr     [ebp+8]                  ; [ebp+8] = DeviceObject
  5. f7353b23     56                  push    esi
  6. f7353b24     57                  push    edi
  7. f7353b25     8b7828              mov     edi,dword ptr     [eax+28h]                ; [eax+28h] = DEVICE_OBJECT.DeviceExtension
  8. f7353b28     807f0400            cmp     byte ptr     [edi+4],0                     ; ds:0023:8145494c=01
  9. f7353b2c     897dfc              mov     dword ptr [ebp-4],edi                  ; 保存设备扩展
  10. f7353b2f     751a                jne         f7353b4b                               ; 8145494c如果为真则跳,否则执行下面的代码并退出这个 routine
  11. f7353b31     8b4d0c              mov     ecx,dword ptr     [ebp+0Ch]                ; Irp
  12. f7353b34     be100000c0      mov         esi,0C0000010h                         ; 0C0000010h = STATUS_INVALID_DEVICE_REQUEST
  13. f7353b39     32d2                xor     dl,dl
  14. f7353b3b     897118              mov     dword ptr     [ecx+18h],esi                ; [ecx+18h] = IoStatus
  15. f7353b3e     ff15182635f7    call    dword ptr ds:[0F7352618h]              ; [0F7352618h] = IofCompleteRequest
  16. f7353b44     8bc6                mov         eax,esi                                ; 返回状态
  17. f7353b46     e977020000      jmp         f7353dc2                               ; Exit

在这里你可能看到这些代码后的注解可能会问为什么是这样的?不急,让我们看看MSND,DeviceControl的函数原型如下:

  1. NTSTATUS     XxxDispatchDeviceControl(
  1.         IN PDEVICE_OBJECT DeviceObject,
  2.         IN PIRP Irp);

于是我们知道f7353b20 的[ebp+8] 指向DeviceObject

在Command窗口输入dt _DEVICE_OBJECT,我们得到如下信息:

kd> dt _DEVICE_OBJECT

  1.        +0x000     Type                 : Int2B
  1.        +0x002     Size                 : Uint2B
  2.        +0x004 ReferenceCount   : Int4B
  3.        +0x008 DriverObject     : Ptr32 _DRIVER_OBJECT
  4.        +0x00c NextDevice       : Ptr32     _DEVICE_OBJECT
  5.        +0x010 AttachedDevice   : Ptr32 _DEVICE_OBJECT
  6.        +0x014 CurrentIrp       : Ptr32 _IRP
  7.        +0x018     Timer            :     Ptr32 _IO_TIMER
  8.        +0x01c     Flags            :     Uint4B
  9.        +0x020 Characteristics  : Uint4B
  10.        +0x024     Vpb                  : Ptr32 _VPB
  11.        +0x028 DeviceExtension  : Ptr32 Void
  12.        +0x02c DeviceType       : Uint4B
  13.        +0x030 StackSize        : Char
  14.        +0x034     Queue            :     __unnamed
  15.        +0x05c AlignmentRequirement : Uint4B
  16.        +0x060 DeviceQueue      : _KDEVICE_QUEUE
  17.        +0x074     Dpc                  : _KDPC
  18.        +0x094 ActiveThreadCount : Uint4B
  19.        +0x098 SecurityDescriptor : Ptr32 Void
  20.        +0x09c DeviceLock       : _KEVENT
  21.        +0x0ac SectorSize       : Uint2B
  22.        +0x0ae Spare1               : Uint2B
  23.        +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
  24.        +0x0b4 Reserved         : Ptr32     Void

通过这个结构我们知道f7353b25 的[eax+28h] 是指DeviceObject偏移0×28处,即是指向 DEVICE_OBJECT.DeviceExtension,
同理,我们可以知道f7353b31 的[ebp+0Ch]是指Irp了

好,话就到这里,相当聪明的你应该都知道后面我讲的那些东西是怎么得出来的了,后面我会大致讲一讲,不会讲得太细,毕竟这篇文章的重
点不是将Crack,如果你还不懂的话可能需要补一下相关的Crack知识。

当我们输入假码后,运行上面的代码之后会由f7353b2f跳到f7353b4b:

;跳到这里来执行

  1. f7353b4b     57                  push    edi
  1. f7353b4c     e835c9ffff      call    f7350486
  2. f7353b51     837f0806            cmp     dword ptr [edi+8],6
  3. f7353b55     8b750c              mov     esi,dword ptr     [ebp+0Ch]                ; Esi = Irp
  4. f7353b58     750c                jne         f7353b66                               ; 跳

跳到这里来执行

  1. f7353b66     8b4660              mov     eax,dword ptr     [esi+60h]                ; eax = Irp.Tail.CurrentStackLocation
  1. f7353b69     8b5008              mov     edx,dword ptr     [eax+8]                  ; edx = CurrentIoStackLocation.Parameters.InputBufferLength
  2. f7353b6c     8b400c              mov     eax,dword ptr     [eax+0Ch]                ; eax = CurrentIoStackLocation.Parameters.IoControlCode = 2A4010h
  3. f7353b6f     b914402a00      mov         ecx,2A4014h                            ; ecx = IOCTL_CODE
  4. f7353b74     3bc1                cmp         eax,ecx                                ; 比较IO控制码
  5. f7353b76     53                  push    ebx
  6. f7353b77     8b5e0c              mov     ebx,dword ptr     [esi+0Ch]                ; ebx = Irp.AssociatedIrp.SystemBuffer, 指向输入缓冲区
  7. f7353b7a     c745080d0000c0  mov     dword ptr     [ebp+8],0C000000Dh

上面的注解得出方法同前面的一致:

kd> dt -b _IRP

  1.        +0x000     Type                 : Int2B
  1.        +0x002     Size                 : Uint2B
  2.        +0x004 MdlAddress       : Ptr32
  3.        +0x008     Flags            :     Uint4B
  4.        +0x00c AssociatedIrp    : __unnamed
  5.           +0x000 MasterIrp        : Ptr32
  6.           +0x000 IrpCount         : Int4B
  7.           +0x000 SystemBuffer     : Ptr32
  8.        +0x010 ThreadListEntry  : _LIST_ENTRY
  9.           +0x000     Flink            :     Ptr32
  10.           +0x004     Blink            :     Ptr32
  11.        +0x018 IoStatus         :     _IO_STATUS_BLOCK
  12.           +0x000 Status               : Int4B
  13.           +0x000 Pointer          :     Ptr32
  14.           +0x004 Information      : Uint4B
  15.        +0x020 RequestorMode    : Char
  16.        +0x021 PendingReturned  : UChar
  17.        +0x022 StackCount       : Char
  18.        +0x023 CurrentLocation  : Char
  19.        +0x024 Cancel               : UChar
  20.        +0x025 CancelIrql       : UChar
  21.        +0x026 ApcEnvironment   : Char
  22.        +0x027 AllocationFlags  : UChar
  23.        +0x028 UserIosb         : Ptr32
  24.        +0x02c UserEvent        : Ptr32
  25.        +0x030 Overlay          :     __unnamed
  26.           +0x000 AsynchronousParameters : __unnamed
  27.              +0x000 UserApcRoutine   : Ptr32
  28.              +0x004 UserApcContext   : Ptr32
  29.           +0x000 AllocationSize   : _LARGE_INTEGER
  30.              +0x000 LowPart          :     Uint4B
  31.              +0x004 HighPart         : Int4B
  32.              +0x000 u                    : __unnamed
  33.                 +0x000 LowPart          :     Uint4B
  34.                 +0x004 HighPart         : Int4B
  35.              +0x000 QuadPart         : Int8B
  36.        +0x038 CancelRoutine    : Ptr32
  37.        +0x03c UserBuffer       : Ptr32
  38.        +0x040     Tail                 : __unnamed
  39.           +0x000 Overlay          :     __unnamed
  40.              +0x000 DeviceQueueEntry : _KDEVICE_QUEUE_ENTRY
  41.                 +0x000 DeviceListEntry  : _LIST_ENTRY
  42.                    +0x000     Flink            :     Ptr32
  43.                    +0x004     Blink            :     Ptr32
  44.                 +0x008 SortKey          :     Uint4B
  45.                 +0x00c Inserted         : UChar
  46.              +0x000 DriverContext    : Ptr32
  47.              +0x010 Thread               : Ptr32
  48.              +0x014 AuxiliaryBuffer  : Ptr32
  49.              +0x018 ListEntry        : _LIST_ENTRY
  50.                 +0x000     Flink            :     Ptr32
  51.                 +0x004     Blink            :     Ptr32
  52.              +0x020 CurrentStackLocation : Ptr32
  53.              +0x020 PacketType       : Uint4B
  54.              +0x024 OriginalFileObject : Ptr32
  55.           +0x000 Apc                  : _KAPC
  56.              +0x000     Type                 : Int2B
  57.              +0x002     Size                 : Int2B
  58.              +0x004 Spare0               : Uint4B
  59.              +0x008 Thread               : Ptr32
  60.              +0x00c ApcListEntry     : _LIST_ENTRY
  61.                 +0x000 Flink                : Ptr32
  62.                 +0x004     Blink            :     Ptr32
  63.              +0x014 KernelRoutine    : Ptr32
  64.              +0x018 RundownRoutine   : Ptr32
  65.              +0x01c NormalRoutine    : Ptr32
  66.              +0x020 NormalContext    : Ptr32
  67.              +0x024 SystemArgument1  : Ptr32
  68.              +0x028 SystemArgument2  : Ptr32
  69.              +0x02c ApcStateIndex    : Char
  70.              +0x02d ApcMode          :     Char
  71.              +0x02e Inserted         : UChar
  72.           +0x000 CompletionKey    : Ptr32

kd> dt -b _IO_STACK_LOCATION

  1.        +0x000 MajorFunction    : UChar
  1.        +0x001 MinorFunction    : UChar
  2.        +0x002     Flags            :     UChar
  3.        +0x003 Control          :     UChar
  4.        +0x004 Parameters       : __unnamed
  5.      
  6.           ...... 省略若干     ......
  7.      
  8.           +0x000 DeviceIoControl  : __unnamed
  9.              +0x000 OutputBufferLength : Uint4B
  10.              +0x004 InputBufferLength : Uint4B
  11.              +0x008 IoControlCode    : Uint4B
  12.              +0x00c Type3InputBuffer : Ptr32
  13.      
  14.           ...... 省略若干     ......
  15.      
  16.        +0x014 DeviceObject     : Ptr32
  17.        +0x018 FileObject       : Ptr32
  18.        +0x01c CompletionRoutine : Ptr32
  19.        +0x020 Context          :     Ptr32

通过上面的代码我们得到了输入缓冲区和其长度,并且取得了控制码为2A4010H,EBX指向输入缓冲区,EDX为其长度,值为604H,于是我们在
Command中输入如下命令来查看一下内存中的数据:

kd> d ebx L0×604

  1. 812715c8      04 06 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  1. 812715d8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  2. 812715e8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  3. 812715f8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  4. 81271608      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  5. 81271618      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  6. 81271628      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  7. 81271638      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  8. 81271648      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  9. 81271658      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  10. 81271668      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  11. 81271678      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  12. 81271688      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  13. 81271698      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  14. 812716a8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  15. 812716b8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  16. 812716c8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  17. 812716d8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  18. 812716e8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  19. 812716f8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  20. 81271708      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  21. 81271718      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  22. 81271728      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  23. 81271738      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  24. 81271748      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  25. 81271758      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  26. 81271768      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  27. 81271778      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  28. 81271788      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  29. 81271798      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  30. 812717a8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  31. 812717b8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  32. 812717c8      00 00 00 00 78 49 6b 55-67 00 00 00 00 00 00 00  ....xIkUg.......
  33. 812717d8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  34. 812717e8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  35. 812717f8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  36. 81271808      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  37. 81271818      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  38. 81271828      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  39. 81271838      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  40. 81271848      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  41. 81271858      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  42. 81271868      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  43. 81271878      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  44. 81271888      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  45. 81271898      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  46. 812718a8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  47. 812718b8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  48. 812718c8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  49. 812718d8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  50. 812718e8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  51. 812718f8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  52. 81271908      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  53. 81271918      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  54. 81271928      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  55. 81271938      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  56. 81271948      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  57. 81271958      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  58. 81271968      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  59. 81271978      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  60. 81271988      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  61. 81271998      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  62. 812719a8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  63. 812719b8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  64. 812719c8      00 00 00 00 41 41 41 41-41 41 41 41 42 42 42 42  ....AAAAAAAABBBB
  65. 812719d8      42 42 42 42 43 43 43 43-43 43 43 43 44 44 44 44  BBBBCCCCCCCCDDDD
  66. 812719e8      44 44 44 44 00 00 00 00-00 00 00 00 00 00 00 00  DDDD............
  67. 812719f8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  68. 81271a08      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  69. 81271a18      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  70. 81271a28      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  71. 81271a38      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  72. 81271a48      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  73. 81271a58      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  74. 81271a68      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  75. 81271a78      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  76. 81271a88      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  77. 81271a98      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  78. 81271aa8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  79. 81271ab8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  80. 81271ac8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  81. 81271ad8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  82. 81271ae8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  83. 81271af8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  84. 81271b08      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  85. 81271b18      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  86. 81271b28      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  87. 81271b38      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  88. 81271b48      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  89. 81271b58      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  90. 81271b68      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  91. 81271b78      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  92. 81271b88      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  93. 81271b98      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  94. 81271ba8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  95. 81271bb8      00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
  96. 81271bc8      00 00 00     00                                          ....

在这604H个字节中包含了我们输入的用户名和注册码。

好,我们继续向下走:

  1. f7353b81     0f8727010000    ja      f7353cae
  1. f7353b87     0f84d2000000    je      f7353c5f
  2. f7353b8d     2d00402a00      sub         eax,2A4000h                            ; IO控制码减2A4000h    
  3. f7353b92     0f8488000000    je          f7353c20                               ; 为2A4000h跳
  4. f7353b98     83e804              sub     eax,4
  5. f7353b9b     7469                je          f7353c06                               ; 为2A4004h跳
  6. f7353b9d     83e804              sub     eax,4
  7. f7353ba0     7444                je          f7353be6                               ; 为2A4008h跳
  8. f7353ba2     83e808              sub     eax,8
  9. f7353ba5     0f85f8010000    jne         f7353da3                               ; 不为2A4010h的话则结束处理

此处是处理控制码为2A4010h的代码

  1. f7353bab     833d543a35f700  cmp     dword ptr     ds:[0F7353A54h],0        ; 是否注册
  1. f7353bb2     0f85eb010000    jne         f7353da3                               ; 已经注册则结束处理
  2. f7353bb8     b804060000      mov         eax,604h                               ;
  3. f7353bbd     3bd0                cmp         edx,eax                                ; 缓冲区长度是否为604h    
  4. f7353bbf     0f85de010000    jne         f7353da3                               ; 不为604h则结束处理
  5. f7353bc5     3903                cmp     dword ptr     [ebx],eax                    ; 比较缓冲区的长度
  6. f7353bc7     0f85d6010000    jne         f7353da3                               ; 不为604h则结束处理

从前面知道 edi 指向设备扩展, ebx 指向 输入缓冲区,后面就处理结束了,因此可以知道f7351532是处理注册的算法函数,我们跟进

  1. f7353bcd     57                  push    edi
  1. f7353bce     53                  push    ebx
  2. f7353bcf     e85ed9ffff      call        f7351532                               ; 跟进
  3. f7353bd4     85c0                test    eax,eax
  4. f7353bd6     894508              mov     dword ptr [ebp+8],eax                  ; 保存注册结果
  5. f7353bd9     0f94c0              sete    al
  6. f7353bdc     a2803535f7      mov     byte     ptr ds:[F7353580h],al
  7. f7353be1     e9bd010000      jmp         f7353da3                               ; 处理结束

跟进f7351532后我们来到这里:

  1. f7351532     8bff                mov     edi,edi
  1. f7351534     55                  push    ebp
  2. f7351535     8bec                mov     ebp,esp
  3. f7351537     81ecac000000    sub     esp,0ACh
  4. f735153d     803d183a35f700  cmp     byte ptr     ds:[0F7353A18h],0 ds:0023:f7353a18=01
  5. f7351544     a1a03335f7      mov         eax,dword ptr ds:[F73533A0h]
  6. f7351549     53                  push    ebx
  7. f735154a     8b5d08              mov     ebx,dword ptr     [ebp+8]                  ; [ebp+8] = 输入缓冲区
  8. f735154d     56                  push    esi
  9. f735154e     8b750c              mov     esi,dword ptr     [ebp+0Ch]                ; [ebp+0Ch] = DeviceExtension
  10. f7351551     8945fc              mov     dword ptr [ebp-4],eax
  11. f7351554     c6855bffffff00  mov     byte ptr [ebp-0A5h],0
  12. f735155b     750a                jne         f7351567                               ; 跳
  13. f735155d     b8010000c0      mov         eax,0C0000001h
  14. f7351562     e9e3000000      jmp         f735164a
  15. f7351567     8d4e30              lea         ecx,[esi+30h]                          ; 跳到这里
  16. f735156a     57                  push    edi
  17. f735156b     898d54ffffff    mov     dword ptr     [ebp-0ACh],ecx ss:0010:bcbc1b34=00000000
  18. f7351571     ff15802535f7    call    dword ptr     ds:[0F7352580h]          ;     call    ds:ExAcquireFastMutex
  19. f7351577     6a0a                push    0Ah
  20. f7351579     59                  pop     ecx
  21. f735157a     33c0                xor     eax,eax
  22. f735157c     8d7d84              lea     edi,[ebp-7Ch]
  23. f735157f     56                  push    esi
  24. f7351580     f3ab            rep     stos dword ptr es:[edi]  es:0023:bcbc1b64=00000000
  25. f7351582     e851fdffff      call    f73512d8
  26. f7351587     be083a35f7      mov         esi,0F7353A08h
  27. f735158c     8d7dcc              lea     edi,[ebp-34h]
  28. f735158f     a5                  movs    dword ptr es:[edi],dword ptr [esi]
  29. f7351590     a5                  movs    dword ptr es:[edi],dword ptr [esi]
  30. f7351591     8d45dc              lea         eax,[ebp-24h]                          ; [ebp-24h] = 存放用户名MD5值的缓冲区
  31. f7351594     a5                  movs    dword ptr es:[edi],dword ptr [esi]
  32. f7351595     50                  push    eax
  33. f7351596     8d8304020000    lea     eax,[ebx+204h]
  34. f735159c     50                  push    eax
  35. f735159d     a5                  movs    dword ptr es:[edi],dword ptr [esi] ; 这一段是把序列号复制到edi指向的地方

我们对比一下,在驱动内部的序列号表示和ring3应用程序中显示的序列号,某些数字是被替换过了,他们有一种对应关系:

  1. a5     13 c1 18 26 f7 30 4e 56 09 19 d8 38 fe 28 cc
  1. A513C11W-26F73M4E-56M919DW-3WFE2WCC

对应关系为:

  1. 8-W    
  1. 0-M    
  2. B-K

继续往下:

  1. f735159e     e8dbfcffff      call        f735127e                               ; 跟进,这里是求用户名的MD5值
  1. f73515a3     6a0a                push    0Ah
  2. f73515a5     59                  pop     ecx

从f735127e跟进,我们来到下面的地方:

  1. f735127e     8bff                mov     edi,edi
  1. f7351280     55                  push    ebp
  2. f7351281     8bec                mov     ebp,esp
  3. f7351283     e898f5ffff      call        f7350820                               ; 初始化MD5种子
  4. f7351288     8b4508              mov     eax,dword ptr     [ebp+8]                  ; [ebp+8] = 用户名
  5. f735128b     8d4801              lea     ecx,[eax+1]
  6. f735128e     8a10                mov     dl,byte ptr [eax]
  7. f7351290     40                  inc     eax
  8. f7351291     84d2                test    dl,dl
  9. f7351293     75f9                jne     f735128e
  10. f7351295     2bc1                sub     eax,ecx                                ; 求用户名长度
  11. f7351297     50                  push        eax                                    ; 长度入栈
  12. f7351298     ff7508              push    dword ptr     [ebp+8]                      ; 用户名入栈
  13. f735129b     e874feffff      call        f7351114                               ; 求用户名的md5值
  14. f73512a0     ff750c              push    dword ptr     [ebp+0Ch]                    ; [ebp+0Ch] = md5值缓冲区
  15. f73512a3     e836ffffff      call        f73511de                               ; 把用户名的md5值放入缓冲区
  16. f73512a8     5d                  pop     ebp
  17. f73512a9     c20800              ret         8                                      ; 返回

我们于是知道f735127e函数是求md5值的,从这个函数返回后,我们继续:

  1. f73515a3     6a0a                push    0Ah
  1. f73515a5     59                  pop     ecx
  2. f73515a6     33c0                xor     eax,eax
  3. f73515a8     8dbd5cffffff    lea         edi,[ebp-0A4h]                         ; [ebp-0A4h] = 存放md5值字符串的缓冲区
  4. f73515ae     f3ab            rep     stos dword ptr     es:[edi]                    ; 缓冲区清0
  5. f73515b0     8d855cffffff    lea     eax,[ebp-0A4h]
  6. f73515b6     50                  push        eax                                    ; 入栈
  7. f73515b7     8d45dc              lea         eax,[ebp-24h]                          ; [ebp-24h] = 用户名的md5值缓冲区
  8. f73515ba     50                  push        eax                                    ; 入栈
  9. f73515bb     e8d8f1ffff      call        f7350798                               ; 把二进制值转为16进制字符串
  10. f73515c0     6a10                push    10h
  11. f73515c2     5e                  pop     esi
  12. f73515c3     33c0                xor     eax,eax
  13. f73515c5     5f                  pop     edi
  14. f73515c6     8a4c05dc            mov     cl,byte ptr     [ebp+eax-24h]          ; 用户名的md5值
  15. f73515ca     224c05cc            and     cl,byte ptr     [ebp+eax-34h]          ; 跟序列号的值进行“与”运算
  16. f73515ce     40                  inc     eax
  17. f73515cf     3bc6                cmp     eax,esi
  18. f73515d1     884c05bb            mov     byte ptr     [ebp+eax-45h],cl          ; 运算结果放到[ebp+eax-45h]的地方
  19. f73515d5     7cef                jl      f73515c6
  20. f73515d7     8d45ec              lea     eax,[ebp-14h]
  21. f73515da     50                  push        eax                                    ; 输出缓冲区
  22. f73515db     56                  push        esi                                    ; esi = 10H, 缓冲区长度
  23. f73515dc     8d45bc              lea         eax,[ebp-44h]                          ; 输入缓冲区, 指向用户名的md5值与序列号运算的结果
  24. f73515df     50                  push    eax
  25. f73515e0     e8cdfcffff      call        f73512b2                               ; 再次计算MD5    
  26. f73515e5     8d4584              lea         eax,[ebp-7Ch]                          ; [ebp-7Ch] = 存放md5值字符串的缓冲区
  27. f73515e8     50                  push    eax
  28. f73515e9     8d45ec              lea         eax,[ebp-14h]                          ; [ebp-14h] = 指向刚计算出来的md5的值
  29. f73515ec     50                  push    eax
  30. f73515ed     e8a6f1ffff      call        f7350798                               ; 这个函数与前面的函数一样,把二进制值转为16进制字符串
  31. f73515f2     8d45ec              lea         eax,[ebp-14h]                          ; md5值的输出缓冲区
  32. f73515f5     50                  push        eax                                    ; 入栈
  33. f73515f6     8d4584              lea     eax,[ebp-7Ch]                          ; 输入缓冲区,指向刚才转换出来的字符串
  34. f73515f9     50                  push        eax                                    ; 入栈
  35. f73515fa     e87ffcffff      call        f735127e                               ; 计算MD5值, 这里是最终与注册码比较的md5值了,我们设为Result_MD5
  36. f73515ff     8d45ac          lea         eax,[ebp-54h]
  37. f7351602     50                  push        eax                                    ; md5值输出缓冲区
  38. f7351603     81c304040000    add         ebx,404h                               ; ebx = 指向我们输入的注册码
  39. f7351609     53                  push    ebx
  40. f735160a     e86ffcffff      call        f735127e                               ; 计算md5值
  41. f735160f     33c0                xor     eax,eax
  42. f7351611     8a4c05ac            mov     cl,byte ptr     [ebp+eax-54h]          ;     [ebp+eax-54h] = 我们输入的注册码的md5值
  43. f7351615     3a4c05ec            cmp     cl,byte ptr     [ebp+eax-14h]          ; 与Result_MD5[eax]进行比较
  44. f7351619     7505                jne         f7351620                               ; 不一样就失败跳
  45. f735161b     40                  inc     eax
  46. f735161c     3bc6                cmp     eax,esi
  47. f735161e     7cf1                jl      f7351611
  48. f7351620     3bc6            cmp         eax,esi                                ; eax索引与esi表示长度是否一样,这句话的意思就是看是不是把md5值的各字节都比较完了
  49. f7351622     b301                mov         bl,1                                   ;
  50. f7351624     7406                je          f735162c                               ; 如果是比较完成则证明注册码是正确的,注册成功
  51. f7351626     8a9d5bffffff    mov     bl,byte ptr     [ebp-0A5h]                 ; [ebp-0A5h]存放的是0,表示注册失败了
  52. f735162c     8b8d54ffffff    mov     ecx,dword ptr     [ebp-0ACh]
  53. f7351632     ff15842535f7    call    dword ptr     ds:[0F7352584h]
  54. f7351638     f6db                neg     bl
  55. f735163a     1bdb                sbb     ebx,ebx
  56. f735163c     81e3f3ffff3f    and     ebx,3FFFFFF3h
  57. f7351642     81c30d0000c0    add     ebx,0C000000Dh
  58. f7351648     8bc3                mov     eax,ebx
  59. f735164a     8b4dfc              mov     ecx,dword ptr [ebp-4]
  60. f735164d     5e                  pop     esi
  61. f735164e     5b                  pop     ebx
  62. f735164f     e86a030000      call    f73519be
  63. f7351654     c9                  leave
  64. f7351655     c20800              ret     8

到这里我们的算法分析就完成了。

算法总结:
1. 求用户名的md5值,设为usermd5
2. usermd5的值与序列号的值进行“与”运算,结果设为mid_result1
3. 求mid_result1的MD5值,结果设为mid_result2
4. mid_result2转换为字符串,结果设为mid_result3
5. 求mid_result3的MD5值,结果设为Result_MD5
6. 求注册码的MD5值,结果设为Regcode_MD5
7. 比较Result_MD5与Regcode_MD5,如果值都相等则注册成功,否则注册失败。