1.暴力破解
1.使用PE工具查看有无壳,发现无壳
2.使用OD,由于是无壳程序,查看字符串,发现可用点
3.点击字符串按回车进入反汇编,发现存在跳转:jnz是结果不为0(或不相等则转移),可以推测这里在这个跳转之前有一个判断,是我们输入的结果如果是不正确,程序就会跳到失败的那一部分,由于这里是爆破,将jnz使用NOP填充,程序就只会弹出成功的窗口
4.这个程序有两个弹窗,都可以用同样的方法爆破。
5.回过头破解弹窗,同样查看字符串,看有没有利用点
6.发现没有利用点,那么在字符串的反汇编窗口设置断点,将程序运行到断点,然后单步调试,如果弹窗弹窗弹出,就需要一步步跟进
7.跟进了N步没有发现,使用查找API的方法,由于弹窗一般是使用的messagebox这个api,那么可以通过查找这个api定位弹窗。在命令窗口输入bpx messageboxA找到api将其断点,然后将程序执行,跑到断点的位置。这里需要注意,可能会中断多个messagebox函数,因为这个程序的主题就是一个窗口,因为一开始弹窗最先加载,那么第一个massagebox很可能就是我们需要找的弹窗,当然,这个需要我们去验证
8.运行发现右下角窗口有出现弹窗的字符串,发现有四个数值,对比反汇编窗口中,在messageboxA的CALL上面有四个push,这里是将这四个数值压入栈中,然后由CALL调用,那么可以推测这个call就是调用弹窗的,我们将四个push和call执行nop,就可以跳过开始的弹窗了。
9.到此为止,这个程序中所有内容爆破完毕。
2.逆向分析
1.Serial部分
通过字符串查找,发现爆破点的jnz上面有一个call,猜测可能是返回的数值,由返回的数值决定我们输入的正确与否,可以尝试在call下断点,然后运行程序,输入任意假码
运行程序发现程序还没有返回结果,而且程序是断在了jnz上面的call,那么我们设置的断点很可能是正确的,此时还可以关注寄存器窗口,接下来F7进入call查看
进入call后发现,函数首先压入三个寄存器中的数值,其中就有我们输入的假码,而且在下面就有一个cmp的比较命令,之后就是一个je(相等就跳转)的比较,点击je发现,如果je实现跳转,那么会调到三个pop,然后retn,也就是说,在这个call的一开始就进行了比较。通过查看寄存器发现,我们输入的假码是与Hello Dude!比较的,也就是说,这个就是我们要找的真码。
尝试验证:发现结论是正确的
2.Serial/name部分
1.先和上面一样使用同样的方法断点,尝试运行,发现程序没有停下来,二十直接判断我们错误,那么这个部分的判断可能是在别的地方,我们需要在jnz处向上查找,发现到达0042FA52时有一个比较是用户名与4相比,也就是用户名是要大于或等于4,不然会直接跳出错误窗口
接来下可以和serial部分一样,在爆破点上的call下断点,查看真码
输入不同的用户名,发现用户名不同,真码中间的数字会改变,接下来分析数值是怎么得来的
0042FA87 8B45 F0 mov eax,dword ptr ss:[ebp-10] ;eax的地址
0042FA8A 0FB600 movzx eax,byte ptr ds:[eax] ;第一个字节1=0x31
0042FA8D F72D 50174300 imul dword ptr ds:[431750] *0x29
0042FA93 A3 50174300 mov dword ptr ds:[431750],eax Eax=0x31*0x29=0x7d9
0042FA98 A1 50174300 mov eax,dword ptr ds:[431750]
0042FA9D 0105 50174300 add dword ptr ds:[431750],eax Eax+eax
0042FAA3 8D45 FC lea eax,dword ptr ss:[ebp-4]
第一个字符对应的16进制数字乘0x29在自增一次