软件名称:chm帮助编辑器V2.61
下载地址:http://kshii.51.net/
破解工具:TRW1.23注册版
破解目的:注册码及其产生机制
破解过程:在注册界面里,用bpx hmemcpy等方法都拦不住,说明作者在这方面下了很大功夫,但百密难免一疏,在使用31次后会跳出一个NAG,提示试用期已到,这是cracker最喜欢见到的:),此时按^N,并下命令PMODULE,又回到NAG画面,点确定后立刻被拦,往上找就会看到如下代码:
016F:0047A204 LEA EAX,[EBP+FFFFFEF7]
016F:0047A20A PUSH EAX
016F:0047A20B PUSH DWORD 0047A4F8 |
016F:0047A210 PUSH DWORD 0047A4FC |读取win.ini的[AgeSet]中的
016F:0047A215 PUSH DWORD 0047A504 |Pnum的值,即软件序号
016F:0047A21A CALL `KERNEL32!GetProfileStringA` |
016F:0047A21F CMP BYTE [EBP+FFFFFEF7],00
016F:0047A226 JNZ NEAR 0047A2C7 如Pnum非空则跳过去
016F:0047A22C CALL 00402A4C |
016F:0047A231 LEA EAX,[EBP-04] |
016F:0047A234 CALL 00403BF4 |
016F:0047A239 MOV EBX,0A |
016F:0047A23E MOV EAX,49 |
016F:0047A243 CALL 00402BF4 |
016F:0047A248 MOV ESI,EAX |
016F:0047A24A INC ESI |
016F:0047A24B LEA EAX,[EBP+FFFFFEF0] |随机产生新的软件序号
016F:0047A251 PUSH EAX |(10个字符)
016F:0047A252 MOV ECX,01 |
016F:0047A257 MOV EDX,ESI |
016F:0047A259 MOV EAX,0047A514 |
016F:0047A25E CALL 0040407C |
016F:0047A263 MOV EDX,[EBP+FFFFFEF0] |
016F:0047A269 LEA EAX,[EBP-04] |
016F:0047A26C CALL 00403E7C |
016F:0047A271 DEC EBX |
016F:0047A272 JNZ 0047A23E |
016F:0047A274 MOV EAX,[0048B8E0]
016F:0047A279 MOV EAX,[EAX+06C0]
016F:0047A27F MOV EDX,[EBP-04]
016F:0047A282 CALL 004306F0
016F:0047A287 MOV EDX,0047A568
016F:0047A28C MOV EAX,[0048B8E0]
016F:0047A291 CALL 004306F0
016F:0047A296 MOV EAX,[EBP-04]
016F:0047A299 CALL 00404038
016F:0047A29E PUSH EAX
016F:0047A29F PUSH DWORD 0047A4FC
016F:0047A2A4 PUSH DWORD 0047A504
016F:0047A2A9 CALL `KERNEL32!WriteProfileStringA` 将软件序号写入win.ini
016F:0047A2AE PUSH DWORD 0047A5C0
016F:0047A2B3 PUSH DWORD 0047A5C8
016F:0047A2B8 PUSH DWORD 0047A504
016F:0047A2BD CALL `KERNEL32!WriteProfileStringA` 写入Pwes,即试用次数
016F:0047A2C2 JMP 0047A4BD
016F:0047A2C7 LEA EAX,[EBP+FFFFFEEC]
016F:0047A2CD LEA EDX,[EBP+FFFFFEF7]
016F:0047A2D3 MOV ECX,0101
016F:0047A2D8 CALL 00403E24
016F:0047A2DD MOV EDX,[EBP+FFFFFEEC]
016F:0047A2E3 MOV EAX,[0048B8E0]
016F:0047A2E8 MOV EAX,[EAX+06C0]
016F:0047A2EE CALL 004306F0
016F:0047A2F3 PUSH DWORD 0100
016F:0047A2F8 LEA EAX,[EBP+FFFFFEF7]
016F:0047A2FE PUSH EAX
016F:0047A2FF PUSH DWORD 0047A4F8
016F:0047A304 PUSH DWORD 0047A5D0
016F:0047A309 PUSH DWORD 0047A504
016F:0047A30E CALL `KERNEL32!GetProfileStringA` 读取Pset值
016F:0047A313 LEA EAX,[EBP+FFFFFEE8]
016F:0047A319 LEA EDX,[EBP+FFFFFEF7]
016F:0047A31F MOV ECX,0101
016F:0047A324 CALL 00403E24
016F:0047A329 MOV EDX,[EBP+FFFFFEE8]
016F:0047A32F MOV EAX,[0048B8E0]
016F:0047A334 MOV EAX,[EAX+06C8]
016F:0047A33A CALL 004306F0
016F:0047A33F XOR EDX,EDX
016F:0047A341 MOV EAX,[0048B8E0]
016F:0047A346 CALL 0047A108 这个CALL是关键,从这里追进去
016F:0047A34B MOV EAX,[0048B8E0]
016F:0047A350 MOV EAX,[EAX+06CC]
016F:0047A356 CMP DWORD [EAX+0C],01F4
016F:0047A35D JZ NEAR 0047A4BD
.
.
.
---------------------------------
016F:0047A108 PUSH EBX
016F:0047A109 MOV EBX,EAX
016F:0047A10B MOV EAX,[EBX+06BC]
016F:0047A111 MOV EAX,[EAX+70]
016F:0047A114 CALL 00479E54 这个CALL是关键的关键,判断注册码的真假,再追...
016F:0047A119 TEST AL,AL
016F:0047A11B JZ 0047A157
016F:0047A11D MOV EAX,[EBX+06BC]
016F:0047A123 MOV EAX,[EAX+70]
016F:0047A126 CALL 00404038
016F:0047A12B PUSH EAX
016F:0047A12C PUSH DWORD 0047A15C
016F:0047A131 PUSH DWORD 0047A164
016F:0047A136 CALL `KERNEL32!WriteProfileStringA`
016F:0047A13B MOV EAX,[EBX+06CC]
016F:0047A141 MOV DWORD [EAX+0C],01F4
016F:0047A148 MOV EDX,0047A174
016F:0047A14D MOV EAX,[0048B8E0]
016F:0047A152 CALL 004306F0
016F:0047A157 POP EBX
016F:0047A158 RET
-----------------------------
016F:00479E54 PUSH EBP
016F:00479E55 MOV EBP,ESP
016F:00479E57 MOV ECX,07
016F:00479E5C PUSH BYTE +00
016F:00479E5E PUSH BYTE +00
016F:00479E60 DEC ECX
016F:00479E61 JNZ 00479E5C
016F:00479E63 PUSH EBX
016F:00479E64 PUSH ESI
016F:00479E65 MOV [EBP-04],EAX
016F:00479E68 MOV EAX,[EBP-04]
016F:00479E6B CALL 00404028
016F:00479E70 XOR EAX,EAX
016F:00479E72 PUSH EBP
016F:00479E73 PUSH DWORD 0047A066
016F:00479E78 PUSH DWORD [FS:EAX]
016F:00479E7B MOV [FS:EAX],ESP
016F:00479E7E MOV BYTE [EBP-05],00 将注册的标志置为假
016F:00479E82 MOV EAX,[EBP-04]
016F:00479E85 CALL 00403E74 计算注册码的长度
016F:00479E8A CMP EAX,BYTE +0D 等13吗?
016F:00479E8D JNZ NEAR 0047A043 不是,说明是假的,那就在此下中断,把win.ini
016F:00479E93 LEA EAX,[EBP-1C] 里的Pset值改为123456789abcd,再来吧
016F:00479E96 PUSH EAX
016F:00479E97 MOV ECX,02
016F:00479E9C MOV EDX,01
016F:00479EA1 MOV EAX,[EBP-04]
016F:00479EA4 CALL 0040407C 取注册码的前2位
016F:00479EA9 MOV EAX,[EBP-1C]
016F:00479EAC MOV EDX,0047A080
016F:00479EB1 CALL 00403F84
016F:00479EB6 JNZ NEAR 0047A043 是“El”吗?不是则假
016F:00479EBC LEA EAX,[EBP-20]
016F:00479EBF PUSH EAX
016F:00479EC0 MOV ECX,01
016F:00479EC5 MOV EDX,03
016F:00479ECA MOV EAX,[EBP-04]
016F:00479ECD CALL 0040407C 取注册码的第3位
016F:00479ED2 MOV EAX,[EBP-20]
016F:00479ED5 MOV EDX,0047A08C
016F:00479EDA CALL 00403F84
016F:00479EDF JNZ NEAR 0047A043 是“@”吗?不是则假
016F:00479EE5 LEA EAX,[EBP-24]
016F:00479EE8 PUSH EAX
016F:00479EE9 MOV ECX,01
016F:00479EEE MOV EDX,0A
016F:00479EF3 MOV EAX,[EBP-04]
016F:00479EF6 CALL 0040407C 取注册码的第10位
016F:00479EFB MOV EAX,[EBP-24]
016F:00479EFE MOV EDX,0047A098
016F:00479F03 CALL 00403F84
016F:00479F08 JNZ NEAR 0047A043 是“%”吗?不是则假
016F:00479F0E LEA EAX,[EBP-28]
016F:00479F11 PUSH EAX
016F:00479F12 MOV ECX,01
016F:00479F17 MOV EDX,0B
016F:00479F1C MOV EAX,[EBP-04]
016F:00479F1F CALL 0040407C 取注册码的第11位
016F:00479F24 MOV EAX,[EBP-28]
016F:00479F27 MOV EDX,0047A0A4
016F:00479F2C CALL 00403F84
016F:00479F31 JNZ NEAR 0047A043 是“s”吗?不是则假
016F:00479F37 LEA EAX,[EBP-2C]
016F:00479F3A PUSH EAX
016F:00479F3B MOV ECX,01
016F:00479F40 MOV EDX,0D
016F:00479F45 MOV EAX,[EBP-04]
016F:00479F48 CALL 0040407C 取注册码的第13位
016F:00479F4D MOV EAX,[EBP-2C]
016F:00479F50 MOV EDX,0047A0B0
016F:00479F55 CALL 00403F84
016F:00479F5A JNZ NEAR 0047A043 是“e”吗?不是则假
016F:00479F60 LEA EAX,[EBP-0C]
016F:00479F63 PUSH EAX
016F:00479F64 MOV ECX,06
016F:00479F69 MOV EDX,04
016F:00479F6E MOV EAX,[EBP-04]
016F:00479F71 CALL 0040407C 取软件序号的第4至9位
016F:00479F76 LEA EAX,[EBP-30] 以下将序号的第4至9位做简单的变换:
016F:00479F79 PUSH EAX 如将“456789”变成“896745”
016F:00479F7A MOV ECX,02
016F:00479F7F MOV EDX,05
016F:00479F84 MOV EAX,[EBP-0C]
016F:00479F87 CALL 0040407C
016F:00479F8C PUSH DWORD [EBP-30]
016F:00479F8F LEA EAX,[EBP-34]
016F:00479F92 PUSH EAX
016F:00479F93 MOV ECX,02
016F:00479F98 MOV EDX,03
016F:00479F9D MOV EAX,[EBP-0C]
016F:00479FA0 CALL 0040407C
016F:00479FA5 PUSH DWORD [EBP-34]
016F:00479FA8 LEA EAX,[EBP-38]
016F:00479FAB PUSH EAX
016F:00479FAC MOV ECX,02
016F:00479FB1 MOV EDX,01
016F:00479FB6 MOV EAX,[EBP-0C]
016F:00479FB9 CALL 0040407C
016F:00479FBE PUSH DWORD [EBP-38]
016F:00479FC1 LEA EAX,[EBP-0C]
016F:00479FC4 MOV EDX,03
016F:00479FC9 CALL 00403F34
016F:00479FCE LEA EDX,[EBP-10]
016F:00479FD1 MOV EAX,[0048B8E0]
016F:00479FD6 MOV EAX,[EAX+06C0]
016F:00479FDC CALL 004306C0 --变换到此结束--
016F:00479FE1 MOV EBX,01
016F:00479FE6 LEA EAX,[EBP-14] 从这里到016F:0047A03D是一个循环,EBX是循环变量
016F:00479FE9 PUSH EAX
016F:00479FEA MOV ECX,01
016F:00479FEF MOV EDX,EBX
016F:00479FF1 MOV EAX,[EBP-10]
016F:00479FF4 CALL 0040407C 取软件序号的第EBX位
016F:00479FF9 LEA EAX,[EBP-18]
016F:00479FFC PUSH EAX
016F:00479FFD MOV EDX,07
016F:0047A002 SUB EDX,EBX
016F:0047A004 MOV ECX,01
016F:0047A009 MOV EAX,[EBP-0C]
016F:0047A00C CALL 0040407C 取注册码的第7-EBX位
016F:0047A011 MOV EDX,0047A0BC 在0047A0BC处有一张表:“123456789!@#$%^-*()PLWAQokmIJNuhbYGVtfcRDXeszESZrdxFTCygvUHBijnOKMplqwa”
016F:0047A016 MOV EAX,[EBP-14]
016F:0047A019 CALL 00404160 算出注册码的第7-EBX位在上表中的位置
016F:0047A01E MOV ESI,EAX 存入ESI
016F:0047A020 MOV EDX,0047A0BC
016F:0047A025 MOV EAX,[EBP-18]
016F:0047A028 CALL 00404160 算出软件序号的第EBX位在上表中的位置
016F:0047A02D MOV EDX,EAX 存入EDX及EAX
016F:0047A02F DEC EDX
016F:0047A030 CMP ESI,EDX ESI=EDX-1?
016F:0047A032 JZ 0047A039 是则真
016F:0047A034 INC EAX
016F:0047A035 CMP ESI,EAX ESI=EAX+1?
016F:0047A037 JNZ 0047A043 不是则假
016F:0047A039 INC EBX
016F:0047A03A CMP EBX,BYTE +07 共循环6次
016F:0047A03D JNZ 00479FE6 --循环结束--
016F:0047A03F MOV BYTE [EBP-05],01 真注册码的标志
016F:0047A043 XOR EAX,EAX
016F:0047A045 POP EDX
016F:0047A046 POP ECX
016F:0047A047 POP ECX
016F:0047A048 MOV [FS:EAX],EDX
016F:0047A04B PUSH DWORD 0047A06D
016F:0047A050 LEA EAX,[EBP-38]
016F:0047A053 MOV EDX,0C
016F:0047A058 CALL 00403C18
016F:0047A05D LEA EAX,[EBP-04]
016F:0047A060 CALL 00403BF4
016F:0047A065 RET
---------------------------------
总结一下注册码的产生机制:注册码为13位,其中第12位为任意字符,注册码的形式为:El@??????%s?e,第4-9位是根据软件序号的前6位产生的,而且不是唯一的(一个软件序号大概对应2^6=64个注册码)。分析上述算法不难做出注册机,不过作者的处境好象很困难,所以最好不要将注册机传播。
这里给出几个成功的注册码:
软件序号 注册码
1234567890 El@325476%s?e
61WM!dgQ^N El@27pAx@%s?e
另外,从2.21版的分析中发现一个数字:“740926”,估计是作者的生日,到时别忘了给他寄份贺卡喔。
- 标 题:《chm帮助编辑器V2.61》注册码破解心得: (11千字)
- 作 者:小 明
- 时 间:2001-2-17 15:50:22
- 链 接:http://bbs.pediy.com