你的位置:首页 > 操作系统

[操作系统]一个调试掉坑过程与总结


今天在用od跟踪一程序,结果摔坑里了,后面想想应该不止OD,市面上大多数调试器都是这样。

这个程序一路跟踪下来执行流程基本就是先执行一段代码,然后解开下一段代码,解完再加密上一段代码,通过jmp跳到解开的代码然后如此反复。

解密部分是在异常里进行的,它通过访问一个无效地址跳到异常,然后在SEHandler里的一个call进行SMC,这个call接收一个buffer,用来存放解出来的代码。

这样反复执行几段代码后我懒得再跟它解密过程了,于是就在buffer位置下了一个断,想直接让它运行到解出来的地方,奇怪的事情出来了,解密完ZwContinue()出去后又一次出现内存访问异常,于是再次跳到刚刚的SEHandler里,因为我前面试过直接在调试器里运行是可以运行的,所以重启程序,还是F9运行不起来,察看buffer发现是解密出来的内容本身就是有问题。我对比了下两次启动时的差异无非就是第一次没有在程序里下断,而第二次下了断,所以我第一反应是它可能在某些位置有对软中断做anti,如果检测到就解出错误的数据,于是我就在buffer的位置下了一个硬件断点,居然还是不行,最后我把所有断点去掉,程序顺利跑起来了。后面抗检测硬件断点的东西也看了好久,大部分都是涉及驱动的,所以也就只是看看。然而这个程序又是不带驱动的,所以就算有检测硬件断点的地方肯定也是ring3下完成的,所以就干脆把解密算法逆了一遍,最后发现原来是我下的那个断点处阻止了一个字节的解密数据写入到buffer中,原理很简单,当下int3断点时调试器会把断点处的一个字节修改成0xCC,而且这个字节的变化调试器是不会让你看到的,这时程序往里面写数据的话是写不进去的,因为一旦写进去,那这个断点就废了。so。。。我被调试器耍了。

总结:以后凡是在有数据写入的地方下执行断点要注意,可以先下个内存访问断点