OD学习笔记
Day1 快捷键
- 设置断点或删除断点
- F4运行到当前选定位置
- F7单步步入
- F8单步步过
- F9运行至下一断点
- CTRL+F9运行到当前函数的return处
- CTRL+G查找表达式
- ALT+B查找断点
Day2 爆破实例
-
OD打开traceme.exe-插件-API断点设置工具-常用断点设置,找到GetDlgItemTextA(不确定的话GetWindowTextA也可顺便勾上)打勾并确定 ,F9运行
-
出现输入弹框,输入后按check,会停在断点处,按ctrl+F9执行到返回,再按F8,观察到就是两段获取输入框数值的代码的中间
-
往下一直跑,看到push edx与push eax后有个call,此时右边edx与eax的值就是我们输入的账号与密码,不难看出这个call就是判断账号是否正确
-
进一步检测,我们可以进入这个call里面看,就是循环检测字符串,最后返回值记在了eax
-
返回原函数,call之后是add esp,0cC退栈,然后test eax,eax用eax的值来对Z寄存器赋值,接着的je很有可能就是关键跳转!
-
找到je关键跳转,继续跑会显示“输入错误”,ctrl+F2重新跑到这,并在这指令执行前把右边Z寄存器的值改成0,再跑会显示“输入成功”,可以确定是关键跳转!
-
于是对je关键跳转,双击修改成jne,重新运行,此时输入的账号与密码只要不是原程序中正确的输入,都会显示成功,至此爆破成功!
-
最后生成新的exe程序,选中修改过的代码,右击,复制到可执行文件,选择,此时界面会切换,选到“文件”对话框,右击代码,保存文件,重命名,确定!
Day3 INT3断点调试
- OD中用F2产生断点,就是把原指令替换成int3指令,机器码是CC
- 机器运行时遇到CC会发出异常并中断
- OD再步进时就会把CC还原为原代码并执行
- 优点:可以无限下int3断点
- 缺点:很容易被检测到,特别是下在函数首部时,我的理是,当于CE配合使用时,会查不到原代码
Day4 INT3断点反调试
-
GetProcAddress函数:一个计算机函数,功能有是检索指定的动态链接库DLL中的输出函数地址,IpProcName能识别DLL中的函数
-
LoadLibrary函数:返回一个句柄,作为GetProcAddress函数的第一个参数
-
FARPROC结构体:是GetProcAddress函数返回的数据类型
#include<iostream>
#include<Windows.h>
using namespace std;
int main() {
FARPROC addr = GetProcAddress(LoadLibrary(L"user32.dll"), "MessageBoxA");
byte byteAddr = *(byte*)addr;
::MessageBoxA(NULL, "内容", "标题", MB_OK);
if (byteAddr == 0xCC) {
cout << "非法调试" << endl;
}
else {
cout << "代码正常" << endl;
}
getchar();
return 0;
}
// 编译器改Release及x86
// 右击项目-属性-配置属性-C/C++-代码生成-Spectre缓解-已禁用
// 右击项目-属性-配置属性-链接器-高级-随机基址-否
// 编译链接生成exe文件
// -------------------------------------------------------
// OD打开exe文件-插件-API断点设置工具-常用断点设置,找到MessageBoxA打勾,F9运行
// 程序会中断在MessageBoxA处,再按F9运行,会弹窗,按确定,控制台会显示“非法调试”
// 至此针对MessageBoxA函数调用位置的反调试功能已实现,下面是验证
// alt+b再删掉刚创建的断点,再重新跑程序,控制台会显示“代码正常”
// -------------------------------------------------------
// 破解方法:就不要在入口断点即可(针对本C++文件的检测点而言)
// ctrl+g弹框输入MessageBoxA确认定位到函数入口(机器码88FF 反汇编mov edi,edi)
// 然后在下一行(机器码55 反汇编mov edi,edi)按F2打断点
// 连续按F9运行,控制台会显示“代码正常”,表示成功破解
Day5 硬件执行断点
- 调试寄存器:有DR0到DR7,DR0到DR3设置断点地址,DR6状态寄存器,DR7控制寄存器
- 添加方法:右击需要断点的指令,断点,硬件执行
- 删除方法:调试,硬件断点,删除,确定
- 原理:用DR0到DR3设地址并用DR7设对应控制位,程序执行到该地址就发出异常并中断,等待用户操作
- 优点:速度快,不容易被检测
- 缺点:最多只能下四个硬件断点
Day6 内存读写断点与确件读写断点
-
内存断点原理:把该内存块设置成不可读不可写不可执行的属性,程序运行到该位置会产生异常,OD捕获到后把内存块改成可读可写可执行,然后继续运行
-
添加方法:在OD界面的下面输入"db 内存地址"(没有双引号),选中要加断点的字节,右击,断点,内存写入或内存访问(无非就是读和写操作)
-
删除方法:在OD界面的下面输入"db 内存地址"(没有双引号),选中要加断点的字节,右击,断点,删除内存断点
-
硬件断点原理:同Day5,注意Day5中执行是作为机器码,Day6中是作为数据地址
-
添加方法:对mov dword ptr ds:[0x405528],edx指令,在OD界面command框输入"db 405528",选中405528起8字节,右击,断点,硬件写入或访问,Dword
-
删除方法:调试,硬件断点,删除,确定
-
区别:内存断点会在该指令执行前中断,硬件断点会在该指令执行后中断(就他这么特殊,其他的中断都是在指令执行前进行中断)
Day7 消息断点
- 添加:OD打开exe程序,按上面的w按钮,下面空白的话右击刷新,在左边有树目录选窗口句柄,右击,在ClassProc上设消息断点,选择监听的消息,确定
- 删除:alt+b查看,选中,delete删除
Day8 条件断点
- 添加:OD打开exe程序,选中要中断的指令,shift+f2,输入中断条件(例如Z==1 && eax!=19ffcc),确定
- 删除:alt+b查看,选中,delete删除
Day9 内存访问一次性断点
- 添加或删除:OD打开exe程序,按上面的M按钮,右击要中断的指令,选中”在访问上设置中断“或“删除访问中断”
- 运行效果:上面的中断设置了之后只会生效一次,就会自动删除
Day10 条件记录断点
添加或删除:OD打开exe程序,选中要中断的指令,shift+f4,设置参数(见下面说明),确定,alt+l查看有记录的值
- 条件:例如可以写eax==19ffcc
- 说明:就是打印日志时显示的文字,右边表达式是变量
- 暂停程序/记录表达数值/记录函数参数:就是触发的条件,如果是按条件的话,可以设置条件满足多少次才触发
- 下面文本框填.d eax就是传eax的值到插件
Day11 hit trace
- 原理:每个指令下了个int3指令
- 操作过程:选中要trace的代码段,右击,hit跟踪,这时选中 代码会有标记颜色,当运行时会变成另一种颜色,且去掉int3断点(重新运行也会消失)
Day12 run trace
- 操作过程:选中要trace的代码段,右击,run跟踪,这时选中 代码会有标记颜色,运行程序,按上面的…按钮,会显示执行过的指令
- 如果要保存文件:则按上面的…按钮后,在下面右击,保存到文件,之后再跑,就会自动往文件里写入
- 记录内容的追加:在OD菜单栏-选项-调试选项,即可选中,还有如果你打了断点的话断点信息也会记录
Day13 调试符号
- PDB文件存的内容,OD打开EXE程序,查看-源码(空的),查看-源文件,会看到有cpp文件,双击进入可以看到真正的源码