-
-
[旧帖]
修复PEID两个小缺陷
0.00雪花
-
发表于:
2014-10-28 11:22
1928
-
一:问题
在使用PEID过程中发现其有两个影响到我工作的小缺陷,一是其在查某些程序壳时自身会崩溃。如下图(下载了多个版本都存在这个问题)
一开始怀疑是PEID加的upx壳影响的,脱壳后发现问题依旧存在。崩溃原因有兴趣的可以在OD中定位一下。
第二个缺陷可能只是针对我个人需要而言,PEID的查壳结果不能自动导出。如下图
如果能导出这里的信息,我就可以在自己的程序里面调用PEID达到自动批量查壳的目的。
PS:PEID本身也有个批量查壳功能,但是查询完后还需要手动导出结果,同样影响我的自动化流程。
二:解决方案
首先解决第二个问题,导出查壳结果的文本数据。思路很简单,用HOOK API的方式来获取文本。怎么HOOK呢?有两个方案,一个是用调试器的方式创建调试事件来动态HOOK,另一个方案是通过IAT表来HOOK。但该PEID被加了两层壳,upx很容易就脱掉,第二个就有心无力了(汗,原谅我的菜...)。所以采用方案一。
方案一的原理很简单,就是通过创建调试器的方式在目标API上下断点(int 3断点),从而获得API的参数。这里OD载入,很容易找到关键API,如下:
在两个关键处下断点调试分析,下面那个SetDlgItemTextA为输出壳结果到UI。所以,我们需要HOOK的API即使它。所以我们写一个Loader当做调试器再改API处下断。大体思路就是这样了。
至于第一个问题很好解决,对于查壳崩溃,只需要在调试器中捕获崩溃异常就可以了。
三.遇到的技术难点
首先就是如何获取到SetDlgItemTextA函数地址,要知道一点,NT系统中,系统dll在加载到所有程序中的地址一样的。也就是说
我们只需要再Loader中获取自身该API地址就可以了。按照这个思路去做,发现 GetProcAddress半天获取不到API地址。很疑惑,后面才恍然大悟,控制台程序根本没加载user32.dll,而该API正是通过该dll导出的,汗!于是,用LoadLibrary( _T("user32.dll") 再获取就OK了。
然后就是这种HOOK API方式的一个通病,容易漏HOOK。在实践过程中确实发生了该问题。SetDlgItemTextA在被调试进程中一共运行了多次,但经常会发生漏HOOK的情况。不想通过注入dll后再HOOK的方式,太麻烦了,怎么去解决这个问题呢,困扰了我很久。先来分析下产生这个问题的原因:一共有两个进程,调试器进程(Loader),被调试进程。调试器进程恢复之前下载的断点后,让被调试进程继续运行,这时候系统分配时间片给被调试进程,在这个分配的时间片内,被调试进程可能已经调用了该API多次,但调试器没来得及下载新的断点。解决这个问题的方法有几种,我采用的是,调试器进程恢复之前下载的断点后,让被调试进程继续运行之前,在原断点地址之前多增加一个断点,这样就可以避免漏HOOK的情况。按照该思路,一共下载了3处断点。
再有的难点就是程序逻辑了,稍微有点绕,不过慢慢整理就好了。
四.最后结果
可以看到已经导出目标字串了。同时在程序目录下生产一个txt文件,里面保持了目标字串,也就是壳信息。
五.源码(ps:因为很多测试过程,所以代码很冗杂,像很多个重复功能的函数,明明可以合并。最后也懒得修改了)
工程及附件下载地址:http://pan.baidu.com/s/1i3GGGbr
非常非常感谢身边的大牛同事们,经常帮助解答各种问题。
[课程]FART 脱壳王!加量不加价!FART作者讲授!