新手学习反汇编之OD寻找功能call
本帖最后由 hackking 于 2017-12-15 15:59 编辑小白一枚,请嘴下留情!!!!!
## 背景知识
* `VC++`编程知识
* `OD`工具使用
* 汇编知识
## 功能实现
简单的互换点击功能;
* 将两个功能互换
效果图:
!(http://www.scanbuf.net/assets/public/20171215134915.png)
!(http://www.scanbuf.net/assets/public/20171215134941.png)
## 创建test程序
使用VS2017创建一个新的MFC工程命名为test,去掉默认按钮,新加两个button,分别命名test,test2。
创建添加两个新方法:
```C++
void CtestDlg::dispaly()
{
MessageBox(L"test");
}
void CtestDlg::dispaly1()
{
MessageBox(L"test2");
}
void CtestDlg::OnBnClickedButton1()
{
dispaly();
}
void CtestDlg::OnBnClickedButton2()
{
dispaly1();
}
```
编译生成`exe`可执行文件;
## 使用OD动态调试
使用`od`打开`test.exe`;
这里需要使用`bp MessageBoxW`下断点,这里因为使用宽字符(MessageBox是在库里声明了一个宏 当你使用宽字符的时候,也就是unicode的时候,自动帮你转换使用 MessageBoxW 而当你使用窄字符的时候,会自动帮你转换到 MEssageBoxA)。
然后运行`F9`。`alt+b`查看断点:
```text
7727FD3F | user32 | 始终 | mov edi,edi
```
`Alt+c`返回CPU汇编代码窗口;切换到`test.exe`程序点击test2按钮;
这个时候会自行到断点地方,注意看堆栈窗口里面的数据,如以下信息;
!(http://www.scanbuf.net/assets/public/20171215142044-follow.png)
```
0017EBE4 01648053/CALL 到 MessageBoxW 来自 test.0164804D
0017EBE8 000F07D6|hOwner = 000F07D6 ('test',class='#32770')
0017EBEC 01C6600C|Text = "test"
0017EBF0 0067EEE0|Title = "test"
0017EBF4 00000000\Style = MB_OK|MB_APPLMODAL
0017EBF8 0017EDD8
0017EBFC CCCCCCCC
0017EC00 0017FA3C
0017EC04/0017ECF0
0017EC08|015D3ED4返回到 test.015D3ED4 来自 test.015A1169
0017EC0C|01C6600CUNICODE "test"
0017EC10|0067EEE0UNICODE "test"
```
会发现调用来源,鼠标移动到`0017EBE4 01648053/CALL 到 MessageBoxW 来自 test.0164804D`右键点击反汇编窗口中跟随,然后在该call入口按`F2`下断点,按`alt+b`切换断点界面,去掉`bp MessageBoxW`,按`F9`运行。然后,然后再次点击test2 button看是否能断下。
反复测试button,发现两个button都会断下,那么证明,两处都调用了这里,这个时候,先去掉当前断点,重新下`bp MessageBoxW`断点,在执行一次button会发现,堆栈窗口里面还有一个调用地址;
!(http://www.scanbuf.net/assets/public/20171215143749-follow2.png)
先跟随过去,下断点,重复上面的动作测试一下,结果发现,这里才是正确的断点。
!(http://www.scanbuf.net/assets/public/20171215143831-bp-1.png)
```
015D3E40/> \55 push ebp ; 这里是 test2 call
015D3E41|.8BEC mov ebp,esp
015D3E43|.81EC CC000000 sub esp,0xCC
015D3E49|.53 push ebx
015D3E4A|.56 push esi
015D3E4B|.57 push edi
015D3E4C|.51 push ecx
015D3E4D|.8DBD 34FFFFFF lea edi,
015D3E53|.B9 33000000 mov ecx,0x33
015D3E58|.B8 CCCCCCCC mov eax,0xCCCCCCCC
015D3E5D|.F3:AB rep stos dword ptr es:
015D3E5F|.59 pop ecx ;test.015D20AB
015D3E60|.894D F8 mov ,ecx
015D3E63|.6A 00 push 0x0
015D3E65|.6A 00 push 0x0
015D3E67|.68 1860C601 push test.01C66018 ;UNICODE "test2"
015D3E6C|.8B4D F8 mov ecx,
015D3E6F|.E8 F5D2FCFF call test.015A1169 ;call test2
015D3E74|.5F pop edi ;test.015D20AB
015D3E75|.5E pop esi ;test.015D20AB
015D3E76|.5B pop ebx ;test.015D20AB
015D3E77|.81C4 CC000000 add esp,0xCC
015D3E7D|.3BEC cmp ebp,esp
015D3E7F|.E8 F97EFBFF call test.0158BD7D
015D3E84|.8BE5 mov esp,ebp
015D3E86|.5D pop ebp ;test.015D20AB
015D3E87\.C3 retn
```
注意:这里主要是不去分析整个流程,因为这样分析很容易掉进坑爬不出来,先用测试的方法论,撸一遍可能就省去了很多时间。
到这里先保存这个`call`,采用同样方法找到`test button`的`call`。
```
015D3EA0/> \55 push ebp ;这里是test call
015D3EA1|.8BEC mov ebp,esp
015D3EA3|.81EC CC000000 sub esp,0xCC
015D3EA9|.53 push ebx
015D3EAA|.56 push esi
015D3EAB|.57 push edi
015D3EAC|.51 push ecx
015D3EAD|.8DBD 34FFFFFF lea edi,
015D3EB3|.B9 33000000 mov ecx,0x33
015D3EB8|.B8 CCCCCCCC mov eax,0xCCCCCCCC
015D3EBD|.F3:AB rep stos dword ptr es:
015D3EBF|.59 pop ecx ;test.01648053
015D3EC0|.894D F8 mov ,ecx
015D3EC3|.6A 00 push 0x0
015D3EC5|.6A 00 push 0x0
015D3EC7|.68 0C60C601 push test.01C6600C ;UNICODE "test"
015D3ECC|.8B4D F8 mov ecx,
015D3ECF|.E8 95D2FCFF call test.015A1169 ;call test1111
015D3ED4|.5F pop edi ;test.01648053
015D3ED5|.5E pop esi ;test.01648053
015D3ED6|.5B pop ebx ;test.01648053
015D3ED7|.81C4 CC000000 add esp,0xCC
015D3EDD|.3BEC cmp ebp,esp
015D3EDF|.E8 997EFBFF call test.0158BD7D
015D3EE4|.8BE5 mov esp,ebp
015D3EE6|.5D pop ebp ;test.01648053
015D3EE7\.C3 retn
```
这里就找到两个button功能call了,需要调换两个地方,发现如果直接call修改,需要堆栈平衡,闲麻烦,往上找找谁调用这里`push ebp`的地址,会发现上面有个`jmp`,在数据窗口上面直接跳转过去;
!(http://www.scanbuf.net/assets/public/20171215145940-jmp.png)
## 完成
啊哈,直接把两个地址互换一下,OK完成。记录下整个分析流程。 影风 发表于 2017-12-15 22:52
新手直接用C++?那你很棒棒哦
新手就不能用C++了?你这什么逻辑把C++说的无限高大上?
自认为只是一门编程语言而已并没有什么难度啊 戒酒的李白 发表于 2017-12-18 13:38
用这个是得要先学c++和汇编吗
不是必须C++,汇编肯定要学的,不然,看不懂汇编代码。
因为有编程部分,这里只是交代知识背景。
学习了,谢谢分享 正需要这样的帖子,逐步学习。 新手就应该这样学习
表示666,小弟我前来膜拜! 感谢 新手很适合这样的文章楼主辛苦了 很清晰,学习了,谢谢! 但是我要谢谢 楼主辛苦了 最近在学od,谢谢楼主分享的