0x01 首先先认识一下OD(OllyDbg)
打开OD界面,呈现出下图的窗口分布,这里笔者对OD界面的几个窗口进行了一下标识。
如图:
下面笔者对这几个窗口在程序破解中的作用一一介绍:
1.菜单窗口:
如图:
从左往右依次去说这些按钮的作用以及快捷键:
序号(编号) | 功能 | 快捷键 |
---|---|---|
1 | 打开新的可执行文件 | F3 |
2 | 重新载入程序 | Ctrl+F2 |
3 | 关闭程序 | Alt+F2 |
4 | 运行程序 | F9 |
5 | 暂停正在运行的程序 | F12 |
6 | 单步步入 | F7 |
7 | 单步步过 | F8 |
8 | 跟踪步入 | Ctrl+F11 |
9 | 跟踪步过 | Ctrl+F12 |
10 | 执行到返回 | Ctrl+F9 |
11 | 转到反汇编窗口中的地址(转到表达式) | Ctrl+G |
12 | 显示记录窗口 | Alt+L |
13 | 显示模块窗口 | Alt+E |
14 | 显示内存窗口 | Alt+M |
15 | 显示线程窗口 | 无 |
16 | 显示窗口 | 无 |
17 | 显示句柄窗口 | 无 |
18 | 显示CPU窗口 | Alt+C |
19 | 显示补丁窗口 | Alt+P |
20 | 显示调用堆栈窗口 | Alt+K |
21 | 显示断点窗口 | Alt+B |
22 | 显示参考窗口 | Alt+R |
23 | 显示Run跟踪窗口 | 无 |
24 | 显示源码窗口 | 无 |
25 | 调试选项 | Alt+O |
26 | 界面选项 | 无 |
27 | 帮助 | 无 |
2.反汇编窗口:
为了演示方便笔者决定用C语言写个简单的Hello World!程序
代码如下(C):
#include<stdio.h>
int main()
{
printf("Hello World!");
getchar();
return 0;
}
将编译好的exe文件拖入OD
这里笔者对反汇编窗口进行了一下划分和标注:
地址栏 Hex栏 反汇编栏 具体信息栏 注释栏
如下表所示:
名称 | 功能 |
---|---|
地址栏 | 程序的内存地址 |
hex栏 | hex数据(16进制) |
反汇编栏 | 程序的汇编代码 |
具体信息栏 | 对汇编代码进行更详尽的查看和说明 |
注释栏 | OD分析出来的,双击可进行编辑 |
3.寄存器窗口
这里就简单介绍几个 通用寄存器
:ESP:
指向堆栈栈顶EBP:
大部分用来定位局部变量和参数
其余的就各自拆开来用,这里不做过多的讲解
这里面不对寄存器做更加深入的讲解,有兴趣的同学可以看看王爽的 《汇编语言(第3版) 》
。
另外, 点击标签 寄存器 (FPU)
可以切换显示寄存器的方式
4.数据窗口:
数据窗口主要的即为程序
或者内存
的数据,右键可以切换显示方式
5.堆栈窗口:(在动态调试方面十分重要)
主要存放线程的临时数据,可以用于动态调试
.
6.命令行窗口
用于执行一些OD命令
例如: bp+API函数名称(内存地址)
设置断点
0x02 一些OD常用操作
为了方便演示下面的操作,笔者写了一段代码来检测explorer.exe
进程的程序
代码如下(C):
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
int main()
{
char* procressName = "explorer.exe";
char pName[MAX_PATH];
strcpy(pName, procressName);
CharLowerBuff(pName, MAX_PATH);
PROCESSENTRY32 currentProcess;
currentProcess.dwSize = sizeof(currentProcess);
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("函数CreateToolhelp32Snapshot调用失败!\n");
return FALSE;
}
BOOL bMore = Process32First(hProcess, ¤tProcess);
while (bMore)
{
CharLowerBuff(currentProcess.szExeFile, MAX_PATH);
if (strcmp(currentProcess.szExeFile, pName) == 0)
{
CloseHandle(hProcess);
printf("发现explorer.exe");
system("pause");
exit(0);
}
bMore = Process32Next(hProcess, ¤tProcess);
}
printf("没有发现explorer.exe\n");
CloseHandle(hProcess);
printf("Cracke Success!");
getchar();
return 0;
}
编译后运行
那现在我们开始来绕过这个检测explorer.exe的程序吧
打开OD
1.载入OD的几种方法
(1). 直接点击打开新的可执行文件按钮(或者按F3)
载入新的exe
(2). 将exe文件直接拖拽到反汇编窗口中进行加载
(3). 进程附加
- 前提是你需要先运行所要附加的exe
点击文件->附加
,找到需要附加的进程,选中后点击附加
2.字符串搜索方法
在反汇编窗口上点击右键->中文搜索引擎[根据需要你可以选取相应的筛选选项(1.搜索ASCII
,2.搜索UNICODE
,3.智能搜索
)]
名称 | 别称 | 简写为 |
---|---|---|
ASCII | ANSI | A |
UNICODE | WideChar | W |
程序API
里面的A/W
就是指的这两种编码
用刚刚那个检测explorer进程的exe为例子:
ASCII搜索:
Unicode搜索:
智能搜索:
在这里面笔者推荐在搜索字符串的时候使用智能搜索
。
3.下断点以及删除断点:
下断点:
-
快捷键下断点
快捷键F2
:用鼠标选中需要下断的代码,按一下F2
如图: -
基本下断: 用鼠标选中代码
右键 -> 断点 -> 切换
如图: - 命令行下断:
- 先找到需要下断的内存地址:
- 先找到需要下断的内存地址:
- 在命令行窗口输入
bp+ 内存地址
- 本程序中需要下断的内存地址为:
00B510EC
输入命令:bp 00B510EC
, 回车
删除断点:
- 基础删除断点方法:
- 查看 –> 断点 然后就进入到显示断点窗口(快捷键
Alt+B
),如图:
- 查看 –> 断点 然后就进入到显示断点窗口(快捷键
- 用鼠标点击需要删除的断点右键删除即可
这里对断点的介绍并不是很全面,只是起到了一个引导知识的作用4.保存文件:
就以这个检测Explorer.exe的程序为例子
我们需要将程序改为直接输出Cracke Success
!
首先搜索字符串找到Cracke Success
!
如图:
双击字符串跟踪
向上翻一翻字符串会发现 没有发现explorer.exe \n
这段ASCII,用鼠标选中ASCII所在的代码,如图所示
这里面用白色圆形所传出来的是一段跳转,我们需要跟踪一下这里的红线代表的是跳转实现,而白线则是不实现。
发现是从je short Checking.00B510EC
跳转过来
这里面普及一下汇编的条件跳转指令:
指令名称 | 英文全称(不重要) | 功能 |
---|---|---|
jmp | jump | 无条件跳转 |
je/jz | jump zero | 结果为0跳转 |
jnz/jne | jump not zero | 结果不为0跳转 |
js | jump if sign | 结果为负跳转 |
jns | jump if not sign | 结果为正跳转 |
jb | jump below | 比较结果小于跳转 |
jnb | jump not below | 比较结果大于或者等于则跳转 |
回到这个程序中.
程序的意思就是调用CreateToolhelp32Snapshot
函数去创造一个当前进程快照,利用ProcessFirst
和ProcessNext
这两个API函数去遍历进程快照的进程并且与Explorer.exe
做比较(cmp指令
),如果结果为真就不跳转,输出“发现explorer.exe”
,如果结果为假就跳转“没有发现explorer.exe Cracke Success!”
所以这其中的关键就在于遍历查找部分
用鼠标选中后,双击
将条件跳转的je
改为无条件跳转的jmp
右键 -> 复制到可执行文件 –> 所有修改
点击全部复制
右键后,找到保存文件
我们将其重命名为Cracker-Checking Explorer.exe 保存在桌面上
运行一下
这个进程检测就被我们绕过了
------文章出自i春秋,这里作为自己的一份笔记,以及分享