【破文作者】 rdsnow[BCG][PYG][D.4s]
【作者主页】 http://rdsnow.ys168.com
【 E-mail 】 [email]rdsnow@163.com[/email]
【 作者QQ 】 83757177
【文章题目】 变形的 MD5
【软件名称】 AutoRunPro Enterprise
【软件版本】 V4.0.0.32
【下载地址】 http://www.longtion.com
----------------------------------------------------------------------------------------
【加密方式】 序列号
【破解工具】 ODbyDYK v1.10[05.09]
【软件限制】 功能限制
【破解平台】 Microsoft Windows XP Professional
【平台版本】 5.1.2600 Service Pack 2 内部版本号 2600
----------------------------------------------------------------------------------------
【软件简介】
AutoRun Pro Enterprise can create, edit professional autorun interface and generate autorun files for CD/DVDs in a WYSIWYG environment.
Display a professional and beautiful interface for users to open or execute files, print documents, send e-mail, visit Web sites, browse CDs,
play sound, music and so on, when your CD is inserted. It's fast and easy to use. Anyone can quickly create autorun CD-ROMs within minutes.
【文章简介】
我编程只有5、6年前学习的一点 turbo c 的基础,为了学习编程,一般的程序都是尽可能的学出 keygen ,这下遇到了个采用变形 MD5 算法的软件,也来试了下。
给变形的 MD5 的程序要写出 keygen ,必须找到变形的地方,然后在标准 MD5 源码中作出相应的修改。
----------------------------------------------------------------------------------------
【破解过程】
程序注册窗口要输入三个编辑框:username,serial 和 key,从后面代码看出 serial 的前四位必须是 "0018"
所以输入:
username= rdsnow[BCG][PYG][D.4s]
serial = 001812345678cdef
key = 9898989832323232
因为有注册码错误的对话框,所以很容易找到关键的地方。
00562BD2 . 8B83 14030000 MOV EAX,DWORD PTR [EBX+314]
00562BD8 . E8 3F78F1FF CALL AutoRunP.0047A41C ; 取得 username
00562BDD . 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
00562BE0 . 8D55 FC LEA EDX,DWORD PTR [EBP-4]
00562BE3 . E8 8460EAFF CALL AutoRunP.00408C6C
00562BE8 . 8D55 E0 LEA EDX,DWORD PTR [EBP-20]
00562BEB . 8B83 F8020000 MOV EAX,DWORD PTR [EBX+2F8]
00562BF1 . E8 2678F1FF CALL AutoRunP.0047A41C ; 取得 serial
00562BF6 . 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
00562BF9 . 8D55 F8 LEA EDX,DWORD PTR [EBP-8]
00562BFC . E8 6B60EAFF CALL AutoRunP.00408C6C
00562C01 . 8D55 DC LEA EDX,DWORD PTR [EBP-24]
00562C04 . 8B83 FC020000 MOV EAX,DWORD PTR [EBX+2FC]
00562C0A . E8 0D78F1FF CALL AutoRunP.0047A41C ; 取得 key
00562C0F . 8B45 DC MOV EAX,DWORD PTR [EBP-24]
00562C12 . 8D55 F4 LEA EDX,DWORD PTR [EBP-C]
00562C15 . E8 5260EAFF CALL AutoRunP.00408C6C
00562C1A . 8B45 F4 MOV EAX,DWORD PTR [EBP-C]
00562C1D . 50 PUSH EAX ; 压入 key
00562C1E . A1 709E5600 MOV EAX,DWORD PTR [569E70]
00562C23 . 8B00 MOV EAX,DWORD PTR [EAX]
00562C25 . 8B4D F8 MOV ECX,DWORD PTR [EBP-8] ; serial
00562C28 . 8B55 FC MOV EDX,DWORD PTR [EBP-4] ; username
00562C2B . E8 5466FFFF CALL AutoRunP.00559284 ; 关键 CALL
00562C30 . 84C0 TEST AL,AL
00562C32 . 75 1D JNZ SHORT AutoRunP.00562C51 ; 关键跳转
00562C34 . 6A 10 PUSH 10
00562C36 . B9 602D5600 MOV ECX,AutoRunP.00562D60 ; ASCII "Register"
00562C3B . BA 6C2D5600 MOV EDX,AutoRunP.00562D6C ; ASCII "Incomplete or incorrect information."
00562C40 . A1 5CA15600 MOV EAX,DWORD PTR [56A15C]
00562C45 . 8B00 MOV EAX,DWORD PTR [EAX]
00562C47 . E8 788DF3FF CALL AutoRunP.0049B9C4 ; 错误的对话框
00562C4C . E9 C8000000 JMP AutoRunP.00562D19
00562C51 > 33C0 XOR EAX,EAX
如果是爆破,不建议在 00562C32 关键跳转处改跳转,应该跟进关键 CALL , 修改注册标志
----------------------------------------------------------------------------------------
下面就跟进吧:
005592F5 . 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
005592F8 . E8 F7B3EAFF CALL AutoRunP.004046F4 ; 取 Serial 的长度
005592FD . 8BD8 MOV EBX,EAX
005592FF . 83FB 01 CMP EBX,1
00559302 . 7C 1E JL SHORT AutoRunP.00559322 ; Serial 为空就跳走
00559304 > 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
00559307 . 807C18 FF 20 CMP BYTE PTR [EAX+EBX-1],20
0055930C . 75 0F JNZ SHORT AutoRunP.0055931D
0055930E . 8D45 E4 LEA EAX,DWORD PTR [EBP-1C]
00559311 . B9 01000000 MOV ECX,1
00559316 . 8BD3 MOV EDX,EBX
00559318 . E8 77B6EAFF CALL AutoRunP.00404994 ; 去掉 Serial 中的空格
0055931D > 4B DEC EBX
0055931E . 85DB TEST EBX,EBX
00559320 .^ 75 E2 JNZ SHORT AutoRunP.00559304
00559322 > 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
00559325 . E8 CAB3EAFF CALL AutoRunP.004046F4 ; 取 key 的长度
0055932A . 8BD8 MOV EBX,EAX
0055932C . 83FB 01 CMP EBX,1
0055932F . 7C 1E JL SHORT AutoRunP.0055934F ; key 为空就跳走
00559331 > 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
00559334 . 807C18 FF 20 CMP BYTE PTR [EAX+EBX-1],20
00559339 . 75 0F JNZ SHORT AutoRunP.0055934A
0055933B . 8D45 E0 LEA EAX,DWORD PTR [EBP-20]
0055933E . B9 01000000 MOV ECX,1
00559343 . 8BD3 MOV EDX,EBX
00559345 . E8 4AB6EAFF CALL AutoRunP.00404994 ; 去掉 key 中的空格
0055934A > 4B DEC EBX
0055934B . 85DB TEST EBX,EBX
0055934D .^ 75 E2 JNZ SHORT AutoRunP.00559331
0055934F > 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
00559352 . E8 9DB3EAFF CALL AutoRunP.004046F4 ; 取 Serial 的长度
00559357 . 83F8 10 CMP EAX,10
0055935A . 0F85 98010000 JNZ AutoRunP.005594F8 ; Serial 的长度不等于 16 就跳走
00559360 . 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
00559363 . E8 8CB3EAFF CALL AutoRunP.004046F4 ; 取 key 的长度
00559368 . 83F8 10 CMP EAX,10
0055936B . 0F85 87010000 JNZ AutoRunP.005594F8 ; key 的长度不等于 16 就跳走
00559371 . 33C0 XOR EAX,EAX
00559373 . 55 PUSH EBP
00559374 . 68 4B945500 PUSH AutoRunP.0055944B
00559379 . 64:FF30 PUSH DWORD PTR FS:[EAX]
0055937C . 64:8920 MOV DWORD PTR FS:[EAX],ESP
0055937F . 8D45 D4 LEA EAX,DWORD PTR [EBP-2C]
00559382 . 50 PUSH EAX
00559383 . B9 08000000 MOV ECX,8
00559388 . BA 01000000 MOV EDX,1
0055938D . 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
00559390 . E8 BFB5EAFF CALL AutoRunP.00404954 ; 取 Serial 的前 8 个字符
00559395 . 8B4D D4 MOV ECX,DWORD PTR [EBP-2C]
00559398 . 8D45 D8 LEA EAX,DWORD PTR [EBP-28]
0055939B . BA 3C955500 MOV EDX,AutoRunP.0055953C
005593A0 . E8 9BB3EAFF CALL AutoRunP.00404740 ; 准备转换
005593A5 . 8B45 D8 MOV EAX,DWORD PTR [EBP-28]
005593A8 . E8 63FCEAFF CALL AutoRunP.00409010 ; 将 8 个字符组成的 Hex 文本转为数值 a
005593AD . 8945 F8 MOV DWORD PTR [EBP-8],EAX ; 保存 a 进 inbuff
005593B0 . 8D45 CC LEA EAX,DWORD PTR [EBP-34]
005593B3 . 50 PUSH EAX
005593B4 . B9 08000000 MOV ECX,8
005593B9 . BA 09000000 MOV EDX,9
005593BE . 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
005593C1 . E8 8EB5EAFF CALL AutoRunP.00404954 ; 取 Serial 的后 8 个字符
005593C6 . 8B4D CC MOV ECX,DWORD PTR [EBP-34]
005593C9 . 8D45 D0 LEA EAX,DWORD PTR [EBP-30]
005593CC . BA 3C955500 MOV EDX,AutoRunP.0055953C
005593D1 . E8 6AB3EAFF CALL AutoRunP.00404740 ; 准备转换
005593D6 . 8B45 D0 MOV EAX,DWORD PTR [EBP-30]
005593D9 . E8 32FCEAFF CALL AutoRunP.00409010 ; 将 8 个字符组成的 Hex 文本转为数值 b
005593DE . 8945 F4 MOV DWORD PTR [EBP-C],EAX ; 保存 b 进入 inbuff
005593E1 . 8D45 C4 LEA EAX,DWORD PTR [EBP-3C]
005593E4 . 50 PUSH EAX
005593E5 . B9 08000000 MOV ECX,8
005593EA . BA 01000000 MOV EDX,1
005593EF . 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
005593F2 . E8 5DB5EAFF CALL AutoRunP.00404954 ; 取 key 的前 8 个字符
005593F7 . 8B4D C4 MOV ECX,DWORD PTR [EBP-3C]
005593FA . 8D45 C8 LEA EAX,DWORD PTR [EBP-38]
005593FD . BA 3C955500 MOV EDX,AutoRunP.0055953C
00559402 . E8 39B3EAFF CALL AutoRunP.00404740 ; 准备转换
00559407 . 8B45 C8 MOV EAX,DWORD PTR [EBP-38]
0055940A . E8 01FCEAFF CALL AutoRunP.00409010 ; 将 8 个字符组成的 Hex 文本转为数值 c
0055940F . 8BD8 MOV EBX,EAX ; c 保存到 EBX
00559411 . 8D45 BC LEA EAX,DWORD PTR [EBP-44]
00559414 . 50 PUSH EAX
00559415 . B9 08000000 MOV ECX,8
0055941A . BA 09000000 MOV EDX,9
0055941F . 8B45 E0 MOV EAX,DWORD PTR [EBP-20]
00559422 . E8 2DB5EAFF CALL AutoRunP.00404954 ; 取 key 的后 8 个字符
00559427 . 8B4D BC MOV ECX,DWORD PTR [EBP-44]
0055942A . 8D45 C0 LEA EAX,DWORD PTR [EBP-40]
0055942D . BA 3C955500 MOV EDX,AutoRunP.0055953C
00559432 . E8 09B3EAFF CALL AutoRunP.00404740 ; 准备转换
00559437 . 8B45 C0 MOV EAX,DWORD PTR [EBP-40]
0055943A . E8 D1FBEAFF CALL AutoRunP.00409010 ; 将 8 个字符组成的 Hex 文本转为数值 d
0055943F . 8BF0 MOV ESI,EAX ; d 保存到 ESI
00559441 . 33C0 XOR EAX,EAX
00559443 . 5A POP EDX
00559444 . 59 POP ECX
00559445 . 59 POP ECX
00559446 . 64:8910 MOV DWORD PTR FS:[EAX],EDX
00559449 . EB 14 JMP SHORT AutoRunP.0055945F
0055944B .^ E9 90A6EAFF JMP AutoRunP.00403AE0
00559450 . E8 F3A9EAFF CALL AutoRunP.00403E48
00559455 . E9 9E000000 JMP AutoRunP.005594F8
0055945A . E8 E9A9EAFF CALL AutoRunP.00403E48
0055945F > 8B45 F4 MOV EAX,DWORD PTR [EBP-C] ; 取出 b
00559462 . 83E0 0F AND EAX,0F ; 取 b 的低 4 位
00559465 . 8945 DC MOV DWORD PTR [EBP-24],EAX ; 保存,他会作为其中一个注册标志,不要等于0
00559468 . 8B45 F8 MOV EAX,DWORD PTR [EBP-8] ; 取出 a
0055946B . C1E8 10 SHR EAX,10 ; 取 a 的高 16 位
0055946E . 66:83F8 18 CMP AX,18
00559472 . 0F85 80000000 JNZ AutoRunP.005594F8 ; a 的高 16 位不等于 0x18 就跳
00559478 . 8B45 F8 MOV EAX,DWORD PTR [EBP-8] ; 取 a
0055947B . 8945 F0 MOV DWORD PTR [EBP-10],EAX ; 保存 a 进 inbuff
0055947E . 8B45 F4 MOV EAX,DWORD PTR [EBP-C] ; 取 b
00559481 . 8945 EC MOV DWORD PTR [EBP-14],EAX ; 保存 b 进 inbuff
00559484 . 8B45 F8 MOV EAX,DWORD PTR [EBP-8] ; 取 a
00559487 . 25 FFFF0000 AND EAX,0FFFF ; 取 a 的低 16 位
0055948C . 8BF8 MOV EDI,EAX
0055948E . C1E7 10 SHL EDI,10 ; 放在 32 位数据的高 16 位
00559491 . 8B45 F4 MOV EAX,DWORD PTR [EBP-C] ; 取 b 的高 16 位
00559494 . C1E8 10 SHR EAX,10 ; 放在 32 位数据的低 16 位
00559497 . 03F8 ADD EDI,EAX ; a 的高 16 位 和 b 的低 16 位拼成一个 32 位数值
00559499 . 8D45 EC LEA EAX,DWORD PTR [EBP-14]
0055949C . 50 PUSH EAX ; 此时 inbuff 在内存中显示成 b a b a
0055949D . 8D4D F0 LEA ECX,DWORD PTR [EBP-10]
005594A0 . 8D55 F4 LEA EDX,DWORD PTR [EBP-C]
005594A3 . 8D45 F8 LEA EAX,DWORD PTR [EBP-8]
005594A6 . E8 295DFCFF CALL AutoRunP.0051F1D4 ; b a b a 组成的 128 位进行 MD5 编码
005594AB . 3B5D F8 CMP EBX,DWORD PTR [EBP-8] ; c 跟 MD5 结果的前 32 位比较
005594AE . 75 11 JNZ SHORT AutoRunP.005594C1
005594B0 . 3B75 F4 CMP ESI,DWORD PTR [EBP-C] ; d 跟 MD5 结果的 32 - 64 位比较
005594B3 . 75 0C JNZ SHORT AutoRunP.005594C1 ; 即 key 跟 MD5 结果的前 64 位比较
005594B5 . 8B45 E8 MOV EAX,DWORD PTR [EBP-18] ; 取 name
005594B8 . E8 FF5BFCFF CALL AutoRunP.0051F0BC ; 计算 serial
005594BD . 3BF8 CMP EDI,EAX
005594BF . 74 04 JE SHORT AutoRunP.005594C5
005594C1 > 33C0 XOR EAX,EAX ; = 0
005594C3 . EB 02 JMP SHORT AutoRunP.005594C7
005594C5 > B0 01 MOV AL,1 ; = 1
005594C7 > 8845 FF MOV BYTE PTR [EBP-1],AL ; 保存注册标志
005594CA . 807D FF 00 CMP BYTE PTR [EBP-1],0 ; 判断注册标志是不是 0
005594CE . 74 28 JE SHORT AutoRunP.005594F8
005594D0 . 837D DC 00 CMP DWORD PTR [EBP-24],0 ; 判断另外一个注册标志是不是 0
005594D4 . 75 0A JNZ SHORT AutoRunP.005594E0
程序是这样判断的:serial 和 key 都是 16 个字符组成。
1、看 serial 的前 4 位是不是 "0018",serial 的最后一位不能是 '0'
2、将 serial 填充到 inbuff 中,注意,因为程序是用 dword 传送的,所以内存中低位在前,高位在后,我的 serial 在buff 中显示成:
0012F104 EF CD 78 56 34 12 18 00 EF CD 78 56 34 12 18 00 锿xV4.锿xV4.
3、inbuff 中数据进行变形 MD5 编码,得到
0012F104 E5 F9 0F 72 A3 46 9E 09 B2 5A AB E3 43 EE 3D 3F 妁rF?糙?C??
4、这个结果从后面开始的 3F 3D EE 43 AB 5A B2 09 组成的字符串 "3F3DEE43AB5AB209" 是个符合要求的 key 是个符合要求的 serial,但是这个时候 serial 还没有
得到验证,所以用 serial 生成的 key 只能躲过第一次跳转。
5、程序把 serial 的验证放在最后。
----------------------------------------------------------------------------------------
大致跟了下 serial 的生成,前四位必须是 "0018" ,中间 8 个字符由 username 生成,最后四位任意。
跟进,在005594B8 CALL AutoRunP.0051F0BC 来到:
0051F0E6 |. 8B45 EC MOV EAX,DWORD PTR [EBP-14]
0051F0E9 |. E8 0656EEFF CALL AutoRunP.004046F4 ; 取 name 的长度 Length
0051F0EE |. 25 07000080 AND EAX,80000007 ; 长度 % 8 ,准备下面消息分组
0051F0F3 |. 79 05 JNS SHORT AutoRunP.0051F0FA
0051F0F5 |. 48 DEC EAX
0051F0F6 |. 83C8 F8 OR EAX,FFFFFFF8
0051F0F9 |. 40 INC EAX
0051F0FA |> BA 08000000 MOV EDX,8
0051F0FF |. 2BD0 SUB EDX,EAX ; 8 - 余数 = 在用户名的后面添加 0 的个数
0051F101 |. 8BC2 MOV EAX,EDX
0051F103 |. 8BD8 MOV EBX,EAX
0051F105 |. 85DB TEST EBX,EBX
0051F107 |. 7E 10 JLE SHORT AutoRunP.0051F119
0051F109 |> 8D45 EC / LEA EAX,DWORD PTR [EBP-14]
0051F10C |. BA B0F15100 | MOV EDX,AutoRunP.0051F1B0
0051F111 |. E8 E655EEFF | CALL AutoRunP.004046FC ; 在用户名信息后面添加 0
0051F116 |. 4B | DEC EBX
0051F117 |.^ 75 F0 \ JNZ SHORT AutoRunP.0051F109
这个地方要小心的是即使用户名本身的长度是 8 的倍数,也会在后面加上 8 个0,不是 8 的倍数,正好通过补 0 ,补 0 后的用户名的长度应该是 8 的倍数。
0051F119 |> 8B45 EC MOV EAX,DWORD PTR [EBP-14]
0051F11C |. E8 D355EEFF CALL AutoRunP.004046F4
0051F121 |. 33D2 XOR EDX,EDX
0051F123 |. 8955 FC MOV DWORD PTR [EBP-4],EDX
0051F126 |. 33D2 XOR EDX,EDX
0051F128 |. 8955 F8 MOV DWORD PTR [EBP-8],EDX
0051F12B |. 8BD8 MOV EBX,EAX
0051F12D |. 85DB TEST EBX,EBX
0051F12F |. 79 03 JNS SHORT AutoRunP.0051F134
0051F131 |. 83C3 07 ADD EBX,7
0051F134 |> C1FB 03 SAR EBX,3
0051F137 |. 4B DEC EBX
0051F138 |. 85DB TEST EBX,EBX
0051F13A |. 7C 3E JL SHORT AutoRunP.0051F17A
0051F13C |. 43 INC EBX
0051F13D |. 33F6 XOR ESI,ESI
0051F13F |> 8D45 E8 / LEA EAX,DWORD PTR [EBP-18]
0051F142 |. 50 | PUSH EAX
0051F143 |. 8BD6 | MOV EDX,ESI
0051F145 |. C1E2 03 | SHL EDX,3
0051F148 |. 42 | INC EDX
0051F149 |. B9 08000000 | MOV ECX,8
0051F14E |. 8B45 EC | MOV EAX,DWORD PTR [EBP-14]
0051F151 |. E8 FE57EEFF | CALL AutoRunP.00404954 ; 取出分组后的各组消息,每组 8 个字符
0051F156 |. 8B45 E8 | MOV EAX,DWORD PTR [EBP-18]
0051F159 |. 8D4D F0 | LEA ECX,DWORD PTR [EBP-10]
0051F15C |. 8D55 F4 | LEA EDX,DWORD PTR [EBP-C]
0051F15F |. E8 D0FEFFFF | CALL AutoRunP.0051F034 ; 将得到的 8 个字符顺序颠倒,并填入 inbuff 息的高64位
0051F164 |. 8D45 F0 | LEA EAX,DWORD PTR [EBP-10]
0051F167 |. 50 | PUSH EAX
0051F168 |. 8D4D F4 | LEA ECX,DWORD PTR [EBP-C]
0051F16B |. 8D55 F8 | LEA EDX,DWORD PTR [EBP-8]
0051F16E |. 8D45 FC | LEA EAX,DWORD PTR [EBP-4]
0051F171 |. E8 5E000000 | CALL AutoRunP.0051F1D4 ; MD5( inbuff )
0051F176 |. 46 | INC ESI
0051F177 |. 4B | DEC EBX
0051F178 |.^ 75 C5 \ JNZ SHORT AutoRunP.0051F13F
0051F17A |> 8B5D FC MOV EBX,DWORD PTR [EBP-4]
0051F17D |. 33C0 XOR EAX,EAX
这里就是将 用户名添 0 后成 8 字节的倍数,然后分成 n 组,分别用每一组消息修改 inbuff 的前 8 个字节,然后进行 MD5 编码,循环 n 次。
----------------------------------------------------------------------------------------
要写出 keygen ,必须跟进 CALL AutoRunP.0051F034 ,跟进 MD5 函数
0051F1FF |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
0051F202 |. C745 E4 6745> MOV DWORD PTR [EBP-1C],1234567 ; 传递四个链接变量(已经变形)
0051F209 |. C745 E8 EFCD> MOV DWORD PTR [EBP-18],89ABCDE>
0051F210 |. C745 EC DCFE> MOV DWORD PTR [EBP-14],BA98FED>
0051F217 |. C745 F0 2143> MOV DWORD PTR [EBP-10],7650432>
★★★★★ 变形1 ★★★★★
这里已经不是:
A = 0x67452301
B = 0xefcdab89
C = 0x98badcfe
D = 0x10325476
找到一个变形
0051F21E |. 8B45 F0 MOV EAX,DWORD PTR [EBP-10]
0051F221 |. 8903 MOV DWORD PTR [EBX],EAX ; 复制四个链接变量的副本
0051F223 |. 8B45 EC MOV EAX,DWORD PTR [EBP-14]
0051F226 |. 8906 MOV DWORD PTR [ESI],EAX ; 复制四个链接变量的副本
0051F228 |. 8B45 E8 MOV EAX,DWORD PTR [EBP-18]
0051F22B |. 8907 MOV DWORD PTR [EDI],EAX ; 复制四个链接变量的副本
0051F22D |. 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
0051F230 |. 8945 D4 MOV DWORD PTR [EBP-2C],EAX ; 复制四个链接变量的副本
0051F233 |. 6A 10 PUSH 10
0051F235 |. 8D45 D0 LEA EAX,DWORD PTR [EBP-30]
0051F238 |. B9 01000000 MOV ECX,1
0051F23D |. 8B15 B4F15100 MOV EDX,DWORD PTR [51F1B4] ; AutoRunP.0051F1B8
0051F243 |. E8 7465EEFF CALL AutoRunP.004057BC
0051F248 |. 83C4 04 ADD ESP,4 ; 下面将 128 位信息填充成 512 位
0051F24B |. 8B45 FC MOV EAX,DWORD PTR [EBP-4]
0051F24E |. 8B00 MOV EAX,DWORD PTR [EAX]
0051F250 |. 8B55 D0 MOV EDX,DWORD PTR [EBP-30]
0051F253 |. 8902 MOV DWORD PTR [EDX],EAX ; 填充
……………………(总共有16个填充)
0051F2EF |. 8B45 FC MOV EAX,DWORD PTR [EBP-4]
0051F2F2 |. 8B00 MOV EAX,DWORD PTR [EAX]
0051F2F4 |. 8B55 D0 MOV EDX,DWORD PTR [EBP-30]
0051F2F7 |. 8942 3C MOV DWORD PTR [EDX+3C],EAX ; 填充
0051F2FA |. 8B45 D4 MOV EAX,DWORD PTR [EBP-2C] ★★★★★ 变形2 ★★★★★
和标准的 MD5 的填充不一样,并不是加个1在消息后然后填充0,最后附上消息长度
而是将消息分为四个 dword ,逆序、顺序、逆序、顺序填充成 512 位
比如消息是:
0012F104 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 1234 5678 90AB CDEF
填充后是:
0106CF74 43 44 45 46 39 30 41 42 35 36 37 38 31 32 33 34 CDEF 90AB 5678 1234
0106CF84 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 1234 5678 90AB CDEF
0106CF94 43 44 45 46 39 30 41 42 35 36 37 38 31 32 33 34 CDEF 90AB 5678 1234
0106CFA4 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 1234 5678 90AB CDEF
//------------- round 1 -------------//
0051F2FD |. 50 PUSH EAX ; /Arg4
0051F2FE |. 8B45 D0 MOV EAX,DWORD PTR [EBP-30] ; |
0051F301 |. 8B00 MOV EAX,DWORD PTR [EAX] ; |
0051F303 |. 50 PUSH EAX ; |Arg3
0051F304 |. 6A 07 PUSH 7 ; |Arg2 = 00000007
0051F306 |. 68 78A46AD7 PUSH D76AA478 ; |Arg1 = D76AA478
0051F30B |. 8BC3 MOV EAX,EBX ; |
0051F30D |. 8B0F MOV ECX,DWORD PTR [EDI] ; |
0051F30F |. 8B16 MOV EDX,DWORD PTR [ESI] ; |
0051F311 |. E8 CE070000 CALL AutoRunP.0051FAE4 ; \AutoRunP.0051FAE4
0051F316 |. 8B07 MOV EAX,DWORD PTR [EDI]
……………………
0051F4C2 |. 8B17 MOV EDX,DWORD PTR [EDI] ; |
0051F4C4 |. E8 1B060000 CALL AutoRunP.0051FAE4 ; \AutoRunP.0051FAE4
0051F4C9 |. 8B45 D4 MOV EAX,DWORD PTR [EBP-2C]
//------------- round 2 -------------//
0051F4CC |. 50 PUSH EAX ; /Arg4
0051F4CD |. 8B45 D0 MOV EAX,DWORD PTR [EBP-30] ; |
0051F4D0 |. 8B40 04 MOV EAX,DWORD PTR [EAX+4] ; |
0051F4D3 |. 50 PUSH EAX ; |Arg3
0051F4D4 |. 6A 05 PUSH 5 ; |Arg2 = 00000005
0051F4D6 |. 68 62251EF6 PUSH F61E2562 ; |Arg1 = F61E2562
0051F4DB |. 8BC3 MOV EAX,EBX ; |
0051F4DD |. 8B0F MOV ECX,DWORD PTR [EDI] ; |
0051F4DF |. 8B16 MOV EDX,DWORD PTR [ESI] ; |
0051F4E1 |. E8 3A060000 CALL AutoRunP.0051FB20 ; \AutoRunP.0051FB20
0051F4E6 |. 8B07 MOV EAX,DWORD PTR [EDI]
……………………
0051F691 |. 8B17 MOV EDX,DWORD PTR [EDI] ; |
0051F693 |. E8 88040000 CALL AutoRunP.0051FB20 ; \AutoRunP.0051FB20
0051F698 |. 8B45 D4 MOV EAX,DWORD PTR [EBP-2C]
//------------- round 3 -------------//
0051F69B |. 50 PUSH EAX ; /Arg4
0051F69C |. 8B45 D0 MOV EAX,DWORD PTR [EBP-30] ; |
0051F69F |. 8B40 14 MOV EAX,DWORD PTR [EAX+14] ; |
0051F6A2 |. 50 PUSH EAX ; |Arg3
0051F6A3 |. 6A 04 PUSH 4 ; |Arg2 = 00000004
0051F6A5 |. 68 4239FAFF PUSH FFFA3942 ; |Arg1 = FFFA3942
0051F6AA |. 8BC3 MOV EAX,EBX ; |
0051F6AC |. 8B0F MOV ECX,DWORD PTR [EDI] ; |
0051F6AE |. 8B16 MOV EDX,DWORD PTR [ESI] ; |
0051F6B0 |. E8 A7040000 CALL AutoRunP.0051FB5C ; \AutoRunP.0051FB5C
0051F6B5 |. 8B07 MOV EAX,DWORD PTR [EDI]
……………………
0051F860 |. 8B17 MOV EDX,DWORD PTR [EDI] ; |
0051F862 |. E8 F5020000 CALL AutoRunP.0051FB5C ; \AutoRunP.0051FB5C
0051F867 |. 8B45 D4 MOV EAX,DWORD PTR [EBP-2C]
//------------- round 4 -------------//
0051F86A |. 50 PUSH EAX ; /Arg4
0051F86B |. 8B45 D0 MOV EAX,DWORD PTR [EBP-30] ; |
0051F86E |. 8B00 MOV EAX,DWORD PTR [EAX] ; |
0051F870 |. 50 PUSH EAX ; |Arg3
0051F871 |. 6A 06 PUSH 6 ; |Arg2 = 00000006
0051F873 |. 68 442229F4 PUSH F4292244 ; |Arg1 = F4292244
0051F878 |. 8BC3 MOV EAX,EBX ; |
0051F87A |. 8B0F MOV ECX,DWORD PTR [EDI] ; |
0051F87C |. 8B16 MOV EDX,DWORD PTR [ESI] ; |
0051F87E |. E8 15030000 CALL AutoRunP.0051FB98 ; \AutoRunP.0051FB98
0051F883 |. 8B07 MOV EAX,DWORD PTR [EDI]
……………………
0051FA2F |. 8B17 MOV EDX,DWORD PTR [EDI] ; |
0051FA31 |. E8 62010000 CALL AutoRunP.0051FB98 ; \AutoRunP.0051FB98
0051FA36 |. 8B45 F0 MOV EAX,DWORD PTR [EBP-10]
0051FA39 |. 0303 ADD EAX,DWORD PTR [EBX] ; + d
0051FA3B |. 8B55 FC MOV EDX,DWORD PTR [EBP-4]
0051FA3E |. 8902 MOV DWORD PTR [EDX],EAX ; save
0051FA40 |. 8B45 EC MOV EAX,DWORD PTR [EBP-14]
0051FA43 |. 0306 ADD EAX,DWORD PTR [ESI] ; + c
0051FA45 |. 8B55 F8 MOV EDX,DWORD PTR [EBP-8]
0051FA48 |. 8902 MOV DWORD PTR [EDX],EAX ; save
0051FA4A |. 8B45 E8 MOV EAX,DWORD PTR [EBP-18]
0051FA4D |. 0307 ADD EAX,DWORD PTR [EDI] ; + b
0051FA4F |. 8B55 F4 MOV EDX,DWORD PTR [EBP-C]
0051FA52 |. 8902 MOV DWORD PTR [EDX],EAX ; save
0051FA54 |. 8B45 E4 MOV EAX,DWORD PTR [EBP-1C]
0051FA57 |. 0345 D4 ADD EAX,DWORD PTR [EBP-2C] ; + a
0051FA5A |. 8B55 08 MOV EDX,DWORD PTR [EBP+8]
0051FA5D |. 8902 MOV DWORD PTR [EDX],EAX ; save
★★★★★ 变形3 ★★★★★
跟进后发现 HASH 函数本身没有变形,但是参与运算的链接变量的顺序变化了。
----------------------------------------------------------------------------------------
【破解心得】
要得到正确的 serial 和 key ,按照下面的流程:
先对用户名添 0 后分成 n 组,再反序,分别用每一组消息修改 inbuff 的前 8 个字节,然后进行 MD5 编码,循环 n 次后,结果的最后 32 位作为 dword 转为十六进制
文本作为 serial 的中间 8 个字符。
然后前面接上 "0018" ,后面接上长度是 4 的任意 16进制文本,总共 16 个字符作为 serial
将 serial 填入 inbuff 的高 64 位,同时也填入 低 64 位,MD5(inbuff)得到 key
这个 MD5 有三处变形,变形没有什么新意,还是老一套:
(1) 四个变量的变形
(2) 数据填充变形
(3) 参与 HASH 运算的变量的顺序变形,HASH 本身没有变形。
----------------------------------------------------------------------------------------
【注册机源码】
因为程序只对 128 位消息进行 MD5 编码,为了便于编辑,没有采用类,大家直接看吧。
// 响应 Generate 按钮
void CkeygenDlg::OnOK()
{
// TODO: Add extra validation here
CkeygenDlg::OnChangeEdit1();
}
void CkeygenDlg::OnChangeEdit1()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialog::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.
// TODO: Add your control notification handler code here
UpdateData(true);
Beep(1000,50);
char inbuff[16] = {0},name[12];
unsigned long state[4];
int i, n, namelen;
//对用户名处理
namelen = m_Edit1.GetLength ();
n = namelen >> 3 ;
for(i = 0;i<n;i++){
strcpy(name,m_Edit1.Mid (i<<3,8)) //取用户名的8个字符
strrev(name); //将8个字符顺序反转
memcpy(inbuff,name,8); //复制到待加密信息的高64位
MD5(inbuff,state); //MD5编码
memcpy(inbuff,state,16); //替换掉待加密信息
}
n = namelen & 7 ; //判断用户名有没有处理完毕
strcpy(name,m_Edit1.Mid (i<<3,n));; //取出剩余字符
strrev(name); //剩余字符顺序反转
i = 8 - n ; //计算补0的个数
memset(inbuff,0,i); //将0填入待加密信息
memcpy(inbuff+i,name,n); //将反转字符填入待加密信息
MD5(inbuff,state); //MD5编码
m_Edit2.Format ("%08X",state[3]); //将 State[3] 转为16进制字符串作为 Serial 的一部分
m_Edit2.Insert (0,"0018"); //serial 前面插入"0018"
n = rand ();
sprintf(inbuff,"%04X",n);
m_Edit2 += inbuff; //serial 的最后四位任意,并且传递给编辑框
memcpy(inbuff,&n,2);
memcpy(inbuff+2,state+3,4);
inbuff[6] = char(0x18);
inbuff[7] = char(0);
memcpy(inbuff+8,inbuff,8); //serial 填充到 inbuff
MD5(inbuff,state); //对 serial MD5编码
sprintf(inbuff,"%08X",state[2]);
m_Edit3.Format ("%08X",state[3]); //取 state[2] 和 state[2] 作为 Code
m_Edit3 += inbuff; //将 code 传递给编辑框
UpdateData(false);
}
// 将 128 待加密信息填充成 512 位,即16个整数
void CkeygenDlg::FillBuff(unsigned long *buff,char *inbuff)
{
int *from=(int *)inbuff;
buff[3]=*from; buff[2]=*(from+1); buff[1]=*(from+2); buff[0]=*(from+3);
buff[4]=*from; buff[5]=*(from+1); buff[6]=*(from+2); buff[7]=*(from+3);
buff[11]=*from; buff[10]=*(from+1); buff[9]=*(from+2); buff[8]=*(from+3);
buff[12]=*from; buff[13]=*(from+1); buff[14]=*(from+2); buff[15]=*(from+3);
}
//四个函数定义1 FF
unsigned long CkeygenDlg::FF(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long x, byte s, unsigned long ac)
{
a = ((b & c)|((~b)&d)) + a + x + ac;
a = (a<<s)|(a>>(32-s)) ;
a += b;
return a;
}
//四个函数定义2 GG
unsigned long CkeygenDlg::GG(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long x, byte s, unsigned long ac)
{
a = ((b&d)|(c&(~d))) + a + x + ac ;
a = (a<<s)|(a>>(32-s)) ;
a += b;
return a;
}
//四个函数定义3 HH
unsigned long CkeygenDlg::HH(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long x, byte s, unsigned long ac)
{
a = (b^c^d) + a + x + ac ;
a = (a<<s)|(a>>(32-s)) ;
a += b;
return a;
}
//四个函数定义4 II
unsigned long CkeygenDlg::II(unsigned long a, unsigned long b, unsigned long c, unsigned long d, unsigned long x, byte s, unsigned long ac)
{
a = ( c^(b|(~d)) ) + a + x + ac ;
a = (a<<s)|(a>>(32-s)) ;
a += b;
return a;
}
//MD5运算主函数 待加密信息保存在在inbuff中,结果保存在state[4]中
void CkeygenDlg::MD5(char *inbuff,unsigned long *state)
{
unsigned long context[16];
state[0]=0x1234567;
state[1]=0x89ABCDEF;
state[2]=0xBA98FEDC;
state[3]=0x76504321;
FillBuff(context,inbuff);
//------------- round 1 -------------//
state[3] = FF(state[3],state[2],state[1],state[0],context[0],7,0xd76aa478); // -1
state[0] = FF(state[0],state[3],state[2],state[1],context[1],12,0xe8c7b756); // -2
state[1] = FF(state[1],state[0],state[3],state[2],context[2],17,0x242070db); // -3
state[2] = FF(state[2],state[1],state[0],state[3],context[3],22,0xc1bdceee); // -4
state[3] = FF(state[3],state[2],state[1],state[0],context[4],7,0xf57c0faf); // -5
state[0] = FF(state[0],state[3],state[2],state[1],context[5],12,0x4787c62a); // -6
state[1] = FF(state[1],state[0],state[3],state[2],context[6],17,0xa8304613); // -7
state[2] = FF(state[2],state[1],state[0],state[3],context[7],22,0xfd469501); // -8
state[3] = FF(state[3],state[2],state[1],state[0],context[8],7,0x698098d8); // -9
state[0] = FF(state[0],state[3],state[2],state[1],context[9],12,0x8b44f7af); //-10
state[1] = FF(state[1],state[0],state[3],state[2],context[10],17,0xffff5bb1);//-11
state[2] = FF(state[2],state[1],state[0],state[3],context[11],22,0x895cd7be);//-12
state[3] = FF(state[3],state[2],state[1],state[0],context[12],7,0x6b901122); //-13
state[0] = FF(state[0],state[3],state[2],state[1],context[13],12,0xfd987193);//-14
state[1] = FF(state[1],state[0],state[3],state[2],context[14],17,0xa679438e);//-15
state[2] = FF(state[2],state[1],state[0],state[3],context[15],22,0x49b40821);//-16
//------------- round 2 -------------//
state[3] = GG(state[3],state[2],state[1],state[0],context[1],5,0xf61e2562); //-17
state[0] = GG(state[0],state[3],state[2],state[1],context[6],9,0xc040b340); //-18
state[1] = GG(state[1],state[0],state[3],state[2],context[11],14,0x265e5a51);//-19
state[2] = GG(state[2],state[1],state[0],state[3],context[0],20,0xe9b6c7aa); //-20
state[3] = GG(state[3],state[2],state[1],state[0],context[5],5,0xd62f105d); //-21
state[0] = GG(state[0],state[3],state[2],state[1],context[10],9,0x2441453); //-22
state[1] = GG(state[1],state[0],state[3],state[2],context[15],14,0xd8a1e681);//-23
state[2] = GG(state[2],state[1],state[0],state[3],context[4],20,0xe7d3fbc8); //-24
state[3] = GG(state[3],state[2],state[1],state[0],context[9],5,0x21e1cde6); //-25
state[0] = GG(state[0],state[3],state[2],state[1],context[14],9,0xc33707d6); //-26
state[1] = GG(state[1],state[0],state[3],state[2],context[3],14,0xf4d50d87); //-27
state[2] = GG(state[2],state[1],state[0],state[3],context[8],20,0x455a14ed); //-28
state[3] = GG(state[3],state[2],state[1],state[0],context[13],5,0xa9e3e905); //-28
state[0] = GG(state[0],state[3],state[2],state[1],context[2],9,0xfcefa3f8); //-30
state[1] = GG(state[1],state[0],state[3],state[2],context[7],14,0x676f02d9); //-31
state[2] = GG(state[2],state[1],state[0],state[3],context[12],20,0x8d2a4c8a);//-32
//------------- round 3 -------------//
state[3] = HH(state[3],state[2],state[1],state[0],context[5],4,0xfffa3942); //-33
state[0] = HH(state[0],state[3],state[2],state[1],context[8],11,0x8771f681); //-34
state[1] = HH(state[1],state[0],state[3],state[2],context[11],16,0x6d9d6122);//-35
state[2] = HH(state[2],state[1],state[0],state[3],context[14],23,0xfde5380c);//-36
state[3] = HH(state[3],state[2],state[1],state[0],context[1],4,0xa4beea44); //-37
state[0] = HH(state[0],state[3],state[2],state[1],context[4],11,0x4bdecfa9); //-38
state[1] = HH(state[1],state[0],state[3],state[2],context[7],16,0xf6bb4b60); //-39
state[2] = HH(state[2],state[1],state[0],state[3],context[10],23,0xbebfbc70);//-40
state[3] = HH(state[3],state[2],state[1],state[0],context[13],4,0x289b7ec6); //-41
state[0] = HH(state[0],state[3],state[2],state[1],context[0],11,0xeaa127fa); //-42
state[1] = HH(state[1],state[0],state[3],state[2],context[3],16,0xd4ef3085); //-43
state[2] = HH(state[2],state[1],state[0],state[3],context[6],23,0x4881d05); //-44
state[3] = HH(state[3],state[2],state[1],state[0],context[9],4,0xd9d4d039); //-45
state[0] = HH(state[0],state[3],state[2],state[1],context[12],11,0xe6db99e5);//-46
state[1] = HH(state[1],state[0],state[3],state[2],context[15],16,0x1fa27cf8);//-47
state[2] = HH(state[2],state[1],state[0],state[3],context[2],23,0xc4ac5665); //-48
//------------- round 4 -------------//
state[3] = II(state[3],state[2],state[1],state[0],context[0],6,0xf4292244); //-49
state[0] = II(state[0],state[3],state[2],state[1],context[7],10,0x432aff97); //-50
state[1] = II(state[1],state[0],state[3],state[2],context[14],15,0xab9423a7);//-51
state[2] = II(state[2],state[1],state[0],state[3],context[5],21,0xfc93a039); //-52
state[3] = II(state[3],state[2],state[1],state[0],context[12],6,0x655b59c3); //-53
state[0] = II(state[0],state[3],state[2],state[1],context[3],10,0x8f0ccc92); //-54
state[1] = II(state[1],state[0],state[3],state[2],context[10],15,0xffeff47d);//-55
state[2] = II(state[2],state[1],state[0],state[3],context[1],21,0x85845dd1); //-56
state[3] = II(state[3],state[2],state[1],state[0],context[8],6,0x6fa87e4f); //-57
state[0] = II(state[0],state[3],state[2],state[1],context[15],10,0xfe2ce6e0);//-58
state[1] = II(state[1],state[0],state[3],state[2],context[6],15,0xa3014314); //-59
state[2] = II(state[2],state[1],state[0],state[3],context[13],21,0x4e0811a1);//-60
state[3] = II(state[3],state[2],state[1],state[0],context[4],6,0xf7537e82); //-61
state[0] = II(state[0],state[3],state[2],state[1],context[11],10,0xbd3af235);//-62
state[1] = II(state[1],state[0],state[3],state[2],context[2],15,0x2ad7d2bb); //-63
state[2] = II(state[2],state[1],state[0],state[3],context[9],21,0xeb86d391); //-64
state[0] += 0x1234567;
state[1] += 0x89ABCDEF;
state[2] += 0xBA98FEDC;
state[3] += 0x76504321;
}
----------------------------------------------------------------------------------------
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
----------------------------------------------------------------------------------------
文章写于2006-1-21 18:10:17
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!