OllyDBG分析报告系列(1)---Int3断点

作 者: driverox
时 间: 2008-05-19,16:45
链 接: http://bbs.pediy.com/showthread.php?t=65094

最近学习逆向,对OD本身做了个逆向,也算是一个小小的锻炼吧。呵呵,在这里以分析报告的形式贴出来,请大家批评指正。谢谢。

Ollydbg(以下均简称为OD)中的Int3断点的主要功能是:在需要下断点的执行代码处将原来的代码改成0xCC,程序执行到此处后会报一个Int3异常,由OD捕获并处理。当要执行该行代码时,将原来的代码改回来并执行,然后再恢复断点,这样就不会影响程序的正常运行了。
这里仅描述最常见的功能,其它的有兴趣的话可以分析一把。

先说明一下OD中的两个结构体,在IDA中,声明为如下格式:
t_bpoint用来保存Int断点的相关信息
00000000 t_bpoint        struc ; (sizeof=0x11)
00000000 addr         dd ?                    ; // Address of breakpoint
00000004 dummy      dd ?                    ; // Always 1
00000008 type         dd ?                    ; // Type of breakpoint, TY_xxx
0000000C cmd         db ?                    ; // Old value of command
0000000D passcount    dd ?                    ; // Actual pass count
00000011 t_bpoint        ends
其中:addr为断点的地址,dummy始终为1,type为断点的类型,cmd为要用0xCC替换的指令码,passcount为需要断下的次数,0表示每次都断下。

t_sorted结构体保存了一种有序的数据:
00000000 ; Descriptor of sorted table
00000000 t_sorted        struc ; (sizeof=0x138)
00000000 name[MAXPATH]   db 260 dup(?)     ; char  Name of table, as appears in error messages
00000104 n               dd ?                    ; int  Actual number of entries
00000108 nmax            dd ?                    ; int  Maximal number of entries
0000010C selected        dd ?                    ; int  Index of selected entry or -1
00000110 seladdr         dd ?                    ; ulong  Base address of selected entry
00000114 itemsize        dd ?                    ; int  Size of single entry
00000118 version         dd ?                    ; ulong  Unique version of table
0000011C data            dd ?                    ; void*  Elements, sorted by address
00000120 sortfunc        dd ?                  ; SORTFUNC  Function which sorts data or NULL
00000124 destfunc        dd ?                    ; DESTFUNC  Destructor function or NULL
00000128 sort            dd ?                    ; int  Sorting criterium (column)
0000012C sorted          dd ?                    ; int  Whether indexes are sorted
00000130 index           dd ?                    ; int  Indexes, sorted by criterium
00000134 suppresserr     dd ?                    ; int  Suppress multiple overflow errors
00000138 t_sorted        ends
name是结构体的名称,用来区别不同类型的结构体
n是数组元素的个数
itemsize是数组元素的大小
data 是指向各种数据结构数组的指针,这里使用的是int3断点,所以现在保存的是int3断点数据结构体数组的指针
---------------------------------------------------------------------------------------------------------------------------------

1)Int3断点的设置
int3断点的设置是通过消息来处理的,对应右键点击菜单中的切换,其对应的消息为1E;此外还有热键F2、双击反汇编窗口等也能切换int3断点,转入的函数虽然不同,但是调用设置int3断点的函数都是同一个,就不再举例了。传入相应参数调用函数00419974,改变int3断点,该函数的调用处如下:
004237C8   .  51                    push    ecx    ; |Arg6
004237C9   .  50                    push    eax    ; |Arg5 => 00000002
004237CA   .  6A 00                 push    0      ; |Arg4 = 00000000
004237CC   .  6A 00                 push    0      ; |Arg3 = 00000000
004237CE   .  6A 71                 push    71     ; |Arg2 = 00000071
004237D0   .  52                    push    edx    ; |Arg1 => 0040100C
004237D1   .  E8 9E61FFFF           call    00419974   ; /OLLYDBG.00419974

下面主要来分析上述的00419974这个函数,经过分析可知大致主要流程为:

