crackme下载地址:
7dfK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4m8W2k6r3W2&6i4K6u0W2j5$3!0E0i4K6u0r3N6s2g2@1L8%4u0A6j5h3I4Q4x3V1k6U0K9r3q4H3y4W2)9J5c8V1g2^5k6i4u0U0K9i4y4W2i4K6u0r3M7$3g2U0N6r3W2G2L8U0l9I4i4K6u0r3j5$3S2S2M7o6k6Q4x3X3b7I4i4K6u0V1x3g2)9J5k6o6l9J5i4K6u0W2P5X3W2H3
再一次带来习题的破解,今天的算法有些特别。同样,菜鸟留步,老鸟飘过……
第一步查壳:
没有壳,事实上一般的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"(
63dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6i4m8W2k6r3W2&6i4K6u0W2j5$3!0E0i4K6u0r3N6s2g2@1L8%4u0A6j5h3I4Q4x3V1k6S2M7s2m8W2L8W2)9J5k6r3q4Q4x3V1k6S2M7s2m8W2L8X3c8Q4x3X3c8m8i4K6u0W2K9s2c8E0i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1^5i4@1u0r3i4K6V1&6i4@1f1&6i4K6R3%4i4K6S2o6i4@1f1#2i4K6S2r3i4@1q4r3i4@1f1@1i4@1u0n7i4@1p5#2i4@1f1%4i4K6W2n7i4@1t1@1i4@1f1$3i4K6S2q4i4@1p5#2i4@1f1$3i4K6W2r3i4@1p5#2i4@1f1^5i4@1q4r3i4@1p5J5i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1@1i4@1u0q4i4K6S2n7i4@1f1#2i4@1p5$3i4K6R3J5i4@1g2r3i4@1u0o6i4K6S2o6x3K6S2Z5i4K6u0V1i4K6u0V1i4K6t1$3k6%4c8Q4x3@1t1#2y4W2)9J5k6q4)9J5k6q4)9J5y4X3N6@1i4K6y4n7"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!
[培训]科锐逆向工程师培训第53期2025年7月8日开班!