默小白 发表于 2019-5-17 14:14

【转帖】反-反汇编patch学习(四)

转自:https://xz.aliyun.com/t/5097

# 源码、编译

代码如下:

```
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char** argv) {
    puts("nop me");
    puts("nop me");
    puts("nop me");
    puts("nop me");
    puts("nop me");
    system("pause");
    return 0;
}
//gcc -m32 main.c -o test
```

# x86-1

## IDA视角

用IDA打开,和之前几篇类似的汇编代码

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200547-9d06c72c-7189-1.png)

因为没开优化,对`esp`的加加减减没有合并

把`0x0804844F`处的`puts("nop me");`全部`nop`掉,也就是4条汇编指令,分别是参数压栈、调用函数、"平栈2次"

## patch

接着,`0x0804844F`处改成`call $+6`,也就是`call 0x08048455`,这条指令长度为5

最后把`0x08048455`的指令改成`pop eax`,效果如下:

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200552-a0765ecc-7189-1.png)

运行时没有什么问题

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200557-a2fc1e0c-7189-1.png)

F5也可以看出大致逻辑,IDA把`sub_8048455`看成了子函数

点进这个子函数,F5就会失败,因为堆栈不平衡

> 实际上`call func` == `push 下一条指令地址` + `jmp func`
>
> 这里通过一个`pop eax`消除`call`对栈的影响,效果其实就是无条件`jmp`,但是IDA显示非常混乱

## 修复

让IDA正确识别也很简单,只要`nop`掉那一块代码就行了

> 如果代码中有防止`patch`的措施,比如取代码段上某一块的数据,`patch`成`nop`以后就会改变原有的结果;也可能是代码段的校验之类,这样就会比较难以处理

## 补充-x64

这个技巧在x64架构下实现也一样简单,只补一个图

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200604-a753881e-7189-1.png)

# x86-2

## 失败的尝试

主要关于`push retn`的组合使用

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200610-aacf6698-7189-1.png)

尝试`patch`成这样,运行到`0x8048440`时压入一个代码段地址,然后直接`retn`

因为`retn == pop eip`,就会直接跳转到`0x8048449`

> 由于IDA一般会把`retn`看作函数结束的标志,所以一般分析到`retn`就结束了

重新打开,**尴尬的是IDA并没有被我们骗到**

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200614-adaf4748-7189-1.png)

可能是IDA对紧邻的`push + retn`有一定的识别吧

## 改进

作为改进方法,我们将栈弄得更复杂一些

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200619-b09c9708-7189-1.png)

目标地址`0x804843D`刚被`push`压栈,这时`esp`指向它

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200624-b39da852-7189-1.png)

紧接着就通过`add dword ptr ,0x2`把存的代码段地址增加2

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200631-b7419d60-7189-1.png)

可以看到即将`ret 0x804843f`也就是原程序流程

> 重新打开后发现识别效果很差,原先的很多代码段已经是红色了,这表明分析是有问题的

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200638-bb8f2e5a-7189-1.png)

不过虽然看到`sp-analysis failed`,但却不影响F5,不知道为什么

F5之后,后半部分的代码逻辑直接没了...效果不错

!(https://xzfile.aliyuncs.com/media/upload/picture/20190508200644-bf61a9a4-7189-1.png)

# 小总结

在实际上手时,一开始第一个例程用的32位exe,但是`patch`之后直接运行失败,调试也直接crash,暂时没找到结果,于是用gcc编译成elf代替

另外,消除对栈的影响也可以单纯的通过`add/sub esp,xxx`来完成,都差不多所以只举了`pop reg`的例子

zhongjiezhe 发表于 2019-5-17 14:57

哦哦哦哦哦,还可以哦

nj001 发表于 2019-5-17 22:52

支持楼主

abc220 发表于 2019-5-18 06:48

不错,支持楼主。

王宇 发表于 2019-5-20 12:08

感谢分享,支持一下
页: [1]
查看完整版本: 【转帖】反-反汇编patch学习(四)