这里是《加密与解密》书中的第五章程序PacMe.exe,一部分工作是在该书的提示下完成的,是挺有意思的一个基于注册文件保护的程序,下面附上破解过程。
http://s16/mw690/002S5apNgy6QNBiY6Pt6f&690
这是程序截图,首先想到的是找check函数对应的点击响应代码,看看什么条件在可以check通过……(不是MFC,没法用xspy直接获取)
丢到IDA里面,直接看字符串(SHIFT+F12):
http://s9/mw690/002S5apNgy6QNBo6Stqe8&690
函数也不太多,实在不行一个个看好了……这里可以看到一些关键字符串。直接火急火燎点到Congratetulation那里,发现只是验证的一个子函数(sub_401033),没有什么价值。
查看UNREGISTERED字符串调用位置,可以看到在4012cf函数中,有一个读写文件的操作:
http://s7/mw690/002S5apNgy6QNBsQJEy46&690
看看具体在程序中的地址是啥:
http://s1/mw690/002S5apNgy6QNBtBcd2a0&690
找到入手点,剩下的就是慢慢过程序对文件的限制了。接着把程序扔进Ollyice,然后在004016a7处下断点,然后点击Check按钮执行到断点位置,程序停在了调用CreateFileA函数之前:
http://s1/mw690/002S5apNgy6QNBzFhkId0&690
根据IDA静态F5的结果可以得知,首先会判断文件是否被打开,不然不会继续执行。所以得在平行文件夹下构造一个同名文件,然后随便写点东西,F8单步向下走可以发现,之后的逻辑是这样的:
http://s16/mw690/002S5apNgy6QNBEiFwH1f&690
由于接下来会读入第一个字符ASCII码值那么多的字符,然后会调用00401000计算这么多个字符的总和,由于之前文件中第一个字符是’1’,所以补足0x31=49个字符。
http://s10/mw690/002S5apNgy6QNBGAZvPc9&690
算完和之后,又需要再读18个字符,于是再补18个:
http://s8/mw690/002S5apNgy6QNBMZ8B9d7&690
这样数量上就没问题了,之前算的和是0xA10,这里先记下来,读完字符会调用0x004010C9,这个函数是干嘛的……
http://s6/mw690/002S5apNgy6QNBPzz1385&690
可以看到这个函数调用了sub_401033函数,而这个函数会输出注册成功,我们再好好看看sub_401033,发现函数有两部分功能构成:
Part
1:
http://s12/mw690/002S5apNgy6QNBSPfbZ8b&690
对函数传入的参数a1进行判断,有4条对应的分支。
Part
2:
http://s7/mw690/002S5apNgy6QNC1gCpMe6&690
这里会对之前操作的那个东西进行判断,如果等于88(’X’),则成功。如果等于42(’*’),则返回0。【什么鬼……】
接下来回到OD里,继续动态跟着走一下,发现首先进行了一个字符串拷贝:
http://s1/mw690/002S5apNgy6QNC5m0h240&690
利用db
403184查看一下:
http://s4/mw690/002S5apNgy6QNC3tzuXd3&690
没错,这是一个指针变量,对应存储的是一个地址,当前地址是004031CC,从IDA分析结果可以得出,对于sub_401033,会对这个指针存储的地址值造成影响。
先看看对应地址的情况,db 004031CC:
http://s3/mw690/002S5apNgy6QNCcZdt092&690
当时真心没有看出这是一个吃豆程序,后来根据对*和X的判断,才明白这是要吃豆豆……
先不管,继续往下走,会进入一个预处理函数0040101d,其内容如下:
http://s8/mw690/002S5apNgy6QNCgN2tx27&690
处理完之后进入一个循环,这个循环在IDA里面比较容易看明白:
http://s5/mw690/002S5apNgy6QNCpGSsQ94&690
即定义两个循环变量,v2从8开始循环,每次减2后,参与对18个字符的移位操作,并且与3,4次之后减到0,然后v1++,执行18*4次循环。
对应18个字符中,每个依次取0、1位,2、3位,4、5位,6、7位,然后组成2进制,作为参数传给401033。根据Part1分析:
=0
指针地址减16(C字符下移一行);
=1
指针地址加1(C字符右移一格);
=2
指针地址加16(C字符上移一行);
=3
指针地址减1(C字符左移一行)。
所以在每次循环要控制C字符按照’.’的路径到达终点’X’,需要的控制码为:
2221 2223
2211 0100 1110 0333 0300 1111 1211 0112 1112 2332 3303 3222 3221
1100 1111 2233
这相当于四进制表示了这18个字符与0x10异或之后的结果,手动将4进制字符转换成16进制字符:
再手动与0x10异或:
B9 BB B5
00 44 2F 20 45 75 06 46 AE E3 FA F9 40 45 BF
好的,重新进行18字符的修改:
http://s7/mw690/002S5apNgy6QNCqz1UWd6&690
然后就可以围观吃豆子的过程了……
http://s11/mw690/002S5apNgy6QNCqC8Oe3a&690
最后两步时候的截图,验证完成就弹框:
http://s1/mw690/002S5apNgy6QNCqHJOEc0&690
然后注册之后:
http://s7/mw690/002S5apNgy6QNCqOeRUd6&690
好吧,之前那个东西是你的用户名长度和字符,重新修改keyfile(这里会发现,异或的对象变了,是用户名字符和的最后一字节,重新异或下并修改,就OK了:
http://s3/mw690/002S5apNgy6QNCqUb6i12&690
加载中,请稍候......