您的位置:首页 > 其它

某软件MD5算法分析与注册机编写

2018-03-07 11:47 316 查看
遇到一个Delphi的软件,只有一个MD5加密和一个处理MD5数据的算法,

通过Delphi的按钮事件找到注册的验证地方

00D86F32 55 push ebp
00D86F33 68 7F70D800 push Dcz.00D8707F
00D86F38 64:FF30 push dword ptr fs:[eax]
00D86F3B 64:8920 mov dword ptr fs:[eax],esp
00D86F3E 8D55 F4 lea edx,dword ptr ss:[ebp-0xC]
00D86F41 8B86 10040000 mov eax,dword ptr ds:[esi+0x410]
00D86F47 E8 C0EA78FF call Dcz.00515A0C
00D86F4C 8B45 F4 mov eax,dword ptr ss:[ebp-0xC]
00D86F4F 8D55 FC lea edx,dword ptr ss:[ebp-0x4] ; 获取机器码
00D86F52 E8 45D669FF call Dcz.0042459C
00D86F57 8D55 F0 lea edx,dword ptr ss:[ebp-0x10]
00D86F5A 8B86 D0030000 mov eax,dword ptr ds:[esi+0x3D0]
00D86F60 E8 A7EA78FF call Dcz.00515A0C
00D86F65 8B45 F0 mov eax,dword ptr ss:[ebp-0x10] ; 假码 eax=假码个数
00D86F68 8D55 F8 lea edx,dword ptr ss:[ebp-0x8]
00D86F6B E8 2CD669FF call Dcz.0042459C
00D86F70 8D45 DC lea eax,dword ptr ss:[ebp-0x24]
00D86F73 B9 9870D800 mov ecx,Dcz.00D87098 ;与机器码合并的一串数据 9E#FFB!857~C0-074A$^C9923@EEB7%E4788^CDC(4FE7^EA381*548$745D@#BA71$51D!66CC)755!3A@0CA#A9%C^45C&1—0+34^&41^A392@B1!9B$0794%75$49
00D86F78 8B55 FC mov edx,dword ptr ss:[ebp-0x4]
00D86F7B E8 B84C68FF call Dcz.0040BC38 ;合并机器码和上面的一串文本字符串
00D86F80 8B45 DC mov eax,dword ptr ss:[ebp-0x24]
00D86F83 8D55 E0 lea edx,dword ptr ss:[ebp-0x20]
00D86F86 E8 E9910300 call <Dcz.md5加密>
00D86F8B 8B45 E0 mov eax,dword ptr ss:[ebp-0x20]
00D86F8E 8D4D E4 lea ecx,dword ptr ss:[ebp-0x1C]
00D86F91 BA E2070000 mov edx,0x7E2 ; 参数edx = 2018
00D86F96 E8 D19CB9FF call <Dcz.md5循环异或>
00D86F9B 8B45 E4 mov eax,dword ptr ss:[ebp-0x1C]
00D86F9E 8D55 E8 lea edx,dword ptr ss:[ebp-0x18]
00D86FA1 E8 CE910300 call <Dcz.md5加密>
00D86FA6 8B45 E8 mov eax,dword ptr ss:[ebp-0x18]
00D86FA9 8D4D EC lea ecx,dword ptr ss:[ebp-0x14]
00D86FAC BA E2070000 mov edx,0x7E2
00D86FB1 E8 B69CB9FF call <Dcz.md5循环异或>
00D86FB6 8B55 EC mov edx,dword ptr ss:[ebp-0x14] ; 计算出来的注册码
00D86FB9 8B45 F8 mov eax,dword ptr ss:[ebp-0x8] ; 输入的注册码
00D86FBC E8 0F4E68FF call Dcz.0040BDD0 ; 文本比较
00D86FC1 75 6B jnz short Dcz.00D8702E
00D86FC3 8B86 D8030000 mov eax,dword ptr ds:[esi+0x3D8] ; 下面就是写配置项,如果比较成功的话
00D86FC9 8B10 mov edx,dword ptr ds:[eax]
00D86FCB FF92 24010000 call dword ptr ds:[edx+0x124]
00D86FD1 50 push eax
00D86FD2 A1 6823E100 mov eax,dword ptr ds:[0xE12368]
00D86FD7 8B00 mov eax,dword ptr ds:[eax]
00D86FD9 B9 B471D800 mov ecx,Dcz.00D871B4 ; REGTYPE
00D86FDE BA D071D800 mov edx,Dcz.00D871D0 ; REGMESSAGE
00D86FE3 8B18 mov ebx,dword ptr ds:[eax]
00D86FE5 FF53 18
4000
call dword ptr ds:[ebx+0x18]
00D86FE8 8B86 D8030000 mov eax,dword ptr ds:[esi+0x3D8]
00D86FEE 8B10 mov edx,dword ptr ds:[eax]
00D86FF0 FF92 24010000 call dword ptr ds:[edx+0x124]
00D86FF6 8B15 B42BE100 mov edx,dword ptr ds:[0xE12BB4]
00D86FFC 8802 mov byte ptr ds:[edx],al
00D86FFE 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
00D87001 50 push eax
00D87002 A1 6823E100 mov eax,dword ptr ds:[0xE12368]
00D87007 8B00 mov eax,dword ptr ds:[eax]
00D87009 B9 F471D800 mov ecx,Dcz.00D871F4 ; REGKEY
00D8700E BA D071D800 mov edx,Dcz.00D871D0 ; REGMESSAGE
00D87013 8B18 mov ebx,dword ptr ds:[eax]
00D87015 FF53 08 call dword ptr ds:[ebx+0x8]
00D87018 A1 EC28E100 mov eax,dword ptr ds:[0xE128EC]
00D8701D 8B55 F8 mov edx,dword ptr ss:[ebp-0x8]
00D87020 E8 733C68FF call Dcz.0040AC98
00D87025 8BC6 mov eax,esi
00D87027 E8 6CE786FF call Dcz.005F5798
00D8702C EB 1C jmp short Dcz.00D8704A
00D8702E 8B86 D0030000 mov eax,dword ptr ds:[esi+0x3D0]
00D87034 8B10 mov edx,dword ptr ds:[eax]
00D87036 FF92 40010000 call dword ptr ds:[edx+0x140]
00D8703C 8B86 D0030000 mov eax,dword ptr ds:[esi+0x3D0]
00D87042 8B10 mov edx,dword ptr ds:[eax]
00D87044 FF92 20010000 call dword ptr ds:[edx+0x120]
00D8704A 33C0 xor eax,eax
00D8704C 5A pop edx
00D8704D 59 pop ecx
00D8704E 59 pop ecx
00D8704F 64:8910 mov dword ptr fs:[eax],edx
00D87052 68 8670D800 push Dcz.00D87086
00D87057 8D45 DC lea eax,dword ptr ss:[ebp-0x24]
00D8705A BA 05000000 mov edx,0x5
00D8705F E8 B43868FF call Dcz.0040A918
00D87064 8D45 F0 lea eax,dword ptr ss:[ebp-0x10]
00D87067 BA 02000000 mov edx,0x2
00D8706C E8 A73868FF call Dcz.0040A918
00D87071 8D45 F8 lea eax,dword ptr ss:[ebp-0x8]
00D87074 BA 02000000 mov edx,0x2
00D87079 E8 9A3868FF call Dcz.0040A918
00D8707E C3 retn



