注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

古城风~~~

竹密无妨溪水过,天高不碍白云飞。这天下总有一份是属于我古城的天地!

 
 
 

日志

 
 

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

2008-06-10 12:45:21|  分类: 反编译(OllyDBG |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最近学习逆向,对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                              ; /Style = MB_YESNO

004199C8  |.  68 40274B0>push    004B2740                           ; |Title

004199CD  |.  68 C3284B0>push    004B28C3                          ; |Text

004199D2  |.  8B0D 7C3B4>mov     ecx, dword ptr [4D3B7C]              ; |

004199D8  |.  51         push    ecx                               ; |hOwner

004199D9  |.  E8 385B090>call    <jmp.&USER32.MessageBoxA>           ; \MessageBoxA

004199DE  |.  8BF0       mov     esi, eax

004199E0  |.  83FE 06    cmp     esi, 6

004199E3  |.  74 08      je      short 004199ED

004199E5  |.  83C8 FF    or      eax, FFFFFFFF  ;返回-1

004199E8  |.  E9 8403000>jmp     00419D71  ;跳转到结束处

得到该地址int3断点的属性,如果已经设置了int3断点,则将其删除并跳转到结束处;若没有设置,则跳过删除部分代码:

004199ED  |>  837D 0C 71 cmp     dword ptr [ebp+C], 71

004199F1  |.  0F85 24020>jnz     00419C1B

004199F7  |.  837D 10 00 cmp     dword ptr [ebp+10], 0

004199FB  |.  75 20      jnz     short 00419A1D

004199FD  |.  53         push    ebx

004199FE  |.  E8 7503000>call    _Getbreakpointtype  ;得到该地址的int3断点的属性

00419A03  |.  F6C4 02    test    ah, 2    ;比较是否已经设置了int3断点

00419A06  |.  59         pop     ecx

00419A07  |.  74 14      je      short 00419A1D  ;若没有设置则跳过删除断点的代码

00419A09  |.  6A 00      push    0                         ; /Arg3 = 00000000

00419A0B  |.  8D53 01    lea     edx, dword ptr [ebx+1]    ; |

00419A0E  |.  52         push    edx                       ; |Arg2

00419A0F  |.  53         push    ebx                       ; |Arg1

00419A10  |.  E8 03FBFFF>call    _Deletebreakpoints        ; \_Deletebreakpoints

00419A15  |.  83C4 0C    add     esp, 0C

00419A18  |.  E9 4103000>jmp     00419D5E

在这里有对传入参数的一个比较,但是测试时无法得到0以外的值,所以无法确定该参数的作用,这样也无法测试00419A6D后面的代码所表示的意义:

00419A1D  |>  837D 10 00 cmp     dword ptr [ebp+10], 0

00419A21  |.  75 4A      jnz     short 00419A6D

这里就是设置int3断点的函数,将地址传入即可:

00419A23  |.  6A 00      push    0                         ; /Arg4 = 00000000

00419A25  |.  6A 00      push    0                         ; |Arg3 = 00000000

00419A27  |.  68 0002020>push    20200                     ; |Arg2 = 00020200

00419A2C  |.  53         push    ebx                       ; |Arg1

00419A2D  |.  E8 2EFBFFF>call    _Setbreakpointext         ; \_Setbreakpointext

00419A32  |.  83C4 10    add     esp, 10

设置完int3断点后,删除int3断点处的name属性为38h、3Ch、3Bh以及30h的name,然后跳转到结束广播处:

00419A35  |.  8D73 01    lea     esi, dword ptr [ebx+1]

00419A38  |.  6A 38      push    38                        ; /Arg3 = 00000038

00419A3A  |.  56         push    esi                       ; |Arg2

00419A3B  |.  53         push    ebx                       ; |Arg1

00419A3C  |.  E8 87B5040>call    _Deletenamerange          ; \_Deletenamerange

00419A41  |.  83C4 0C    add     esp, 0C

00419A44  |.  6A 3C      push    3C                        ; /Arg3 = 0000003C

00419A46  |.  56         push    esi                       ; |Arg2

00419A47  |.  53         push    ebx                       ; |Arg1

00419A48  |.  E8 7BB5040>call    _Deletenamerange          ; \_Deletenamerange

00419A4D  |.  83C4 0C    add     esp, 0C

00419A50  |.  6A 3B      push    3B                        ; /Arg3 = 0000003B

00419A52  |.  56         push    esi                       ; |Arg2

00419A53  |.  53         push    ebx                       ; |Arg1

00419A54  |.  E8 6FB5040>call    _Deletenamerange          ; \_Deletenamerange

00419A59  |.  83C4 0C    add     esp, 0C

00419A5C  |.  6A 30      push    30                        ; /Arg3 = 00000030

00419A5E  |.  56         push    esi                       ; |Arg2

00419A5F  |.  53         push    ebx                       ; |Arg1

00419A60  |.  E8 63B5040>call    _Deletenamerange          ; \_Deletenamerange

00419A65  |.  83C4 0C    add     esp, 0C

00419A68  |.  E9 F102000>jmp     00419D5E      ;跳转到结束广播处

这部分省略的代码无法得知其调用的必要条件,不过里面的内容跟上面相似,都是通过判断来设置int3断点,这里就不再详细说明了:

……

……

向子窗体发送广播,要求更新所有子窗口:

00419D5E  |>  6A 00      push    0                         ; /Arg3 = 00000000

00419D60  |.  6A 00      push    0                         ; |Arg2 = 00000000

00419D62  |.  68 7404000>push    474                       ; |Arg1 = 00000474

00419D67  |.  E8 0807040>call    _Broadcast                ; \_Broadcast

00419D6C  |.  83C4 0C    add     esp, 0C

最后返回0,并且恢复现场:

00419D6F  |.  33C0       xor     eax, eax

00419D71  |>  5F         pop     edi

00419D72  |.  5E         pop     esi

00419D73  |.  5B         pop     ebx

00419D74  |.  8BE5       mov     esp, ebp

00419D76  |.  5D         pop     ebp

00419D77  \.  C3         retn

  评论这张
 
阅读(476)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017