【转帖】反-反汇编patch学习(二)
转自:https://xz.aliyun.com/t/4721上一篇文章中主要是一种花指令的思路
1. 把当前的RIP的值pop到寄存器中,比如rax
2. 调整rax的值,使之处于反汇编引擎的解析的某条指令**中间**,让反汇编引擎出错,但实际上可以正确跳转,解决方法是帮助IDA正确识别数据和代码
这篇文章主要是在子函数中劫持父函数的流程
使用的测试文件在附件中
# 栈上相关背景
在函数调用时,`call xxx`会将下一条指令的地址压栈,再前往要跳转的指令
当子函数调用结束,`retn`会将之前保存的指令地址置为`RIP`的值,也就是说,`retn == pop rip`
> 子函数调用时,一开始可能会把`RBP`压栈,并把`RSP`的值赋给`RBP`,在退出函数时进行逆操作
无论是哪种情况,可以发现,父函数的返回地址也只是栈上保存的一个数据而已,也没有保护机制:比如子函数只能把RSP的值控制在一定范围内
也就是说,我们可以在子函数中获得父函数的`ret addr`,将其`pop`到寄存器中,再修改这个寄存器的值,当子函数`retn`时,父函数的**返回地址**也就被劫持了
# 实例
## 伪造子函数
我们还是拿上一篇文章中的`nothing-patched.exe`做演示,在附件中
这是正常的原程序流程
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092659-67b249ba-599d-1.png)
最后一行的`call sub_140001031`是我改成nop后加上的
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092720-73f4d760-599d-1.png)
可以认为我们在这边**伪造**一个子函数
## 修改retaddr
此时rbx就是父函数的返回地址,而现在只是`add rbx,0`,并没有改变返回地址,只要把这个0改一下,就可以劫持流程了
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092739-7fa254c0-599d-1.png)
可以看到,当前执行到`retn`,在堆栈窗口正好会回到`...102E`,它也就是原本`call`指令的下一条指令的地址
记为patched1,在附件中
如果这时我们将`add rbx,0`改成`add rbx,46`,那么就会跳转到源程序流程了
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092749-85ad2be2-599d-1.png)
## 加花
我们通过动态调试,让返回地址加上0x19,也就是跳转到下一个`jmp`指令上,记作patched2
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092805-8ee8c2ca-599d-1.png)
重新打开可以发现IDA已经识别错误了
这是因为在`...1047`处的`jmp`指令的前一个byte改成了如`0xEB`,这样就会让静态的反汇编引擎分析成错误`jmp`
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092817-962ab6e2-599d-1.png)
上图为动态调试时的场景
同样的,F5的结果也已经飞了
!(https://xzfile.aliyuncs.com/media/upload/picture/20190408092826-9bc9520c-599d-1.png)
## 去花
加上`0xEB`的这个技巧在上一篇文章已经说过了,去花也只是需要帮助IDA正确识别代码和数据等
# 补充
最后,因为本文只是介绍一下反-反汇编的小技巧,单一的技巧会显得比较单薄,但是如果把这些技巧组合起来,加上反调试等技术,会让代码变得很"难看",破解的难度也是指数级上升 学习了 非常有用、辛苦了 学习了 非常有用、辛苦了{:1_893:} 学习了,楼主辛苦 学习了 楼主辛苦 楼主辛苦了 感谢楼主分享
页:
[1]