我的断点心得帮初学者进阶.docx

上传人:b****6 文档编号:8684691 上传时间:2023-02-01 格式:DOCX 页数:13 大小:86.25KB
下载 相关 举报
我的断点心得帮初学者进阶.docx_第1页
第1页 / 共13页
我的断点心得帮初学者进阶.docx_第2页
第2页 / 共13页
我的断点心得帮初学者进阶.docx_第3页
第3页 / 共13页
我的断点心得帮初学者进阶.docx_第4页
第4页 / 共13页
我的断点心得帮初学者进阶.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

我的断点心得帮初学者进阶.docx

《我的断点心得帮初学者进阶.docx》由会员分享,可在线阅读,更多相关《我的断点心得帮初学者进阶.docx(13页珍藏版)》请在冰豆网上搜索。

我的断点心得帮初学者进阶.docx

我的断点心得帮初学者进阶

我的断点心得帮初学者进阶

∙【文章标题】:

 我的断点心得帮初学者进阶

【文章作者】:

 书呆彭

【使用工具】:

 OD,MSDN,VC

【作者声明】:

 本文完全是个人的心得与体会,看到许多初学者还在苦苦寻找“字符串”和“关键跳”,特写此文,其中错误和不当之处,欢迎大家多多批评指正。

------------------->8-------------------------------------------------------------

【详细过程】

  

  在正文开始之前,先说几句。

  

  要写一篇文章是很累的,要打字,为了效果好还要截图、排版等。

  

  而且写这些东西是没有报酬的,属于义务劳动。

  

  我只希望能对出学者有所帮助,为论坛做点贡献。

  

  我也希望读者能仔细地把文章看完。

  

  看完后有什么意见就说什么。

  

  我不希望看的人随便把网页往下一拉,顺手回复个“好”,“顶”,“支持”之类的。

  

  对了,还有“先顶后看”的。

  

  我觉得,要先看过了,再回复。

有话要说就回,没什么说的可以不回。

  

  我的意思就是,技术不同于灌水。

  

  

  ---------------->8------------------------------------------------------------

  

  

  开始。

  

  本文不讲脱壳,不讲算法,也不讲anti-anti,主要讲一讲如何用OD定位到一个程序的关键代码位置。

  

  

  由于解密技术的发展,带动了软件加密的发展。

现在已经很难像两年前,或者更早,那样,用“W32Dsm->参考->字符串参考”的方法来定位程序的关键代码点了。

  

  但是还是有很多人抱着“字符串”这个“法宝”不放。

不愿意,或者也可能没有找到方法,去学习一下更有效的定位关键代码的动态方法:

断点。

  

  甚至有时根据别人的指点用API断点已经到达关键代码了,却又习惯地去寻找“字符串”。

  

  

  本人不才,算不上什么高手,但是我在逆向研究程序时,几乎没有使用过字符串的方法来定位关键代码。

  

  我记得两年前,很多流行的破文中都说,先静态,后动态。

  

  但我恰恰相反。

在跟踪代码时我总是先动态定位代码,然后再阅读静态的反汇编结果。

  

  并且,在分析代码时,我常常是“动静结合,先猜后验证”的方法,以前我写过一个CRACKME的分析,讲过这个,就不说了。

  

  

  

  

  断点,BreakPoint,顾名思义,就是要正在运行的程序break的点。

在Intel x86体系中,大家都知道断点是一种异常,然后通过异常处理的机制,让调试器获得控制权。

  

  下面我的描述,总是假设:

  

  1.程序代码没有被加密,通常就是指加壳。

  

  2.程序中没有anti-debug

  

  3.程序是本机代码,不是虚拟机伪指令,如VB

  

  

  

  

  首先,什么是关键代码?

  

  我们知道一个完整的程序,所包含的代码是海量的,我们虽然有反汇编工具,但不可能把所有的代码都去看一下。

  

  我们所说的关键代码,通常就是指包含有注册算法和有效性验证的程序代码。

  

  我们下断点的目的,是找到关键代码“附近”的代码,从而定位到最终的关键代码。

  

  

  通常,关键代码都具有这样的结构:

  

  1.读取用户的输入

  

  2.经过一定的计算、验证

  

  3.显示(或不显示,仅存储)验证结果。

  

  其中,2是“真正关键”的代码,而1和3就是我说的“附近”的代码。

  

  

  在Windows下的应用程序,2完全自主的,我们没办法,但1和3(也就是输入和输出)无论如何也必须通过某种形式的操作系统调用才能实现。

