今天给大家分享一个有趣的问题,来增长一点知识。
一位小伙伴(
歌虽无形
)遇到的问题,后来研究清楚后,我让他总结分析了一下,我稍微改了一下,分享给大家。
事情是这样的:
公司采购了新软件,想在新软件下沿用旧的一些插件和功能,于是就将旧版本的dll直接替换了新版本。
然而,诡异的现象出现了,win7下能正常运行,但win10却怎么也跑不起来,一运行就会会闪退。
学习逆向,当然要自己来动手解决这个问题,是时候展示真正的技术了。
经过分析,发现了崩溃的地方,有个函数入口的地方反汇编后是长这个样子的:
注意看,入口处,函数开辟栈帧,把栈顶抬高了0x298的大小,使用了
sub rsp, 298h
指令。
然后是函数结束返回的地方,要恢复栈空间,使用了
add, esp, 298h
指令:
聪明的你一定已经发现问题了,怎么开始是用的rsp寄存器,后面用的是esp寄存器呢?
PS:esp是x86架构CPU的栈指针寄存器,rsp是x64架构CPU的栈指针寄存器。x64兼容了x86指令集,可以通过esp访问rsp的低32位。
先别往下看,你先猜一下,这里会出问题吗,为什么会出问题呢?
由于前面正好有一堆nop,于是将紧邻着的一个nop从0x90改为0x48,这样一来,就把
add esp, 298h
这条指令,改成了
add rsp, 298h
了。保存,然后成功修复了~然后很得意的在群里吹水去了~
但事情并没有结束。过了几天总结文档时,突然意识到:不对!有问题!
修复程序的当时我给开发那边给出了一个解释,是恢复栈指针时出现了错误导致堆栈不平衡。但现在仔细想想,简简单单一句“堆栈不平衡”完全解释不通。
原因是,win7能跑,意味着在win7下
add esp
和
add rsp
结果是一致的,也就是栈顶指针的高32位空间没变动(或者变动了,但变动前后是一样的),而win10下却变动了。
没有头绪,找风哥帮忙。在风哥建议下又分析了一次。先找出之前的程序崩溃转储,用windbg再看看有没有什么蛛丝马迹。
dump分析出来是这个样子的:
经典的0xC0000005 错误码。但除此之外也似乎没有别的问题了?等等,再看一下寄存器:
发现了一个很可疑的点,在执行了