iniwf

风是温柔的,雨是伤心的,云是快乐的,月是多情的,爱是迷失的,恋是醉人的,情是难忘的,天是长久的,地是永恒的

使用WinDBG进行双机内核调试

标 题: 使用WinDBG进行双机内核调试
作 者: xIkUg
时 间: 2006-11-10 21:16
链 接: http://bbs.pediy.com/showthread.php?threadid=34731
详细信息:

使用WinDBG进行双机内核调试

By xikug.xp
版本:1.0
作者:xIkUg/RCT
xikug.xp [at] gmail [dot] com

我常去的网站:

http://www.wintoolspro.com
http://debugman.wintoolspro.com
http://www.fcgchina.com
http://bbs.pediy.com
http://www.unpack.cn

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

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

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

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

如图:

SerialNULL的设置

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

在VirtualPC中设置:

Virtual PC中的设置

进行入虚拟机系统(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模式启动系统:

 

以Debug模式启动系统

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

 

WinDBG设置

点击“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

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

rtytry

 

我们找到了

[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:

f7353b1a 8bff            mov     edi,edi                            ; 这里断下 
f7353b1c 55              push    ebp 
f7353b1d 8bec            mov     ebp,esp 
f7353b1f 51              push    ecx 
f7353b20 8b4508          mov     eax,dword ptr [ebp+8]              ; [ebp+8] = DeviceObject 
f7353b23 56              push    esi 
f7353b24 57              push    edi 
f7353b25 8b7828          mov     edi,dword ptr [eax+28h]            ; [eax+28h] = DEVICE_OBJECT.DeviceExtension 
f7353b28 807f0400        cmp     byte ptr [edi+4],0                 ; ds:0023:8145494c=01 
f7353b2c 897dfc          mov     dword ptr [ebp-4],edi              ; 保存设备扩展 
f7353b2f 751a            jne     f7353b4b                           ; 8145494c如果为真则跳,否则执行下面的代码并退出这个 routine 
f7353b31 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]            ; Irp 
f7353b34 be100000c0      mov     esi,0C0000010h                     ; 0C0000010h = STATUS_INVALID_DEVICE_REQUEST 
f7353b39 32d2            xor     dl,dl 
f7353b3b 897118          mov     dword ptr [ecx+18h],esi            ; [ecx+18h] = IoStatus 
f7353b3e ff15182635f7    call    dword ptr ds:[0F7352618h]          ; [0F7352618h] = IofCompleteRequest 
f7353b44 8bc6            mov     eax,esi                            ; 返回状态 
f7353b46 e977020000      jmp     f7353dc2                           ; Exit 
在这里你可能看到这些代码后的注解可能会问为什么是这样的?不急,让我们看看MSND,DeviceControl的函数原型如下:

NTSTATUS XxxDispatchDeviceControl( 
    IN PDEVICE_OBJECT DeviceObject, 
    IN PIRP Irp); 
于是我们知道f7353b20 的[ebp+8] 指向 DeviceObject

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

kd> dt _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 
通过这个结构我们知道f7353b25 的[eax+28h] 是指DeviceObject偏移0×28处,即是指向 DEVICE_OBJECT.DeviceExtension,
同理,我们可以知道f7353b31 的 [ebp+0Ch]是指Irp了

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

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

;跳到这里来执行

f7353b4b 57              push    edi 
f7353b4c e835c9ffff      call    f7350486 
f7353b51 837f0806        cmp     dword ptr [edi+8],6 
f7353b55 8b750c          mov     esi,dword ptr [ebp+0Ch]            ; Esi = Irp 
f7353b58 750c            jne     f7353b66                           ; 跳 
跳到这里来执行

f7353b66 8b4660          mov     eax,dword ptr [esi+60h]            ; eax = Irp.Tail.CurrentStackLocation 
f7353b69 8b5008          mov     edx,dword ptr [eax+8]              ; edx = CurrentIoStackLocation.Parameters.InputBufferLength 
f7353b6c 8b400c          mov     eax,dword ptr [eax+0Ch]            ; eax = CurrentIoStackLocation.Parameters.IoControlCode = 2A4010h 
f7353b6f b914402a00      mov     ecx,2A4014h                        ; ecx = IOCTL_CODE 
f7353b74 3bc1            cmp     eax,ecx                            ; 比较IO控制码 
f7353b76 53              push    ebx 
f7353b77 8b5e0c          mov     ebx,dword ptr [esi+0Ch]            ; ebx = Irp.AssociatedIrp.SystemBuffer, 指向输入缓冲区 
f7353b7a c745080d0000c0  mov     dword ptr [ebp+8],0C000000Dh 
上面的注解得出方法同前面的一致:

kd> dt -b _IRP

   +0x000 Type             : Int2B 
   +0x002 Size             : Uint2B 
   +0x004 MdlAddress       : Ptr32 
   +0x008 Flags            : Uint4B 
   +0x00c AssociatedIrp    : __unnamed 
      +0x000 MasterIrp        : Ptr32 
      +0x000 IrpCount         : Int4B 
      +0x000 SystemBuffer     : Ptr32 
   +0x010 ThreadListEntry  : _LIST_ENTRY 
      +0x000 Flink            : Ptr32 
      +0x004 Blink            : Ptr32 
   +0x018 IoStatus         : _IO_STATUS_BLOCK 
      +0x000 Status           : Int4B 
      +0x000 Pointer          : Ptr32 
      +0x004 Information      : Uint4B 
   +0x020 RequestorMode    : Char 
   +0x021 PendingReturned  : UChar 
   +0x022 StackCount       : Char 
   +0x023 CurrentLocation  : Char 
   +0x024 Cancel           : UChar 
   +0x025 CancelIrql       : UChar 
   +0x026 ApcEnvironment   : Char 
   +0x027 AllocationFlags  : UChar 
   +0x028 UserIosb         : Ptr32 
   +0x02c UserEvent        : Ptr32 
   +0x030 Overlay          : __unnamed 
      +0x000 AsynchronousParameters : __unnamed 
         +0x000 UserApcRoutine   : Ptr32 
         +0x004 UserApcContext   : Ptr32 
      +0x000 AllocationSize   : _LARGE_INTEGER 
         +0x000 LowPart          : Uint4B 
         +0x004 HighPart         : Int4B 
         +0x000 u                : __unnamed 
            +0x000 LowPart          : Uint4B 
            +0x004 HighPart         : Int4B 
         +0x000 QuadPart         : Int8B 
   +0x038 CancelRoutine    : Ptr32 
   +0x03c UserBuffer       : Ptr32 
   +0x040 Tail             : __unnamed 
      +0x000 Overlay          : __unnamed 
         +0x000 DeviceQueueEntry : _KDEVICE_QUEUE_ENTRY 
            +0x000 DeviceListEntry  : _LIST_ENTRY 
               +0x000 Flink            : Ptr32 
               +0x004 Blink            : Ptr32 
            +0x008 SortKey          : Uint4B 
            +0x00c Inserted         : UChar 
         +0x000 DriverContext    : Ptr32 
         +0x010 Thread           : Ptr32 
         +0x014 AuxiliaryBuffer  : Ptr32 
         +0x018 ListEntry        : _LIST_ENTRY 
            +0x000 Flink            : Ptr32 
            +0x004 Blink            : Ptr32 
         +0x020 CurrentStackLocation : Ptr32 
         +0x020 PacketType       : Uint4B 
         +0x024 OriginalFileObject : Ptr32 
      +0x000 Apc              : _KAPC 
         +0x000 Type             : Int2B 
         +0x002 Size             : Int2B 
         +0x004 Spare0           : Uint4B 
         +0x008 Thread           : Ptr32 
         +0x00c ApcListEntry     : _LIST_ENTRY 
            +0x000 Flink            : Ptr32 
            +0x004 Blink            : Ptr32 
         +0x014 KernelRoutine    : Ptr32 
         +0x018 RundownRoutine   : Ptr32 
         +0x01c NormalRoutine    : Ptr32 
         +0x020 NormalContext    : Ptr32 
         +0x024 SystemArgument1  : Ptr32 
         +0x028 SystemArgument2  : Ptr32 
         +0x02c ApcStateIndex    : Char 
         +0x02d ApcMode          : Char 
         +0x02e Inserted         : UChar 
      +0x000 CompletionKey    : Ptr32 
kd> dt -b _IO_STACK_LOCATION

   +0x000 MajorFunction    : UChar 
   +0x001 MinorFunction    : UChar 
   +0x002 Flags            : UChar 
   +0x003 Control          : UChar 
   +0x004 Parameters       : __unnamed 
  
      ...... 省略若干 ...... 
  
      +0x000 DeviceIoControl  : __unnamed 
         +0x000 OutputBufferLength : Uint4B 
         +0x004 InputBufferLength : Uint4B 
         +0x008 IoControlCode    : Uint4B 
         +0x00c Type3InputBuffer : Ptr32 
  
      ...... 省略若干 ...... 
  
   +0x014 DeviceObject     : Ptr32 
   +0x018 FileObject       : Ptr32 
   +0x01c CompletionRoutine : Ptr32 
   +0x020 Context          : Ptr32 
通过上面的代码我们得到了输入缓冲区和其长度,并且取得了控制码为2A4010H,EBX指向输入缓冲区,EDX为其长度,值为604H,于是我们在
Command中输入如下命令来查看一下内存中的数据:

kd> d ebx L0×604

812715c8  04 06 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812715d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812715e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812715f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271608  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271618  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271628  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271638  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271648  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271658  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271668  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271678  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271688  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271698  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716a8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716c8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812716f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271708  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271718  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271728  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271738  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271748  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271758  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271768  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271778  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271788  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271798  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812717a8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812717b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812717c8  00 00 00 00 78 49 6b 55-67 00 00 00 00 00 00 00  ....xIkUg....... 
812717d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812717e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812717f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271808  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271818  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271828  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271838  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271848  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271858  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271868  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271878  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271888  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271898  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718a8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718c8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812718f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271908  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271918  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271928  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271938  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271948  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271958  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271968  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271978  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271988  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271998  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812719a8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812719b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
812719c8  00 00 00 00 41 41 41 41-41 41 41 41 42 42 42 42  ....AAAAAAAABBBB 
812719d8  42 42 42 42 43 43 43 43-43 43 43 43 44 44 44 44  BBBBCCCCCCCCDDDD 
812719e8  44 44 44 44 00 00 00 00-00 00 00 00 00 00 00 00  DDDD............ 
812719f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a08  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a18  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a28  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a38  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a48  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a58  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a68  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a78  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a88  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271a98  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271aa8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271ab8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271ac8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271ad8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271ae8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271af8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b08  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b18  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b28  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b38  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b48  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b58  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b68  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b78  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b88  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271b98  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271ba8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271bb8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................ 
81271bc8  00 00 00 00                                      .... 
在这604H个字节中包含了我们输入的用户名和注册码。

好,我们继续向下走:

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

f7353bab 833d543a35f700  cmp     dword ptr ds:[0F7353A54h],0        ; 是否注册 
f7353bb2 0f85eb010000    jne     f7353da3                           ; 已经注册则结束处理 
f7353bb8 b804060000      mov     eax,604h                           ; 
f7353bbd 3bd0            cmp     edx,eax                            ; 缓冲区长度是否为604h 
f7353bbf 0f85de010000    jne     f7353da3                           ; 不为604h则结束处理 
f7353bc5 3903            cmp     dword ptr [ebx],eax                ; 比较缓冲区的长度 
f7353bc7 0f85d6010000    jne     f7353da3                           ; 不为604h则结束处理 
从前面知道 edi 指向设备扩展, ebx 指向 输入缓冲区,后面就处理结束了,因此可以知道f7351532是处理注册的算法函数,我们跟进

f7353bcd 57              push    edi 
f7353bce 53              push    ebx 
f7353bcf e85ed9ffff      call    f7351532                           ; 跟进 
f7353bd4 85c0            test    eax,eax 
f7353bd6 894508          mov     dword ptr [ebp+8],eax              ; 保存注册结果 
f7353bd9 0f94c0          sete    al 
f7353bdc a2803535f7      mov     byte ptr ds:[F7353580h],al 
f7353be1 e9bd010000      jmp     f7353da3                           ; 处理结束 
跟进f7351532后我们来到这里:

f7351532 8bff            mov     edi,edi 
f7351534 55              push    ebp 
f7351535 8bec            mov     ebp,esp 
f7351537 81ecac000000    sub     esp,0ACh 
f735153d 803d183a35f700  cmp     byte ptr ds:[0F7353A18h],0 ds:0023:f7353a18=01 
f7351544 a1a03335f7      mov     eax,dword ptr ds:[F73533A0h] 
f7351549 53              push    ebx 
f735154a 8b5d08          mov     ebx,dword ptr [ebp+8]              ; [ebp+8] = 输入缓冲区 
f735154d 56              push    esi 
f735154e 8b750c          mov     esi,dword ptr [ebp+0Ch]            ; [ebp+0Ch] = DeviceExtension 
f7351551 8945fc          mov     dword ptr [ebp-4],eax 
f7351554 c6855bffffff00  mov     byte ptr [ebp-0A5h],0 
f735155b 750a            jne     f7351567                           ; 跳 
f735155d b8010000c0      mov     eax,0C0000001h 
f7351562 e9e3000000      jmp     f735164a 
f7351567 8d4e30          lea     ecx,[esi+30h]                      ; 跳到这里 
f735156a 57              push    edi 
f735156b 898d54ffffff    mov     dword ptr [ebp-0ACh],ecx ss:0010:bcbc1b34=00000000 
f7351571 ff15802535f7    call    dword ptr ds:[0F7352580h]          ; call    ds:ExAcquireFastMutex 
f7351577 6a0a            push    0Ah 
f7351579 59              pop     ecx 
f735157a 33c0            xor     eax,eax 
f735157c 8d7d84          lea     edi,[ebp-7Ch] 
f735157f 56              push    esi 
f7351580 f3ab            rep stos dword ptr es:[edi]  es:0023:bcbc1b64=00000000 
f7351582 e851fdffff      call    f73512d8 
f7351587 be083a35f7      mov     esi,0F7353A08h 
f735158c 8d7dcc          lea     edi,[ebp-34h] 
f735158f a5              movs    dword ptr es:[edi],dword ptr [esi] 
f7351590 a5              movs    dword ptr es:[edi],dword ptr [esi] 
f7351591 8d45dc          lea     eax,[ebp-24h]                      ; [ebp-24h] = 存放用户名MD5值的缓冲区 
f7351594 a5              movs    dword ptr es:[edi],dword ptr [esi] 
f7351595 50              push    eax 
f7351596 8d8304020000    lea     eax,[ebx+204h] 
f735159c 50              push    eax 
f735159d a5              movs    dword ptr es:[edi],dword ptr [esi] ; 这一段是把序列号复制到edi指向的地方 
我们对比一下,在驱动内部的序列号表示和ring3应用程序中显示的序列号,某些数字是被替换过了,他们有一种对应关系:

a5 13 c1 18 26 f7 30 4e 56 09 19 d8 38 fe 28 cc 
A513C11W-26F73M4E-56M919DW-3WFE2WCC 
对应关系为:

8-W 
0-M 
B-K 
继续往下:

f735159e e8dbfcffff      call    f735127e                           ; 跟进,这里是求用户名的MD5值 
f73515a3 6a0a            push    0Ah 
f73515a5 59              pop     ecx 
从f735127e跟进,我们来到下面的地方:

f735127e 8bff            mov     edi,edi 
f7351280 55              push    ebp 
f7351281 8bec            mov     ebp,esp 
f7351283 e898f5ffff      call    f7350820                           ; 初始化MD5种子 
f7351288 8b4508          mov     eax,dword ptr [ebp+8]              ; [ebp+8] = 用户名 
f735128b 8d4801          lea     ecx,[eax+1] 
f735128e 8a10            mov     dl,byte ptr [eax] 
f7351290 40              inc     eax 
f7351291 84d2            test    dl,dl 
f7351293 75f9            jne     f735128e 
f7351295 2bc1            sub     eax,ecx                            ; 求用户名长度 
f7351297 50              push    eax                                ; 长度入栈 
f7351298 ff7508          push    dword ptr [ebp+8]                  ; 用户名入栈 
f735129b e874feffff      call    f7351114                           ; 求用户名的md5值 
f73512a0 ff750c          push    dword ptr [ebp+0Ch]                ; [ebp+0Ch] = md5值缓冲区 
f73512a3 e836ffffff      call    f73511de                           ; 把用户名的md5值放入缓冲区 
f73512a8 5d              pop     ebp 
f73512a9 c20800          ret     8                                  ; 返回 
我们于是知道f735127e函数是求md5值的,从这个函数返回后,我们继续:

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

据此,我们这次内核驱动调试之旅就结束了,相当成功,我们可以根据算法写注册机了。

感谢:Forever, fly, heXer, jwh51, +dEMON, kanxue, shoooo, 南蛮妈妈, sucsor, cnbragon, 堀北真希, DarkNess0ut and RCT & FCG & CCG all Members and you


©2000-2007 PEdiy.com All rights reserved.
By PEDIY

posted on 2009-03-30 22:45 iniwf 阅读(1339) 评论(0)  编辑 收藏 引用 所属分类: 驱动


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

收藏夹

IT技术

积分与排名

最新评论

阅读排行榜

评论排行榜