所以,API断点几乎是通用的办法。

  

  而难点,就在于我们下断点的技巧。

  

  

  先说思路1,从输入角度来下。

学过一点C语言的人知道,在控制台下,获取用户输入是从stdin文件中读取的。

而win32窗口应用程序怎么获得用户输入呢?

  

  我们最常见的情况,是从编辑框(Edit)控件中输入信息。

  

  这种情况下程序要获取用户的输入,也就是获取编辑框的文字。

通过什么途径?

这里就需要一些编程的基础知识了。

(所以我总强调编程是逆向的基础)

  

  GetWindowText()和GetDlgItemText()是最常用的两个API。

至于A还是W,试试就知道了。

  ---------------->8------------------------------------------------------------

  

  例1:

  

  下载

  

  

  

  我们用OD载入,bp GetDlgItemTextA,F9运行。

点check,被OD断下了。

看下堆栈窗口中给出的提示:

  

  

∙代码:

∙  0013FA48   004010B0  /CALL 到 GetDlgItemTextA 来自 010.004010AB

∙  0013FA4C   002108A2  |hWnd = 002108A2 ('Pusillus Crackme 1.0',class='#32770')

∙  0013FA50   00000BB8  |ControlID = BB8 (3000.)

∙  0013FA54   00403044  |Buffer = 010.00403044

∙  0013FA58   0000000A  \Count = A (10.)

∙  

∙  

  是不是我们要找的呢?

你当然可以执行到返回,然后看缓冲区Buffer = 010.00403044的内容是不是自己输入的。

  

  我给出另一种方法:

ControlID == 0xbb8,在OD中转到“窗口”窗口(有点绕),看到

  

  

∙代码:

∙  Windows

∙  句柄           标题                              父窗口     WinProc    ID         风格       扩展风格   线程       ClsProc    类

∙  002108A2       Pusillus Crackme 1.0              Topmost                          94C800C4   00010101   主          7D96A3F2   #32770

∙  K00140878                                        002108A2              00000BB8   50010080   00000204   主          7D9637BF   Edit

∙  K0019088A      Default IME                       002108A2                         8C000000              主          7D9A0638   IME

∙  IE0023085A     M                                 0019088A                         8C000000              主          FFFF08A1   MSCTFIME UI

∙  E0020085C      Check                             002108A2              00000BB9   50010001   00000004   主          7D960F28   Button

∙  

∙  

  我们看到ID为0xBB8的控件是唯一的一个Edit控件。

  这个ID是程序作者定义的,对于一个程序,每个控件的ID是不变的。

  

  这个CrackMe非常简单,所以返回到用户代码后就是“关键”代码了。

  

  

  

  ---------------->8------------------------------------------------------------

  例2:

  

  下载

  

  

  

  这个例子是VC7写的,unicode程序,所以这回我们下bp GetDlgItemTextW,随便输入,点确定。

  

  咦,没断到,直接弹出了错误提示。

如图:

  

  

  

  我们换另一个试试,bp GetWindowTextW,结果发现我们无法切换到CrackMe的界面了,只要一切换就被OD断下来。

  

  第一次中断时,堆栈参数:

  

∙代码:

∙  0013F6FC   7DBF9A40  /CALL 到 GetWindowTextW 来自 COMCTL32.7DBF9A3A

∙  0013F700   001500DC  |hWnd = 001500DC ('确定',class='Button',parent=000E00AE)

∙  0013F704   00269050  |Buffer = 00269050

∙  0013F708   00000003  \Count = 3

∙  

∙  

  F9,又中断到这里

  

  

∙代码:

∙  0013F960   7DBF73F4  /CALL 到 GetWindowTextW 来自 COMCTL32.7DBF73EE

