crackme下载地址:http://www.pediy.com/tutorial/chap6/Exercise/section01/chap6-1-1-02.zip
再一次带来习题的破解,今天的算法有些特别。同样,菜鸟留步,老鸟飘过……
第一步查壳:
没有壳,事实上一般的crackme都不会加壳
第二步试运行:
随便输入点什么,点ok,会弹出对话框
第三步:OD载入
查找字符串,在wrong s/n#行双击跟随,来到这
往上翻翻,我们要找到会跳向这一段的跳转
004011B1 /75 1E jnz short crackme5.004011D1
就是这个了,把这里的jnz改为je也许能爆破成功,不过我没试验,我们的目标是注册码!!!
通常这样的跳转上面必有call,我们找找
004011A9 E8 5D000000 call crackme5.0040120B
应该就是这个,call的作用一般是将我们输入的假码进行一系列运算,然后和真码或者经过运算的真码进行比对,如果不等就会用jnz跳到出错的地方去。
在这行call上F2下断,F9运行
程序又跑起来了,随便输入,我这里就12345678了,点一下ok,OD自己断下来了
F7跟进这个call看看
看到注释栏里有一行写着“ASCII"12345678"”,这里应该就是算法的核心了,go on……
F8一步步运行,可以看到这里有一行跳转
00401213 B8 A6204000 mov eax,crackme5.004020A6 ; ASCII "12345678",将假码存入eax
00401218 8038 00 cmp byte ptr ds:[eax],0
0040121B 74 60 je short crackme5.0040127D
这是判断我们是否输入的,如果没有输入,也就是这时的eax=00000000,这里的跳转就会实现,自然会跳到出错的地方去,你可以试试前面不输入假码,看看这里的跳转是否会实现(这里的箭头变成红色就表示跳转实现)
00401221 8A18 mov bl,byte ptr ds:[eax] ; eax(也就是我们之前存入假码的地方)的头一位送入bl,注意看ebx值的变化
00401223 C1C3 08 rol ebx,8 ; 移位操作,可以看到上一步的操作之后ebx的值已经变成00000031(即bl=31,ASCII"1"的16进制值)
00401226 03D3 add edx,ebx ; 相加,结果送入edx,可以看到这时的ebx=00003100,也要注意edx值的变化
00401228 40 inc eax ; eax+1,作用是与下面的跳转组成循环,依次取假码的每一位
00401229 8038 00 cmp byte ptr ds:[eax],0 ; 判断假码是否依次取完
0040122C ^ 75 F3 jnz short crackme5.00401221 ; 我们的假码只有8位,所以八次循环后,这里的跳转便不再实现
这里你也许会问,rol是什么?其实我也不知道,Google一下,循环左移,还是不懂。不管它了,F8一下,看一下ebx值的变化,由00000031变成了00003100,这下明白了吧。
简单分析一下,这一段循环的作用是处理假码,循环完成后,edx里就存着经过处理的假码了,这时的edx=366DA4FF
第一次循环后,ebx=00003100,edx=00003100+00000000=00003100
第二次循环后,ebx=00313200,edx=00313200+00003100=00316300(假码的第二位也开始代入运算,edx=这一次的ebx+上一次算出的edx)
第三次循环后,ebx=31323300,edx=31323300+00316300=31639600
第四次循环后,ebx=32333431,edx=32333431+31639600=6396CA31(注意31又移位到了尾端,即bl处)
第五次循环后,ebx=33343532,edx=33343532+6396CA31=96CAFF63(31不见了?这是因为在执行00401221 8A18 mov bl,byte ptr ds:[eax] 这一步,即移位的前一步时,bl处的31被35覆盖了)
第六次循环后,ebx=34353633,edx=34353633+96CAFF63=CB003596
第七次循环后,ebx=35363734,edx=35363734+CB003596=100366CCA
第八次循环后,ebx=36373835,edx=36373835+100366CCA=1366DA4FF(实际上只会显示为366DA4FF)
继续F8
经过一个call后,可以看到这一行的注释栏里写着“ASCII"366DA4FF"”,说明这个call的作用就是将Hex(16进制)值转换成(说直接写成应该更好理解)ASCII
接着就是连续的比较和跳转了,其实是将ASCII"366DA4FF"(经过一个mov已经存入ebx)的每一位与一个值比较,不等则跳到出错的地方
还记得我们上面提到将那个jnz改为je就能爆破了?现在看来是不对的,须将这里所有的jnz一并改为je
现在我们得到一组数值:38 44 43 41 46 33 36 38 ,这是真码经过处理后得到的,其表示的ASCII字符串为"8DCAF368"(http://www.pediy.com/tutorial/appen-a/append-A.htm,这里可以直接查询,例如,38h-->56-->"8"),也就是说,真码经过前面的循环运算后,edx=8DCAF368
我们还不知道真码的位数,不妨多假设
真码为3位的情况:X1 X2 X3 ,则经过循环计算后edx= X1 X1+x2 X1+X2+X3 00
真码为4位的情况:X1 X2 X3 X4,则edx= X1+X2 X1+X2+X3 X1+X2+X3+X4 X1
真码为5位的情况:X1 X2 X3 X4 X5,则edx= X1+X2+X3 X1+X2+X3+X4 X1+X2+X3+X4+X5 X1+X2
依此类推……
我们很容易看出真码至少4位,且由edx=8D CA F3 68 ,逐位比较,算出真码的后三位分别为25(即8D-68) 3D(即CA-8D) 29(即F3-CA),且前面几位的和为68
好了,到这里也基本解决了,注册码其实只要不少于4位就好,我们这里不妨试一下5位的,68=32+36,我们的注册码也就是32 36 25 3D 29 ,即ASCII"26%=)",将26%=)填入对话框,Bingo!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)