1.    判断是否配置了“Warn when break not in code”为1,若为1的话,程序会先判断所下断点是否在代码区,不在的话,会显示警告消息,若用户选择继续,则会断下,否则退出;
2.    若没有配置上面的项目,则首先获得断点的类型(即断点类型的高位是否为2,若为2则删除断点,不为2则设置断点),检查该地址的断点是否已经存在,若存在,则删除断点,并退出;
3.    若该地址处无Int3断点,则设置断点,使用的是Setbreakpointext函数,其流程如下:
a)  获得断点在调试进程中实际地址;
b)  判断指令码是否有效(判断规则是:指令码与1F做与运算之后为3或13的时候,说明是断在指令码中间;1D、1E、1F是正常指令码,除此之外,其它的都是无法执行的指令码),无效的话,重新设置CPU窗口,显示错误提示并退出;
c)  在t_sorted结构中查找断点数据;
d)  若t_sorted中不存在该断点,则添加;
e)  判断被调试进程是否在运行状态,若在运行,则把所有的线程都挂起;
f)  读取断点所在地址的内存,若读取成功的话,调用WriteMemory写入0xCC断点(跟入WriteMemory后,发现是调用WriteProcessMemory这个API函数来下Int3断点的);
g)  恢复线程运行;
h)  显示信息在窗口中;
4.  若设置断点成功,则插入name并做其它的一些判断与显示操作,进而退出;

保存现场,提升栈帧空间,用于存放局部变量:
00419974  /$  55         push    ebp
00419975  |.  8BEC       mov     ebp, esp
00419977  |.  81C4 F8FBF>add     esp, -408
0041997D  |.  53         push    ebx
0041997E  |.  56         push    esi
0041997F  |.  57         push    edi
检查OD配置文件中的   “Warn when break not in code”是否为1,1为真,0为假,若上面的配置为0,则跳到下面的处理代码中:
00419980  |.  8B7D 14    mov     edi, dword ptr [ebp+14]
00419983  |.  8B5D 08    mov     ebx, dword ptr [ebp+8]
00419986  |.  833D C4574>cmp     dword ptr [4D57C4], 0  ; 4D57C4--Warn when break not in code
0041998D  |.  74 5E      je      short 004199ED  ;为0则跳转到下面的处理代码
检查传入的参数是否正确:
0041998F  |.  837D 0C 71 cmp     dword ptr [ebp+C], 71
00419993  |.  75 12      jnz     short 004199A7
00419995  |.  837D 10 00 cmp     dword ptr [ebp+10], 0
00419999  |.  75 0C      jnz     short 004199A7
先在t_sorted列表中查找int3断点,找不到返回8,并跳过取得模块信息部分:
0041999B  |.  53         push    ebx
0041999C  |.  E8 D703000>call    _Getbreakpointtype
004199A1  |.  F6C4 02    test    ah, 2    ;检查返回值是否为20h
004199A4  |.  59         pop     ecx
004199A5  |.  75 46      jnz     short 004199ED  ;不是则跳过取得模块信息部分
取得模块信息,并检查是否取得,若取得失败则跳转到显示断点错误消息分支:
004199A7  |>  53         push    ebx                       ; /Arg1
004199A8  |.  E8 6B44040>call    _Findmodule               ; /_Findmodule
004199AD  |.  59         pop     ecx
004199AE  |.  8BF0       mov     esi, eax
004199B0  |.  85C0       test    eax, eax  ;检查是否得到模块信息
004199B2  |.  74 0F      je      short 004199C3  ;没有得到则跳转到下面错误显示分支
004199B4  |.  3B5E 0C    cmp     ebx, dword ptr [esi+C]
004199B7  |.  72 0A      jb      short 004199C3
004199B9  |.  8B56 0C    mov     edx, dword ptr [esi+C]
004199BC  |.  0356 10    add     edx, dword ptr [esi+10]
004199BF  |.  3BDA       cmp     ebx, edx
004199C1  |.  72 2A      jb      short 004199ED
显示断点错误消息,若用户选择Yes则继续,否则退出:
004199C3  |>  68 2421000>push    2124                       &nb
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值