发新话题
打印

Ollydbg教程之WinDbg用户态调试

Ollydbg教程之WinDbg用户态调试

  现在可以知道call dword ptr ss:[ebp+8]的最后是调用TLSCALLBACK,所以结束时必须代替系统释放堆栈,通过这次调试,我们可以用汇编写TLSCALLBACK,并把ANTI DEBUG代码放在这里,结果不言而喻。
  如果在WinDbg中,应该怎么做。为了让WinDbg看起来容易用一点,我又写了个SCRIPT,它在附件里的名字是gs。复制到程序安装目录,输入$><GS,然后按ENTER。如果程序有TLSCALLBACK,将会断在那里(用了BP设断,然后G的方法,以后也会自动断在那里),没有就断在EP。<gs,然后按ENTER。如果程序有TLSCALLBACK,将会断在那里(用了bp设断,然后g的方法,以后也会自动断在那里),没有就断在EP。
r @$t0=@$peb+8
r @$t0=poi(@$t0)                     ;$通过peb获得基址
r @$t1=@$t0+3c
r @$t1=poi(@$t1)+@$t0
r @$t1=@$t1+c0
r @$t1=poi(@$t1)            ;$取得TLS表基址
.if (@$t1!=0)
}
.if (@$t0!=0)
  现在程序停在入口点了。我用OD的时候习惯静态分析,然后分析到我感兴趣的地方,设断,F9,看寄存器看堆栈。这在WinDbg中不可能,它的反汇编功能真的不怎么样。例如我单步到这里:
call dword ptr [beta+0x3a3ac (0043a3ac)] ds0043a3ac=

  才会显示这个是API调用,在反汇编窗口里面只是单纯显示call dword ptr [beta+0x3a3ac (0043a3ac)]。你必须跟进那个call,调用栈才有反应,还不如直接用db esp查看堆栈。而且进去之后也不会提示那些是什么参数。所以我一般在使用的时候,同时打开MSDN的搜索页面,当然还有IDA。
0040c7cf 0f85e4010000 jne beta+0xc9b9 (0040c9b9) [br=0]

  后面br=0代表没有跳转成功,如果是1,那么就是成功跳转。当然WinDbg也有方便的地方。在Ollydbg的例子中,我是下拉反汇编窗口直接看后面用什么API。而在WinDbg中,你可以使用pc命令,现在直接自动单步到CALL,然后停下来,而不需要关心在这中间遇到多少个条件跳转。
  第二次较量,在进行代码分析时WinDbg要逊色一点,它的SCRIPT功能倒是不错,可以弥补一些差距。
  关于目标程序:现在我们知道程序通过参数/q启动一个新的进程。用Ollydbg和WinDbg带参数/q重新载入程序。开始的时候,我们曾经用WinDbg双进程调试过,当时新进程产生了一个错误,忽略错误运行之后,我们能停在EP。我希望知道系统是怎么处理这个错误的。
  Ollydbg中按F9到达错误处,然后按SHIFT+F7进入SEH链中的第一个例程
  WinDbg中按F5到达错误处,然后还是SCRIPT,对应附件中的lseh和disasm这两个文件。一定要复制到安装目录下。$><<LSEH使用SCRIPT,效果如图:seh使用SCRIPT,效果如图:
      [img]http://cms.yesky.com/imagelist/2008/010/317a685va2p7.jpg[/img]

      这个SCRIPT的功能是列举所有SEH例程,可以下断,也可以反汇编该例程的前10条命令。我用DML做了一个简单的可视化界面。显然可以做一个界面,通过点鼠标来单步之类的,这样HOOK 快捷键ANTI DEBUG就不可行了。如果你点一下反汇编,你会发现系统DLL里面有很多符号标记,相反Ollydbg却认不出来。也许Micro$oft开发WinDbg就是鼓励别人调试它的产品。
[table=95%][tr][td]r @$t0=poi(@$teb)                                ;$取得SEH链表的第一个元素
.for (r $t3 = 0; @$t0 !=-1; r $t3 = @$t3 + 1)
.if (@$t0=-1)

反汇编的链接命令是使用disasm这个SCRIPT,并以@$t2来传递参数,下面来看看它的代码:

u @$t2 l10                                              ;$反汇编@$t2指向的地址
.printf /D "<link cmd="$><Lseh">返回</link>n"             ;$使用lseh[/td][/tr][/table]
  这有点花俏,我写了另外一个SCRIPT,对应附件中的SEH。它的功能是在第一个SEH例程下断了。gN,断下来。
  我们看到处理错误的函数在系统区,由于忽略错误能回到EP,也就是说该系统SEH例程可以处理错误,然后返回到某处用户代码,于是我在WinDbg中使用guc这个SCRIPT,运行到用户代码为止,结果窗体出来了还没停下来。现在换Ollydbg取消了入口处的断点之后,使用执行到用户代码,效果跟WinDbg一样。重新开始,经过层层跟踪之后发现出问题的地方是INT 2E,单步过去就变成运行。看来R3调试器跟我一样,不认识那东西。也就是说,可以用INT 2E等调用来对抗模拟跟踪,当然这需要你掌握它的使用。至于TLSCALLBACK,或者我们可以假定它出错,系统就会把控制权交回EP,有待实践证明或高手调试证明了。
  第三次较量,算是平手了。
  最后简单的总结一下WinDbg在R3下的表现
  1. 强大的script功能,适用于自动化完成一些任务。
  2. DML,提供一个简陋的可视化界面与用户进行简单的互动。
  3. HTML文件输出支持,这是我在学习DML的过程中发现的。“.logopen”建立HTML文件,“.printf”输出HTML标记,“.logclose”关闭文件。
  4. 适合调试系统内核,它对内核的符号标记比Ollydbg要多。为了获得更多WINDOWS内核的符号支持,你需要通过菜单"File=>Symbol File Path"然后输入
  “srv*%SystemRoot%symbols*http://msdl.microsoft.com/download/symbols
  注意:此命令行使WinDbg到micro$oft的网站下载符号文件,由于网速以及符号文件库比较大的关系,会导致初次使用时较费时(我这里校园网,等了几分钟)。此外假如程序也加载了一些非micro$oft的模块,WinDbg也会尝试在该网站查找,因此假如你对内核不感兴趣,请把路径设为空格。

TOP

发新话题