版本:OllyDbg v1.10 下载地址:http://www.ollydbg.de/
TraceMe.exe 下载地址:http://download.csdn.net/download/situxiye/3075791
OD界面介绍
1.分析TraceMe.exe
界面
功能:验证序列号是否正确
验证流程:
输入用户名和序列号–>调用GetDlgItemTextA函数(获取对话框文本)–>计算序列号–>调用lstrcmp函数(将计算结果与用户输入作比较)–>正确/错误
2.加载前设置
菜单Options/Debugging options/Event
设置暂停点:主模块(文件)的入口点。
3.加载.exe到OD
方法一:直接加载
菜单File/Open,或快捷键F3 (支持带参数打开:打开对话框中Arguments栏中输入参数行)
实际是调用CreateProcess创建一个用来调试的进程
方法二:附加,即调试正在运行的程序
菜单File/Attach,选中进程即可
若是隐藏进程,获得隐藏进程的pid,在控制台 C:\OllyDbg.exe -p pid值
4.快捷键
F8单步执行,跳过CALL和LOOP
F7单步执行,跟进CALL和LOOP
Ctrl+F9,跳出CALL调用的函数
Alt+F9,跳出系统API函数
F9,程序运行
F12,暂停程序(进入死循环时)
F4,执行到光标所在的行
F2设置断点(双击Hex dump也可)
Alt+B打开断点窗口,管理断点
反汇编面板:Ctrl+G查找.test区块中expression–>双击修改指令
数据面板:Ctrl+G查找.data区块中expression–>选中数据,Binary–>Edit修改十六进制数或字符串(字符串要以00h结尾)
5.调试
1、加载后,目标程序会暂停在Ntdll.dll的DbgBreakPoint处,按一下F9让程序继续运行。
(Ntdll.dll:Windows系统从ring3到ring0的入口,win32 API 最终都是调用ntdll.dll中的函数实现的)
2、找到GetDlgItemTextA(在Address栏),设置断点
注:鼠标点击选中反汇编面板
方法一:直接查找:Ctrl + G -->输入函数名
(因为事先不知道程序具体调用了什么函数,所以要多试几次,找到相应的函数)
方法二:输入表查找:Ctrl+N -->在name栏找到函数名
3、输入用户名和序列号,点击check,程序中断。
4.分析
Comment栏,即注释,很详细
GetDlgItemTextA的四个参数:对话框句柄,控件标识(ID号),缓冲区指针,缓冲区最大字符数
(参考Win32.API手册,搞清定义中参数)
(标准调用约定:从右到左顺序入栈(push),被调用者清理栈中参数,返回值放在eax中)
(C调用约定:从右到左顺序入栈,由调用者清理栈中参数)
按F8单步执行,GetDlgItemTextA执行之后,数据窗口显示读入了输入的用户名和序列号
找到序列号判断的关键代码,发现只要4011F5一句不跳转就可注册成功。
5.爆破(或补丁patch)
即屏蔽程序的某些功能,或改变程序流程,使程序的保护方式失效。
修改方法一:改变标志寄存器的值
执行到4011F5行,在寄存器面板中找到寄存器ZF,双击一次取反,由1变0或由0变1
修改方法二:改变汇编代码
选中4011F5行,双击,输入指令“NOP”
目前修改是内存中数据,选中修改过的代码–>右键–>Copy to executable–>Selection–>Save File,把修改复制到.exe 文件中
6.找到正确序列号
加载TraceMe之后运行,输入pediy和假序列号“121212”,跳出错误提示框。
M(内存窗口)–>最上一行Ctrl+B搜索框–>Ascll输入121212定位–>在其前后位置找到正确序列号2470
(根据数据约束性,即密码相邻性)
6.制作注册机
方法一:用Keymake软件(针对序列号在内存中是明码的)
在指定位置拦截程序指令,将内存或寄存器的值读出来,得到正确序列号
第一次拦截处:
.text:004011E5 E8 56 01 00 00 call sub_401340
第二次拦截处:
.text:0040138D 55 push ebp ; lpString2
Keymate设置如下:其他–>内存注册机–>生成注册机和原程序放在一个目录下
方法二:内存注册机
常用断点
- INT 3断点,即用CC指令(机器码是CCh),替换原来的指令。调试器捕捉到CC指令就停在断点处。
快捷键F2,或双击Hex dump
好处:可同时设多个断点;
缺点:易被检测(因为修改了原指令),检测API地址的第一个字节,若是CCh,则认为被下断。
若要躲过检测,只要将断点下在函数内部(例如,函数入口的下一行)即可。
2.硬件断点
利用DRx调试寄存器。DR0~DR3放断点的地址,DR7设定相应的控制位。当运行到相应地址时中断。
右键–>Breakpoint–>Hardware设置断点;菜单Debug–>Hardware breakpoints–>Delete删除断点
优点:速度快,不易被检测
缺点:最多只能4个断点
3.内存断点
对所设的地址设为不可访问/不可写,当访问/写入时中断。
右键–>Breakpoint–>Memory设置断点;右键–>Breakpoint–>Remove memory breakpoint删除断点
优点:不易被检测,当硬件断点失灵时,用它来替代
缺点:降低OD速度。
4.内存访问一次性断点
一次性,即中断发生后,断点就被删除。
M(memory map)–>找到相应的内存段–>Set break-on-access
优点:脱壳时特别有用
5.消息断点
当用户点击一个按钮。移动鼠标或向文本框输入文字时,会发送消息到当前窗体。当窗体接收到特定消息时程序中断。
W(Windows)–>找相关参数:句柄(Handle)、ID等–>右键–>Message breakpoint on ClassProc–>Messages设置消息种类,即设置中断;Alt+B断点窗口,删除中断。
6.条件中断
断点满足一定条件时才中断,是一个带有条件表达式的 INT 3 断点。
右键–>Breakpoint–>Conditional
7.条件记录断点
有条件断点的作用,还能记录断点处 函数表达式的值、参数的值、断点的次数等。
右键–>Breakpoint–>Conditional log–>输入条件和表达式,设置断点