跟进MD5加密CALL进去
00768E4C 55 push ebp
00768E4D 8BEC mov ebp,esp
00768E4F 83C4 E8 add esp,-0x18
00768E52 53 push ebx
00768E53 56 push esi
00768E54 894D F8 mov dword ptr ss:[ebp-0x8],ecx
00768E57 8955 FC mov dword ptr ss:[ebp-0x4],edx
00768E5A 8BF0 mov esi,eax
00768E5C 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
00768E5F 8B15 08177300 mov edx,dword ptr ds:[0x731708]
00768E65 E8 5E48CAFF call Dcz.0040D6C8
00768E6A 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00768E6D 8945 F0 mov dword ptr ss:[ebp-0x10],eax
00768E70 8B45 0C mov eax,dword ptr ss:[ebp+0xC]
00768E73 8945 F4 mov dword ptr ss:[ebp-0xC],eax
00768E76 33DB xor ebx,ebx
00768E78 B8 E868E000 mov eax,Dcz.00E068E8
00768E7D 8B10 mov edx,dword ptr ds:[eax]
00768E7F 89549E 08 mov dword ptr ds:[esi+ebx*4+0x8],edx
00768E83 43 inc ebx
00768E84 83C0 04 add eax,0x4
00768E87 83FB 04 cmp ebx,0x4
00768E8A ^ 75 F1 jnz short Dcz.00768E7D
00768E8C EB 23 jmp short Dcz.00768EB1
00768E8E 6A 00 push 0x0
00768E90 6A 40 push 0x40
00768E92 8D56 04 lea edx,dword ptr ds:[esi+0x4]
00768E95 33C9 xor ecx,ecx
00768E97 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
00768E9A E8 69FCFCFF call <Dcz.需要逆>
00768E9F 8BD8 mov ebx,eax
00768EA1 8BC6 mov eax,esi
00768EA3 8B10 mov edx,dword ptr ds:[eax] ;这一块是加密长度为0x40部分的数据
00768EA5 FF52 1C call dword ptr ds:[edx+0x1C] ; MD5加密轮加密部分
00768EA8 8BC3 mov eax,ebx
00768EAA 99 cdq
00768EAB 2945 F0 sub dword ptr ss:[ebp-0x10],eax
00768EAE 1955 F4 sbb dword ptr ss:[ebp-0xC],edx
00768EB1 837D F4 00 cmp dword ptr ss:[ebp-0xC],0x0
00768EB5 75 08 jnz short Dcz.00768EBF ;MD5循环分组加密
00768EB7 837D F0 40 cmp dword ptr ss:[ebp-0x10],0x40 ;如果需要加密的数据长度小于0x40就向下执行
00768EBB ^ 73 D1 jnb short Dcz.00768E8E
00768EBD EB 02 jmp short Dcz.00768EC1
00768EBF ^ 7D CD jge short Dcz.00768E8E
00768EC1 FF75 F4 push dword ptr ss:[ebp-0xC]
00768EC4 FF75 F0 push dword ptr ss:[ebp-0x10]
00768EC7 8D56 04 lea edx,dword ptr ds:[esi+0x4]
00768ECA 33C9 xor ecx,ecx
00768ECC 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
00768ECF E8 34FCFCFF call <Dcz.需要逆>
00768ED4 8B56 04 mov edx,dword ptr ds:[esi+0x4]
00768ED7 C60402 80 mov byte ptr ds:[edx+eax],0x80 ; 0x80补齐,填充使长度为448bit
00768EDB 83C0 01 add eax,0x1
00768EDE 71 05 jno short Dcz.00768EE5
00768EE0 E8 0FFAC9FF call Dcz.004088F4
00768EE5 83F8 38 cmp eax,0x38 ;比较剩余数据位数
00768EE8 7E 1D jle short Dcz.00768F07
00768EEA 8BD8 mov ebx,eax
00768EEC 83FB 3F cmp ebx,0x3F
00768EEF 7F 0D jg short Dcz.00768EFE
00768EF1 8B46 04 mov eax,dword ptr ds:[esi+0x4]
00768EF4 C60418 00 mov byte ptr ds:[eax+ebx],0x0
00768EF8 43 inc ebx
00768EF9 83FB 40 cmp ebx,0x40
00768EFC ^ 75 F3 jnz short Dcz.00768EF1
00768EFE 8BC6 mov eax,esi
00768F00 8B10 mov edx,dword ptr ds:[eax]
00768F02 FF52 1C call dword ptr ds:[edx+0x1C]
00768F05 33C0 xor eax,eax
00768F07 8BD8 mov ebx,eax
00768F09 83FB 37 cmp ebx,0x37
00768F0C 7F 0D jg short Dcz.00768F1B
00768F0E 8B46 04 mov eax,dword ptr ds:[esi+0x4]
00768F11 C60418 00 mov byte ptr ds:[eax+ebx],0x0
00768F15 43 inc ebx
00768F16 83FB 38 cmp ebx,0x38
00768F19 ^ 75 F3 jnz short Dcz.00768F0E
00768F1B 6A 00 push 0x0
00768F1D 6A 08 push 0x8
00768F1F 8B45 08 mov eax,dword ptr ss:[ebp+0x8]
00768F22 8B55 0C mov edx,dword ptr ss:[ebp+0xC]
00768F25 E8 123ECAFF call Dcz.0040CD3C ;这个CALL的作用是把原数据位数 * 0x8
00768F2A 71 05 jno short Dcz.00768F31
00768F2C E8 C3F9C9FF call Dcz.004088F4
00768F31 8945 E8 mov dword ptr ss:[ebp-0x18],eax
00768F34 8955 EC mov dword ptr ss:[ebp-0x14],edx
00768F37 BB 38000000 mov ebx,0x38 ;ebx作为数组索引0x38,填充后面的数据
00768F3C 8B45 E8 mov eax,dword ptr ss:[ebp-0x18]
00768F3F 8B55 EC mov edx,dword ptr ss:[ebp-0x14]
00768F42 81E0 FF000000 and eax,0xFF ; eax & 0xFF 并且依次填充到0x38后面部分
00768F48 33D2 xor edx,edx
00768F4A 8B56 04 mov edx,dword ptr ds:[esi+0x4]
00768F4D 88041A mov byte ptr ds:[edx+ebx],al ;填充al到0x38后面部分
00768F50 8B45 E8 mov eax,dword ptr ss:[ebp-0x18]
00768F53 8B55 EC mov edx,dword ptr ss:[ebp-0x14]
00768F56 0FACD0 08 shrd eax,edx,0x8 ;eax,shr 8 位
00768F5A C1EA 08 shr edx,0x8
00768F5D 8945 E8 mov dword ptr ss:[ebp-0x18],eax
00768F60 8955 EC mov dword ptr ss:[ebp-0x14],edx
00768F63 43 inc ebx
00768F64 83FB 40 cmp ebx,0x40
00768F67 ^ 75 D3 jnz short Dcz.00768F3C ;直到0x40全部被填充完
00768F69 8BC6 mov eax,esi
00768F6B 8B10 mov edx,dword ptr ds:[eax]
00768F6D FF52 1C call dword ptr ds:[edx+0x1C] ; 再一次MD5加密剩余数据
00768F70 6A 10 push 0x10
00768F72 8B45 F8 mov eax,dword ptr ss:[ebp-0x8]
00768F75 B9 01000000 mov ecx,0x1
00768F7A 8B15 08177300 mov edx,dword ptr ds:[0x731708]
00768F80 E8 1F46CAFF call Dcz.0040D5A4
00768F85 83C4 04 add esp,0x4
00768F88 33DB xor ebx,ebx
00768F8A 6BCB 04 imul ecx,ebx,0x4
00768F8D 71 05 jno short Dcz.00768F94
00768F8F E8 60F9C9FF call Dcz.004088F4
00768F94 8B55 F8 mov edx,dword ptr ss:[ebp-0x8]
00768F97 8B449E 08 mov eax,dword ptr ds:[esi+ebx*4+0x8]
00768F9B E8 D0D1FCFF call Dcz.00736170
00768FA0 43 inc ebx
00768FA1 83FB 04 cmp ebx,0x4
00768FA4 ^ 75 E4 jnz short Dcz.00768F8A
00768FA6 5E pop esi
00768FA7 5B pop ebx
00768FA8 8BE5 mov esp,ebp
00768FAA 5D pop ebp
00768FAB C2 0800 retn 0x8


