前言
1.《加密与解密》第二章内容为动态调试,关于软件的使用方式以及快捷键的区别,书中有详细的介绍,并且网上也有很多资料,故本篇博客不详细记述
2. 关于《加密与解密》配套文件的获取:请按照书中“前言”的提示进行操作。由于版权问题,这篇博客不提供下载链接
3. 书中使用的软件为OllyDbg
。 我个人分析时候使用x32Dbg x64Dbg
。虽然使用的软件不同,但是分析操作区别不大
分析TrackME.exe
首先打开TraceMe.exe
,观察软件功能
接下来增加用户名的字数,再试试
程序的流程图如下
设置程序断点
接下来用x32Dbg
打开TraceMe.exe
(书中使用的是OllyDbg
)
4013A0这一列对应虚拟地址
虚拟地址:在一般情况下,同一程序的同一条指令在不同系统环境下此值相同。55这一列对应机器码
机器码:就是CPU执行的机器代码。
push ebp
这一列对应汇编指令
汇编指令:与机器码对应的程序代码。(这也是“汇编语言”这门课要重点学习的内容)其他窗口的内容,书中有详细介绍
x32Dbg
自动停止在程序入口点(红色的AddressOfEntryPoint
),接下来对程序打断点,目的是当用户输入文本后,程序暂停运行,接下来的每一步操作由用户控制。
那么功能为"用户输入文本"的函数是啥呢?书中提供了两个API函数。GetDlgltemText
函数以及GetWindowText
以下是这些函数的文档
IpString
是要获取的文本的地址
书中提供了两种定位函数的方法
- 按下
<ctrl-g>
快捷键,输入目标表达式(GetDlgltemText)或者目标地址 - 按下
<ctrl-n>
,可以看到程序调用的所有API函数,接下来可以顺利找到目标函数了
定位后,按下f2
打下断点,之后运行程序,每一次程序调用目标函数时,都会停止运行,等待用户下一步操作
动态调试程序
为了方便,先记录一下会使用的快捷键
快捷键 | 功能 |
---|---|
f7 | 单步调试,遇到函数调用,会进入函数内部 |
f8 | 单步调试,遇到函数调用也会执行,不过会直接跳到执行后的语句 |
ctrl+f9 | 程序会一直运行,直到遇见第一个返回语句 |
alt+f9 | 若进入系统领空,此命令可瞬问回到应用程序领空 |
alt+b | 打开断点 |
调试顺序如下:首先打开程序
按下f9,程序运行到入口
再按下f9(如果卡住就多按几次),程序中断,出现窗口图标
输入用户名以及序列号,按下check,程序就能继续运行了
程序运行到GetDlgItemText函数,由于打下断点,此时程序就会停下
接下来可以看看调用函数的形式参数了。我们先让程序执行到用户领空,结果如下
这里涉及到一点汇编语言的知识:push
作用是将数据压入栈中,而函数调用时参数从右到左压栈,结合上GetDlgltemText
函数原型,能够得到形参的值
004011AE | 6A 51 | push 51 | int nMaxCount
004011B0 | 50 | push eax | LPTSTR lpString
004011B1 | 6A 6E | push 6E | int nIDDlgItem
004011B3 | 56 | push esi | HWND hDlg
因为在x86架构中,函数的返回值经常放在eax寄存器中。 所以eax寄存器会存放GetDlgltemText
函数的返回值,也就是用户名的长度。分析接下来的汇编代码
需要注意mov ebx , eax
,它将eax寄存器的值复制到ebx中,ebx现在存放用户名的长度,eax存放序列号的长度
这段代码执行两个比较任务:
- 如果用户名的第一个字节为0,跳转到401248地址。
- 将ebx的长度与5比较,如果小于5,程序就跳转到401248地址。
之后使用lea eax , dword ptr ss:[esp+A0]
,将序列号的值赋值给eax寄存器。接下来就是对这些值进行判断了
如下图所示,401340地址的函数判断结果会放在eax寄存器中,test eax eax
会检查eax寄存器的值是0还是正数,如果是0,那么下一条汇编代码会实现跳转,导致注册失败
原理:当
eax
为0 ,test
语句会将ZF标志位置为1。而ZF为1时,满足je
语句跳转的条件。
也就是说:如果我们将ZF标志位置为0,那么je语句就不会跳转。
或者可以将je语句变成空指令,从根源上解决问题
原理解释明白了,接下来理解书中的内容应该没有问题了:)
介绍各种断点
-
INT 3断点
这是很常用的断点,在x32dbg
中,可以使用f2
或者右键左边灰色的圆点,如果对应地址变红,就表示成功打下断点
这个断点的优点是数量没有限制,缺点是改变了程序的机器码,容易被检测到
因为这个断点会将首字节改为CC , 所以又被称为CC断点 -
硬件断点
硬件断点与DRx寄存器有关,这个寄存器本身的特点决定了只能同时存在4个硬件断点,但是由于断点不会修改机器码的首字节,所以更难被检测到
以下是打下硬件断点的方法:鼠标右键–>断点–>设置硬件断点
硬件断点的颜色粉粉的,和CC断点颜色不一样。 -
内存断点
设置内存访问断点或内存写入断点,原理是对所设的地址赋予不可访问/不可写属性,这样当访问/写入的时候就会产生异常。x32dbg捕获异常后,比较异常地址是不是断点地址,如果是就中断,用户继续操作
可以阅读一下其他大佬写的,使用内存断点的实战:x64dbg入门
-
消息断点
Windows本身是由消息驱动的,如果调试时没有合适的断点,可以尝试使用消息断点。当某个特定窗口函数接收到某个特定消息时,消息断点将使程序中断。消息断点与INT3断点的区别在于:
INT3断点可以在程序启动之前设置,消息断点只有在窗口被创建之后才能被设置并拦截消息。
看雪上大佬写的消息断点实战 -
条件断点
在调试过程中,我们经常希望断点在满足一定条件时才会中断,这类断点称为条件断点。
关于x32dbg
条件断点的使用,可以阅读官方文档
本文结束
非常厉害猫猫♡,这使我嘴角上翘♡,爱♡来♡自♡瓷♡器♡
后记
- 当看到
x64dbg
调试器的时候,才发现书中有介绍这个软件,一开始我以为书中只有介绍OD
。。。。 Windbg
的内容太多,考虑到文章篇幅,就不详细介绍了