hackking 发表于 2017-12-15 15:58

新手学习反汇编之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完成。记录下整个分析流程。

Poner 发表于 2017-12-16 01:34

影风 发表于 2017-12-15 22:52
新手直接用C++?那你很棒棒哦

新手就不能用C++了?你这什么逻辑把C++说的无限高大上?
自认为只是一门编程语言而已并没有什么难度啊

hackking 发表于 2017-12-18 13:56

戒酒的李白 发表于 2017-12-18 13:38
用这个是得要先学c++和汇编吗

不是必须C++,汇编肯定要学的,不然,看不懂汇编代码。
因为有编程部分,这里只是交代知识背景。

first 发表于 2017-12-15 16:15

学习了,谢谢分享

guer 发表于 2017-12-15 16:48

正需要这样的帖子,逐步学习。

hackysh 发表于 2017-12-15 17:42

新手就应该这样学习

人心所向 发表于 2017-12-15 18:26

表示666,小弟我前来膜拜!

连晋 发表于 2017-12-15 20:12

感谢 新手很适合这样的文章楼主辛苦了      

burnda 发表于 2017-12-15 21:10

很清晰,学习了,谢谢!

googldfo 发表于 2017-12-15 21:16

但是我要谢谢

heazerry 发表于 2017-12-15 21:28

楼主辛苦了

不羡云卿颜_ 发表于 2017-12-15 22:24

最近在学od,谢谢楼主分享的
页: [1] 2 3
查看完整版本: 新手学习反汇编之OD寻找功能call