wonderzdh 发表于 2013-6-14 17:06

【wonderzdh】-逆向学习笔记第二篇-吾爱扣扣的一个CM

本帖最后由 wonderzdh 于 2013-7-16 10:27 编辑

【文章标题】: 吾爱扣扣的一个CM
【文章作者】: wonderzdh
【作者主页】: http://hi.baidu.com/chicken
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
本套教程至少得更新到10课,由于没有事先安排,内容可能会比较乱,但是每字每句都是心得。

为什么我要把这些心得发出来,而不自己藏着。因为我发的东西本身就是我对学习逆向的一个梳理和总结。

赠人玫瑰,手有余香。至于你们回不回复,评不评分,我一点所谓也没有。

后续课程不会继续在【逆缘论坛】首发,【吾爱破解】转帖的形式存在,而是两个站同时更新。

也希望我的帖子在吾爱不是归类转帖,而是属于原创,本人可是吾爱未来的“原创精英”+“论坛大牛”呀。{:301_972:}

如果想求破,可直接来逆缘免费求破,网址什么的就不发了,自己百度一下。
【详细过程】

刚刚看了吾爱扣扣的一个CM,很适合我们新手的一个经典CM。PEID显示UPX的壳,这个壳大家都懂,压缩壳,ESP定律或者说堆寨平衡法秒杀之。这里我也写一下:当OD提示这个的时候这个程序一般就是加壳了的,我们需要选择“否”,不分析,然后自己去调试。第一句pushad按F8单步,此时ESP变红,变红就是被修改了。关于ESP定律在附录里我会讲到。我们在ESP上右键选中数据窗口跟随。此时注意看数据窗口第一行,地址为:0012ff6c ,这和我们刚刚的ESP的值是一致的。意思就是我们来到了ESP指向的地址里,这里存放的字节型数据是:00。下一行地址是0012ff7c,0012ff8c-0012ff6c=10,这意味着第一行包含16个字节(10是16进制换到10进制就是16)。2个16进制数是一个字节,这里刚好有16个字节,自己看第一行慢慢数,慢慢理解。我们下断点用Word-双字节(也称为字),Byte是字节,Dword就是双字。下好硬件断点,我们按F9运行,断在此处:熟悉UPX的都知道,JNZ下边一个SUB,然后就是JMP到OEP了。这里你可以看到JMP后边的地址是0044ef9d,而这句代码所在的地址是004c4aa4,这是一个很大的跳转,一般我们破解要注意的就是很大的跳转或者PUSH很多后边的CALL,这些一般都是关键的部分。我们在SUB那句下断,然后运行,或者直接F4运行到所选。两个F8就到OEP了。程序运行到OEP处一般就是最佳dump时机,此时源程序会全部“复原”到内存中,我们只需要用LordPE将内存镜像dump出来即可,保存为dumped.exe。双击dumped.exe无法运行,那就需要修复PE文件了。这是由于dump出来的PE格式中的问题,比如输入表(程序所需外部DLL命令表)不正确等引起的。我们打开ImportREC,选中此时程序的进程(我们OD载入脱壳前的源程序),把OEP的偏移地址(0044ef9d-00400000;此行代码所在的地址减去此行代码所在内存区块的基地址,关于内存分配可以参考《加密与解密》这本书)输入进去。然后获取输入表,没有无效的输入函数的话就直接转存修复,保存为dumped_.exe。脱壳完毕,下面开始破解。OD载入脱壳后的程序(dumped_.exe),F9直接运行。这里用到一个最常见断点:user32.GetWindowTextA这个函数的作用就是获取我们输入框中的文本。百度百科:http://baike.baidu.com/view/1080327.htm这里后缀A代表ANSI版本,后缀W则代表Unicode,我们搜索文本的时候也可以发现有这两种字符编码之分。一般情况下,我们在CPU窗口Ctrl+N搜索当前区段所用到的API函数,直接输入getwindowtexta找到此函数,然后右键在每个参考上设置断点,意思是该程序每次调用这个函数都会被断下,当然更好的办法是进入到这个函数内部下条件断点。但是OD提示没有参考命令,我到调用地址查看是有的,但是OD就是找不到(直接用UPX脱壳机脱壳出来的文件就可以找到)。不过没关系我们换一种方式。我们右键,查找-所有模块间的调用,然后排序按目标文件,这样就可以找到所有调用GetWindowTextA这个函数的地址了。我们输入GetWindowTextA,就来到此处:直接 选中这两块地址F2下断,下断后显示红色。点击OD最上方“b”查看我们下的断点,都是始终激活。这里可以方便的管理我们的普通断点,不包括硬件和内存断点,这些断点在调试选项中查看。下断后我们输入显眼的ID和注册码,中途可能会断下几次,这是由于其他地方调用了GetWindowTextA,我们只关心我们按下按钮后断下的时机,所以我们没有按下按钮前断在这里我们都按F9运行,点击按钮(Register)后断下的才是我们需要断下的地方。我们按下按钮(Register)后,发现程序断下来了,此时就是提取我们输入文本的时候,但肯定至少调用2次,因为我们有ID和注册码两个文本框嘛。中断后就是获取我们输入的文本,后边肯定是判断对不对,然后来个跳转,执行相应的操作。所以我们就需要按F9看看他到底断下几次。第三次断下EAX出现我们输入的ID。第四次断下出现我们的注册码。一共断下五次,我们第六次按F9的时候程序运行了,我们输入的内容被清空了。所以,第五次断下之后的代码就离我们要找的关键最近。我们重新输入ID激活码然后断下5次,OD如下:接着我们需要进行的是逆向最重要的部分,跟踪,我们F8单步走,一直走到如下出:这里很特殊,如果你们细心的话可以发现这里有很多PUSH然后来个CALL,上边还是一个判断跳转。这种结构很可能就是我们要找的部分,小菜只能这么解释了,求大牛指导。(其实我们F7跟进CALL会发现很多关于窗口控件的操作)修改很简单,选中 je 00401430,右键--二进制--用NOP填充。我们再右键--复制到可执行文件--所有修改;然后再右键--保存文件即可。然后,我们随意输入ID和注册码都显示成功。
第一篇地址:http://www.52pojie.cn/thread-199860-1-1.html