0076903C 53 push ebx ; md5初始化 [eax]是一个函数跳转表,[eax+4]是加密字符一部分,[eax+8]开始为四个幻数
0076903D 56 push esi
0076903E 57 push edi
0076903F 55 push ebp
00769040 83C4 B4 add esp,-0x4C
00769043 890424 mov dword ptr ss:[esp],eax
00769046 8B0424 mov eax,dword ptr ss:[esp]
00769049 8B58 08 mov ebx,dword ptr ds:[eax+0x8] ; 0x67452301幻数KA
0076904C 8B0424 mov eax,dword ptr ss:[esp]
0076904F 8B70 0C mov esi,dword ptr ds:[eax+0xC] ; 0xEFCDAB89幻数KB
00769052 8B0424 mov eax,dword ptr ss:[esp]
00769055 8B78 10 mov edi,dword ptr ds:[eax+0x10] ; 0x98BADCFE幻数KC
00769058 8B0424 mov eax,dword ptr ss:[esp]
0076905B 8B68 14 mov ebp,dword ptr ds:[eax+0x14] ; 0x10325476幻数KD
0076905E 33C0 xor eax,eax
00769060 894424 04 mov dword ptr ss:[esp+0x4],eax ;后面的即MD5的F,H,G,I轮循环加密了
00769064 8D4424 0C lea eax,dword ptr ss:[esp+0xC] ;si也能在后面找到,和原来的一样
00769068 894424 08 mov dword ptr ss:[esp+0x8],eax