∙  0013F964   000C00CA  |hWnd = 000C00CA ('用户名:

',class='Static',parent=000E00AE)

∙  0013F968   00269050  |Buffer = 00269050

∙  0013F96C   00000005  \Count = 5

∙  

∙  

  再F9,

  

  

∙代码:

∙  0013F960   7DBF73F4  /CALL 到 GetWindowTextW 来自 COMCTL32.7DBF73EE

∙  0013F964   002C01DC  |hWnd = 002C01DC ('注册码:

',class='Static',parent=000E00AE)

∙  0013F968   00269050  |Buffer = 00269050

∙  0013F96C   00000005  \Count = 5

∙  

∙  

  再F9,就运行了。

我们看一下,为什么会中断呢?

  

  原来是因为系统要绘制“确定”按钮。

  

  不过,上面几次中断,并没有获取编辑框文字。

  

  这就引出了今天要讲的另一个技巧:

条件断点。

  

  我们希望只有在读取用户输入内容时才中断。

  

  先来到OD的“窗口”窗口:

  

  

∙代码:

∙  Windows

∙  句柄           标题                              父窗口     WinProc    ID         风格       扩展风格   线程       ClsProc    类

∙  000E00AE       MFc7                              Topmost                          94C800CC   00050101   主          7D96A3F2   #32770

∙   000C00CA      用户名:

                          000E00AE              FFFFFFFF   50020000   00000004   主          FFFF0743   Static

∙   001500DC      确定                              000E00AE              00000001   50010001   00000004   主          FFFF074B   Button

∙   002C01DC      注册码:

                          000E00AE              FFFFFFFF   50020000   00000004   主          FFFF0743   Static

∙   0036011E                                        000E00AE              000003E8   50010080   00000204   主          FFFF06AB   Edit

∙   004101E8                                        000E00AE              000003E9   50010080   00000204   主          FFFF06AB   Edit

∙   009E0104      Default IME                       000E00AE                         8C000000              主          7D9A0638   IME

∙    002501F6     M                                 009E0104                         8C000000              主          FFFF07D9   MSCTFIME UI

∙  

∙  

  我们看到有两个Edit控件,我们随便取其中一个,比如0036011E,记下这个句柄。

你可以根据你机器上显示的值来确定。

  注意,这个窗口句柄是在窗口创建时由系统分配的,每次运行程序时的值可能不一样。

但是窗口一旦创建,那么在它销毁前它的句柄是保挂不变的。

  再回到反汇编窗口,在GetWindowTextW这行按Shift+F2,弹出如下条件断点对话框:

有朋友说这一句不好理解,改成下面这样:

  回到反汇编窗口,按Ctrl+G,输入GetWindowTextW,来到这个API的代码处,然后按Shift+F2,弹出编辑断点条件的对话框:

  

  

  

  我们看一下堆栈,窗口句柄是第一个参数,位于[ESP+4],于是我们输入[ESP+4]==0x36011E,确定。

  

  现在我们再运行程序,输入点什么,点确定,OD给断下来了。

堆栈中看看,

  

  

∙代码:

∙  0013F568   0040C544  /CALL 到 GetWindowTextW 来自 009.0040C53E

∙  0013F56C   0036011E  |hWnd = 0036011E (class='Edit',parent=000E00AE)

∙  0013F570   00899980  |Buffer = 00899980

∙  0013F574   00000005  \Count = 5

∙  

∙  

  我们看到返回地址就在程序EXE模块中,所以直接返回,看一下,是这么一副模样。

  

  

∙代码:

∙  0040C516  /$  8BFF          MOV     EDI, EDI

∙  0040C518  |.  55            PUSH    EBP

∙  0040C519  |.  8BEC          MOV     EBP, ESP

∙  0040C51B  |.  56            PUSH    ESI

∙  0040C51C  |.  8BF1          MOV     ESI, ECX

∙  0040C51E  |.  837E 50 00    CMP     DWORD PTR DS:

[ESI+50], 0

∙  0040C522  |.  75 2F         JNZ     SHORT 009.0040C553

∙  0040C524  |.  FF76 20       PUSH    DWORD PTR DS:

[ESI+20]            ; /hWnd

∙  0040C527  |.  FF15 20965200 CALL    DWORD PTR DS:

[<&USER32.GetWindow>; \GetWindowTextLengthW

∙  0040C52D  |.  8D48 01       LEA     ECX, DWORD PTR DS:

[EAX+1]

∙  0040C530  |.  51            PUSH    ECX                              ; /Count

∙  0040C531  |.  8B4D 08       MOV     ECX, [ARG.1]                     ; |

∙  0040C534  |.  50            PUSH    EAX                              ; |/Arg1

∙  0040C535  |.  E8 6BA2FFFF   CALL    009.004067A5                     ; |\009.004067A5

∙  0040C53A  |.  50            PUSH    EAX                              ; |Buffer

∙  0040C53B  |.  FF76 20       PUSH    DWORD PTR DS:

[ESI+20]            ; |hWnd

∙  0040C53E  |.  FF15 24965200 CALL    DWORD PTR DS:

[<&USER32.GetWindow>; \GetWindowTextW

∙  0040C544  |.  8B4D 08       MOV     ECX, [ARG.1]

∙  0040C547  |.  6A FF         PUSH    -1                               ; /Arg1 = FFFFFFFF

∙  0040C549  |.  E8 6693FFFF   CALL    009.004058B4                     ; \009.004058B4

∙  0040C54E  |.  5E            POP     ESI

∙  0040C54F  |.  5D            POP     EBP

∙  0040C550  |.  C2 0400       RETN    4

∙  0040C553  |>  8B4E 50       MOV     ECX, DWORD PTR DS:

[ESI+50]

∙  0040C556  |.  8B01          MOV     EAX, DWORD PTR DS:

[ECX]

∙  0040C558  |.  5E            POP     ESI

∙  0040C559  |.  5D            POP     EBP

∙  0040C55A  \.  FFA0 8C000000 JMP     DWORD PTR DS:

[EAX+8C]

∙  

∙  

∙  

  看来这是一个包装(Wrapper)函数,我们继续返回,就来到了“关键代码”了(不贴了)。

  

  

  ---------------->8------------------------------------------------------------

  例3:

  

  下载

  

  

  

  再看这个,是某版本的易语言的。

bp GetWindowTextA,同例2一样,我们切换不到程序界面了。

按上面的方法,下个条件断点,OK,我们到了:

  

  

∙代码:

∙  0013F110   100AE3BA  /CALL 到 GetWindowTextA 来自 krnln.100AE3B4

∙  0013F114   004701D8  |hWnd = 004701D8 (class='Edit',parent=001100CA)

∙  0013F118   02367AF0  |Buffer = 02367AF0

∙  0013F11C   00000005  \Count = 5

∙  

∙  

  可是这个返回点是在krnln模块中,并不是EXE当中啊,怎么办?

  

  我们先回来krnln领空。

  

  下面我来讲今天的第3个技巧:

RUN跟踪。

不熟悉的人先去看看OD的说明书,照着说明书将相关选项设置好,否则可能不起作用。

  

  使用工具之前阅读说明书是一个好习惯。

  

  我们Alt+E,看一下EXE模块的地址:

  

  

∙代码:

∙  Executable modules, 条目 0

∙   基址=00400000

∙   大小=0001F000 (126976.)

∙   入口=00403831 015.<模块入口点>

∙   名称=015

∙   路径=F:

\Debugee\Crack Me\015.exe

∙  

∙  

  好,我们按Ctrl+T,选中“EIP位于范围内”,后面的范围就填整个模块的范围吧,无所谓,见图:

  

  

  

  确定后,我们按Ctrl+F11(至于F11还是F12,视情况而定,这里本例仅为一个特例),看到什么了?

OD停在了这里:

  

  

∙代码:

∙  0040993E    DD45 F4         FLD     QWORD PTR SS:

[EBP-C]

∙  00409941    DC45 E8         FADD    QWORD PTR SS:

[EBP-18]

∙  00409944    DC05 04914000   FADD    QWORD PTR DS:

[409104]

∙  0040994A    DD5D E0         FSTP    QWORD PTR SS

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 日语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1