附录:
ESP定律原理:
根据《加密与解密》中的介绍,我们运行加壳后的程序,外壳需要先初始化各寄存器的值(主要是ESP,EBP),外壳执行完毕后会恢复这些寄存器的值,这应该是压缩壳才用到的。
我自己的理解是:压缩壳执行前和真正的程序执行前的寨顶(就是ESP)是一致的,第一个push就是压入到这个ESP中(或者说附近吧)。
这就是为什么我们对ESP指向的地址下硬件写入断点的原因了,当外壳对这个地址写入数据的时候就是OEP附近!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于【wonderzdh】,转载请注明作者并保持文章的完整,谢谢!

                                                       2013-6-14 17:06

bdk236 发表于 2013-6-14 17:09

很好,很强大,,学习了

luoenlai 发表于 2013-6-14 17:18

路过支持了{:1_931:}{:1_932:}

莫谷 发表于 2013-6-14 17:20

不错的东西,小伙子继续努力。我比较看好你

1354669803 发表于 2013-6-14 17:27

这一课就是讲的获取窗口文本断点的应用 哦耶

cxqdly 发表于 2013-6-14 18:00

很适合学习受教了

吾爱扣扣 发表于 2013-6-14 21:14

1354669803 发表于 2013-6-14 17:27 static/image/common/back.gif
这一课就是讲的获取窗口文本断点的应用 哦耶

膜拜大牛和LZ!

sos501 发表于 2013-6-15 12:23

很不错的心得!!!

我是冰冻的番茄 发表于 2013-6-18 11:59

{:1_918:}{:1_918:}{:1_918:}{:1_918:} 酱油一下而已!

sunhai0975 发表于 2013-6-19 17:13

楼主问个问题 为什么我把调用GetWindowTextA的两处下断以后F9运行之后 激活窗口又暂停了呢 没法输假码呢 这是什么原因啊 求指教
页: [1] 2
查看完整版本: 【wonderzdh】-逆向学习笔记第二篇-吾爱扣扣的一个CM