可以发现MD5的加密过程幻数kA = 0x67452301,kB = 0xefcdab89,kC = 0x98badcfe,kD = 0x10325476

再来分析一下MD5加密后数据处理的函数:
00920CA4 BE 01000000 mov esi,0x1
00920CA9 8B45 FC mov eax,dword ptr ss:[ebp-0x4]
00920CAC 0FB74470 FE movzx eax,word ptr ds:[eax+esi*2-0x2] ; 依次取md5每一个
00920CB1 33D2 xor edx,edx
00920CB3 52 push edx
00920CB4 50 push eax
00920CB5 8BC3 mov eax,ebx ; ebx初始为 = 2018,后面每一次是上一次的结果
00920CB7 99 cdq
00920CB8 330424 xor eax,dword ptr ss:[esp] ; md5每一位和2018进行异或保存到eax
00920CBB 335424 04 xor edx,dword ptr ss:[esp+0x4]
00920CBF 83C4 08 add esp,0x8
00920CC2 0FB6C0 movzx eax,al ; al给eax
00920CC5 8B0485 AC81E000 mov eax,dword ptr ds:[eax*4+0xE081AC] ; eax = 0xE081AC+eax*4
00920CCC C1EB 08 shr ebx,0x8
00920CCF 81E3 FFFFFF00 and ebx,0xFFFFFF ; ebx = 7
00920CD5 33C3 xor eax,ebx
00920CD7 8BD8 mov ebx,eax
00920CD9 46 inc esi ; esi作为md5索引
00920CDA 49 dec ecx ; 0x20次循环
00920CDB ^ 75 CC jnz short Dcz.00920CA9
00920CDD 8B4D F8 mov ecx,dword ptr ss:[ebp-0x8] ; eax = ebx 算法为取md5每一位和2018异或取到al作为0xE081AC的偏移,取到之后和7异或
00920CE0 8BC3 mov eax,ebx
00920CE2 F7D0 not eax ; not
00920CE4 BA 08000000 mov edx,0x8 ;
00920CE9 E8 6646B0FF call Dcz.00425354 ; 将结果转换成文本


这个处理算法就是:
每一位md5都和一个temp进行异或,temp初始化为2018,异或后取最低byte位进行数组(0XE081AC)索引,再将索引到的值shr 8和and 0xFFFFFFFF ,最后temp = 索引值和temp再进行异或,一直循环32次后将temp进行取反,还是很简单这个算法。

还有一点,文本常量里面有个“—”,这个在转换时候是Unicode转Utf8

过程:
1.先将合并的数据进行第一次MD5加密
2.第一次MD5加密的数据进行处理得到一个新的文本
3.将这个新的文本再次进行MD5加密
4.再次处理这个MD5加密数据得到注册码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: