科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道从Ollydbg说起-----WinDbg用户态调试教程(4)

从Ollydbg说起-----WinDbg用户态调试教程(4)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

我假设你已经掌握Ollydbg的使用,并且希望用WinDbg进行内核级的调试。这篇教程将会以Ollydbg为线索,帮助你尽快掌握WinDbg的使用,并简单介绍它的一些特性。我把这篇文章定位为Ollydbg到WinDbg内核调试之间的过渡。

作者:论坛整理 来源:zdnet网络安全 2008年4月14日

关键字: 加密 OllyDBG 破解

  • 评论
  • 分享微博
  • 分享邮件
2.2.2  断点功能

软中断,即INT3:

[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"] 

~Thread 指定线程,可缺省
ID       指定断点ID,可缺省。内核调试限32个断点,用户模式不限
Options 可缺省
/1  中断后自动删除该断点。
      /c  指定最大调用深度,大于这个深度则断点不工作。
          /C 指定最小调用深度,小于这个深度则断点不工作。/C和/c不能同时使用。
      
Address   地址或符号。例如MessageBoxW.
Passes    忽略中断的次数,可缺省。例:
bp messageboxw 1
则程序会忽略第一次调用messageboxw产生的中断,其后激活断点。
CommandString  可缺省。每次中断后都会运行该命令行。一般用于设置条件断点,也用于HOOK 某些用于ANTI DEBUG的API

硬件断点:

[~Thread] ba[ID] Access Size [Options] [Address [Passes]] ["CommandString"] 

Access r 读写;w 写;e 运行;I I/O操作断点,只限XP或以后版本,内核调试,X86系列。
Size    大小,只能是1,2,4,8。如果Access为e,则只能是1。

例:Ba e1 0040c7c0;             $运行断点
    Ba w4 0040c7c0;             $0040c7c0和0040c7c4范围内进行写操作则断 

除了ba和bp,还有以下两个断点相关指令

bl 显示当前断点状态及ID

bc ID 删除断点,例如bc *;    $删除所有断点。

异常断点:

菜单“debug=>event filters”,在这里你能设置包括断点异常在内的所有异常的处理方式。一般我们不关心那个。Ollydbg提供了SHIFT+F7/F8/F9,而WinDbg就只提供了一个指令gN。注意WinDbg某些指令是区分大小写的。把这个放在这里说是因为你也可以用该命令下断,下面让我们来看看gN的用法

[~Thread] gN[a] [= StartAddress] [BreakAddress ... [; BreakCommands]] 

a     如果你使用了gNa那么将会以内存断点的方式中断,缺省则以软中断的方式
BreakCommands     中断产生之后便会运行该命令

这相当于Ollydbg中的SHIFT+F9

消息断点:

WinDbg并没有提供这个功能,不过你可以写一个SCRIPT对 RegisterClass 或RegisterClassEx设断,取得WNDPROC的首址,并设条件断点。由于我对消息机制了解不多,这里就不给出SCRIPT了。

2.2.3  自动跟踪

[~Thread] t [r] [= StartAddress] [Count] ["Command"]
[~Thread] 设置其影响的线程。可缺省
[= StartAddress] 设置起始地址。要注意在地址前面加上=,否则会被当作COUNT参数。此外还会以当前环境(堆栈和寄存器),直接跳到该地址执行跟踪。可缺省
[Count]    跟踪步数,可缺省
["Command"]       跟踪完毕之后会在结果显示之前执行的命令,可缺省

这里并不会象Ollydbg那样统计次数。一般这个指令用于单步步入,类似的还有P,单步步过。较有特色的命令是PC和TC,到CALL就自动暂停。当然WinDbg也有能统计的命令。

wt [WatchOptions] [= StartAddress] [EndAddress] 

跟踪,并显示统计结果。
WatchOptions   可缺省,可选参数如下 
-l num 跟踪深度限制,例如限制跟踪深度为10则wt -l10 00402312
        -nc 不显示单独CALL的信息
        -ns 不显示累计信息
        -nw 不显示在跟踪过程中的警告信息
EndAddress    终点地址。当wt在模块或者函数入口点,此项可缺省。

现在我们来看看它的显示效果(从帮助文件中复制过来的:P)

0:000> wt                 函数的开始,现在使用"wt"
Tracing MyModule!myFunction to return address 00401137
 141 [  0]  MyModule!myFunction
  20 [  1]    MyModule!anotherFunction
   5 [  2]      MyModule!deeperFunction
  10 [  1]    MyModule!anotherFunction
   3 [  2]      MyModule!deeperFunction
  30 [  1]    MyModule!anotherFunction
   4 [  0]  MyModule!myFunction

147 Instructions were executed 146(0 from other threads) traces 147 sums

Function Name           Invocations  MinInstr  MaxInstr  AvgInstr

MyModule!deeperFunction        2           3          5         4
MyModule!anotherFunction       1          68         68        68
MyModule!myFunction            1         213        213       213
0 system calls were executed

System Call:

3.  调试示例

首先要说明的是WinDbg中的某些指令是区分大小写的。最后我将以实际调试过程来说明Ollydbg与WinDbg的差别。先介绍一下目标软件,black light beta版。自动查ROOTKIT,使用修改文件名并重新启动系统的方法清除ROOTKIT。国庆节到期,爆破时间限制不难,设断改跳转就可以了,如果写这个,就没什么好写了。用PEID查了一下,没有壳,有TLS表。这个才是这次调试的主角,我希望通过调试来增强对TLSCALLBACK的了解。

先使用Ollydbg载入目标程序,如果你的设置是首次暂停在WINMAIN,并且没有使用任何关于TLS的增强插件,那么你会看到窗口出来了,但是Ollydbg却提示“进程已经终止,退出代码0”。

现在用WinDbg载入程序,选中“debug child processes also”。程序一开始停在系统断点。输入g $exentry.没断成功,落在子进程的系统断点。再次输入g $exentry,产生了一个非法访问的错误。gN $exentry,终于能断在EP了。好了,如果你喜欢用这个软件,你可以爆破它的时间限制了。

Ollydbg与WinDbg的第一次较量,在没有任何插件的情况,WinDbg由于支持子进程调试,使得它在这个特例里要简单一些。

现在我们可以知道,程序在入口点之前就已经被运行,很可能是TLSCALLBACK,并在建立新进程后退出。

-------------------------------------------------------关于多进程调试-------------------------------------------------------------

0:000> |                    ;$查询当前进程数,注意0:000表示当前调试的进程的识别号是0
.  0  id: 46c  create  name: beta.exe
#  1  id: 410  child  name: beta.exe

0:000> | 1 s                 ;$切换到子进程1。S是切换参数,当前状态是默认显示的。
eax=00000000 ebx=7ffdf000 ecx=00010101 edx=ffffffff esi=00000000 edi=00000000
eip=0041e3ec esp=0012ffc4 ebp=0012fff0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246
beta+0x1e3ec:
0041e3ec 6a60            push    60h

1:001>                     ;$切换之后命令提示符变成1:001了。

--------------------------------------------------------------回到正题------------------------------------------------------------

现在我们需要调试TLS处的代码。回到Ollydbg,我用的插件是shoooo大大的WMOS,能显示TLSCALLBACK的首址。为了方便每次都停在TLSCALLBACK,我在入口处设了硬断,重新运行之后,我们可以开始调试了。

0040C7C0    8B4424 08       mov eax,dword ptr ss:[esp+8]          一开始便从初试栈中读取数据
0040C7C4    83EC 54         sub esp,54
0040C7C7    56              push esi                             初始栈-58
0040C7C8    BE 01000000     mov esi,1
0040C7CD    3BC6            cmp eax,esi              比较初始栈+8是否为1
0040C7CF    0F85 E4010000   jnz blbeta.0040C9B9                   没有跳转
0040C7D5    53              push ebx                             初始栈-5c
0040C7D6    8D4424 64       lea eax,dword ptr ss:[esp+64]            EAX=初始栈+8
0040C7DA    50              push eax                             此处是0040c7e2的参数
0040C7DB    FF15 ACA34300   call dword ptr ds:[<&KERNEL32.GetCommandLineW>; 
0040C7E1    50              push eax
0040C7E2    FF15 60A44300   call dword ptr ds:[<&SHELL32.CommandLineToArg>; 
0040C7E8    8BD8            mov ebx,eax                          EBX=参数首址
0040C7EA    397424 64       cmp dword ptr ss:[esp+64],esi             参数长度与1比较
0040C7EE    76 19           jbe short blbeta.0040C809                跳了
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章