此破解练习之所以称为另类 它和你输入的用户名无关 可能是作者不慎所造成的 bug 呵呵 太有意思了! 因为与注册名没有关
系那注册码是不是就是一个固定的字符串呢 呵呵 是呀 这么复杂(相对菜鸟)的算法 查几个表 又查了这么次 循环看着都晕
结果却不论你用什么用户名都一样 真是!
附件:crackme3.rar
好不费话了 说一下总结吧 首先在分析这个软件的算法循环的时候首先要弄清楚 几个值 [ebp-f4]、[422A30](d 422a30看一下 啊
这不是我输入的注册名吗 狂晕 把我输入的注册名都给覆盖了)、[423820](每次循环结果都放里了 循环如果结束 ? 423820 就可以看到
真注册码了)
给初学者出一题 把上面我的分析 给写中文 式子 表达一下它的注册码计算方法! 这样对你的算法是很有帮助的! 应该不是
很难 因为我的说明 很详细!
bpx GetDlgItemTextA 下断 下面是算法分析!
00401158 |. 6A 0C PUSH 0C ; /Count = C (12.)
0040115A |. 68 10384200 PUSH crackme3.00423810 ; |Buffer = crackme3.00423810
0040115F |. 68 E8030000 PUSH 3E8 ; |ControlID = 3E8 (1000.)
00401164 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; |
00401167 |. 50 PUSH EAX ; |hWnd
00401168 |. FF15 D8524200 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
0040116E |. 3BF4 CMP ESI,ESP ; 取用户输入的注册码
00401170 |. E8 BB030000 CALL crackme3.00401530
00401175 |. 8BF4 MOV ESI,ESP
00401177 |. 68 00020000 PUSH 200 ; /Count = 200 (512.)
0040117C |. 68 00384200 PUSH crackme3.00423800 ; |Buffer = crackme3.00423800
00401181 |. 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
00401186 |. 8B4D 08 MOV ECX,DWORD PTR SS:[EBP+8] ; |
00401189 |. 51 PUSH ECX ; |hWnd
0040118A |. FF15 D8524200 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00401190 |. 3BF4 CMP ESI,ESP ; 没有发现取用户输入的注册名 狂晕 难道是一个定值 完
全正确
00401192 |. E8 99030000 CALL crackme3.00401530
00401197 |. 8985 08FFFFFF MOV DWORD PTR SS:[EBP-F8],EAX
0040119D |. C785 0CFFFFFF>MOV DWORD PTR SS:[EBP-F4],0
004011A7 |. EB 0F JMP SHORT crackme3.004011B8 ; 下面注册码算法部份开始 仔细分析发现几乎没有和输入
的用户名有关 常用的变量[ebp-f4] 稍加分析就可以知道循环一次就加一 初值在上一行赋值为0 按它来取密码表 然后进行一些运算
004011A9 |> 8B95 0CFFFFFF /MOV EDX,DWORD PTR SS:[EBP-F4] ; 当前的取注册名的第几位 位数数给edx
004011AF |. 83C2 01 |ADD EDX,1 ; 把位数加一
004011B2 |. 8995 0CFFFFFF |MOV DWORD PTR SS:[EBP-F4],EDX ; 加一后的值存入ebp-f4的内存地址
004011B8 |> 8B85 0CFFFFFF MOV EAX,DWORD PTR SS:[EBP-F4] ; 在把位数给eax
004011BE |. 3B85 08FFFFFF |CMP EAX,DWORD PTR SS:[EBP-F8] ; 把总位数与当前比较
004011C4 |. 0F8D AB000000 |JGE crackme3.00401275 ; 全部计算完毕 则跳走
004011CA |. 8B8D 0CFFFFFF |MOV ECX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 ecx
004011D0 |. 0FBE91 742A42>|MOVSX EDX,BYTE PTR DS:[ECX+422A74] ; 按位数取crackme的ASC码 为什么是crackme 是d 422a74
看到的
004011D7 |. 8B85 0CFFFFFF |MOV EAX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 eax
004011DD |. 0FBE88 302A42>|MOVSX ECX,BYTE PTR DS:[EAX+422A30] ; 按位数取密码表 送入ecx 因为循环后值加1 所以依次取
第1个.2.3.4.....(d 422a30 可以看出是密码表)
004011E4 |. 23D1 |AND EDX,ECX ; 依次取的密码表 送入ecx 与 依次取crackme的ASC码 或
004011E6 |. 8B85 0CFFFFFF |MOV EAX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 eax
004011EC |. 8890 10384200 |MOV BYTE PTR DS:[EAX+423810],DL ; 把值依次送入423810 内存处保存 累加
004011F2 |. 8B8D 0CFFFFFF |MOV ECX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 ecx
004011F8 |. 8B95 0CFFFFFF |MOV EDX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 edx
004011FE |. 8A81 10384200 |MOV AL,BYTE PTR DS:[ECX+423810] ; 依次取密码表 送入ecx 与 依次取crackme的ASC码 或
的值给al (d 423810 可以看出是密码表)
00401204 |. 2282 742A4200 |AND AL,BYTE PTR DS:[EDX+422A74] ; 与上面依次取crackme的ASC码 或
0040120A |. 8B8D 0CFFFFFF |MOV ECX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 ecx
00401210 |. 8881 10384200 |MOV BYTE PTR DS:[ECX+423810],AL ; 把上面的值 给依次送入423810
00401216 |. 8B95 0CFFFFFF |MOV EDX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 edx
0040121C |. 8B85 0CFFFFFF |MOV EAX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 eax
00401222 |. 8A8A 10384200 |MOV CL,BYTE PTR DS:[EDX+423810] ; 把上面的值 给依次送入 cl
00401228 |. 3288 302A4200 |XOR CL,BYTE PTR DS:[EAX+422A30] ; 按位数查422a30密码表ASC 与423810内存的第“当前位数
”的值 异或
0040122E |. 8B95 0CFFFFFF |MOV EDX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 edx
00401234 |. 888A 10384200 |MOV BYTE PTR DS:[EDX+423810],CL ; 按上面异或值移到累加到 423810里 例:如423810原为
1234 cl为 5 移了之后就是把5加在1234后面成12345 此例适合前面的类似[edx +423810]
0040123A |. 8B85 0CFFFFFF |MOV EAX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 eax
00401240 |. 8A88 10384200 |MOV CL,BYTE PTR DS:[EAX+423810] ; 按位数取423810内存开始处的值 给cl 理解成依次取也行
因为每次都加1
00401246 |. 028D 0CFFFFFF |ADD CL,BYTE PTR SS:[EBP-F4] ; 上面的值 加上当前取的位数
0040124C |. 8B95 0CFFFFFF |MOV EDX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 edx
00401252 |. 888A 10384200 |MOV BYTE PTR DS:[EDX+423810],CL ; 把加上位置后的值依次送入 423810内存地址
00401258 |. 8B85 0CFFFFFF |MOV EAX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 eax
0040125E |. 8B8D 0CFFFFFF |MOV ECX,DWORD PTR SS:[EBP-F4] ; 把当前取的位数给 edx
00401264 |. 8A91 10384200 |MOV DL,BYTE PTR DS:[ECX+423810] ; 按位数从 423810 取值 送入 dl
0040126A |. 8890 20384200 |MOV BYTE PTR DS:[EAX+423820],DL ; 把值送入423820 下面一句是跳回循环 说明程序循环结束之
后 重要数据保存在这里 循环结束后可以 ? 432820 可以看到真注册码
00401270 |.^ E9 34FFFFFF \JMP crackme3.004011A9 ; 返回继续循环 下面的式子无用 因为真注册码有此循环形
成
00401275 |> 8BF4 MOV ESI,ESP
00401277 |. 68 20384200 PUSH crackme3.00423820 ; /<%ld> = 423820 (4339744.)
0040127C |. 68 2C004200 PUSH crackme3.0042002C ; |Format = "%ld"
00401281 |. 8D45 B0 LEA EAX,DWORD PTR SS:[EBP-50] ; |
00401284 |. 50 PUSH EAX ; |s
00401285 |. FF15 C4524200 CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
0040128B |. 83C4 0C ADD ESP,0C
0040128E |. 3BF4 CMP ESI,ESP
00401290 |. E8 9B020000 CALL crackme3.00401530
00401295 |. 8BF4 MOV ESI,ESP
00401297 |. 8D4D B0 LEA ECX,DWORD PTR SS:[EBP-50]
0040129A |. 51 PUSH ECX ; /String
0040129B |. FF15 A8514200 CALL DWORD PTR DS:[<&KERNEL32.lstrlenA>] ; \lstrlenA
004012A1 |. 3BF4 CMP ESI,ESP
004012A3 |. E8 88020000 CALL crackme3.00401530
004012A8 |. 83E8 01 SUB EAX,1
004012AB |. 50 PUSH EAX
004012AC |. 8D55 B0 LEA EDX,DWORD PTR SS:[EBP-50]
004012AF |. 52 PUSH EDX
004012B0 |. E8 50FDFFFF CALL crackme3.00401005
004012B5 |. 8BF4 MOV ESI,ESP
004012B7 |. 50 PUSH EAX ; /<%08X>
004012B8 |. 68 1C004200 PUSH crackme3.0042001C ; |Format = "plmm: 0x%08X"
004012BD |. 68 20384200 PUSH crackme3.00423820 ; |s = crackme3.00423820
004012C2 |. FF15 C4524200 CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
004012C8 |. 83C4 0C ADD ESP,0C
004012CB |. 3BF4 CMP ESI,ESP
004012CD |. E8 5E020000 CALL crackme3.00401530
004012D2 |. 8BF4 MOV ESI,ESP
004012D4 |. 68 00384200 PUSH crackme3.00423800 ; |Format = "4339744"
004012D9 |. 8D85 60FFFFFF LEA EAX,DWORD PTR SS:[EBP-A0] ; |
004012DF |. 50 PUSH EAX ; |s
004012E0 |. FF15 C4524200 CALL DWORD PTR DS:[<&USER32.wsprintfA>] ; \wsprintfA
004012E6 |. 83C4 08 ADD ESP,8
004012E9 |. 3BF4 CMP ESI,ESP
004012EB |. E8 40020000 CALL crackme3.00401530
004012F0 |. 8BF4 MOV ESI,ESP
004012F2 |. 8D4D B0 LEA ECX,DWORD PTR SS:[EBP-50]
004012F5 |. 51 PUSH ECX ; /String2
004012F6 |. 8D95 60FFFFFF LEA EDX,DWORD PTR SS:[EBP-A0] ; |
004012FC |. 52 PUSH EDX ; |String1
004012FD |. FF15 A4514200 CALL DWORD PTR DS:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
00401303 |. 3BF4 CMP ESI,ESP
00401305 |. E8 26020000 CALL crackme3.00401530
0040130A |. 85C0 TEST EAX,EAX
0040130C |. 75 35 JNZ SHORT crackme3.00401343 ; 关键跳 如跳程序就退出了! 不跳提示成功 爆破点
0040130E |. 8BF4 MOV ESI,ESP
00401310 |. 8D85 10FFFFFF LEA EAX,DWORD PTR SS:[EBP-F0]
感谢你看完此文!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!