老文章档案 · 2003 年

破解对象:Visual CHM 3.20b

破解教程 · 算法分析 · 2003-08-14 · 作者:人气: · 出处:赢政天下整理收藏)

软件简介:

Visual CHM 是一个非常便利的制作CHM文件的工具,完全的可视化*作。

多种编译属性,可以使制作出的CHM文件具有非常的专业感。

喜欢做电子书,喜欢收集网络文章的朋友,非常值得下载试用。

相信,当您开始使用 Visual CHM 时再不会为怎么制作CHM文件头疼,

再也不用学习CHM帮助文件制作方法了。

软件限制:

没有注册的版本会有50个文件的限制。

破解者:DarkNess0ut

破解目的:注册码算法分析,制作注册机

破解工具:DeDe 3.1\ keyMake 1.73 \FI 2.5\VC++\aspackdie1.4

破解说明:软件采用非明码校验,难度大,动静结合分析。分析算法,制作注册机!

启动时计算用户名和密码,加上“注册”时,校验密码!

本破解只是研究算法和破解,请支持国产优秀软件!

鉴于v3.10已经写过了,破解的过程,这次就不写了,把v3.2里的Email转换代码和Code的转换代码贴出来。

1。Email第一次转换,函数EmailConv_1(Email)

将EBX转换成小写字母的函数为ConvCode(EBX,Index)

源代码见v3.10

=============================================================================

0050FE4E 8D45EC lea eax, [ebp-$14] //Email<==EDX

* Possible String Reference to: 'http://www.vchm.com/ ;convenient CHM

| editor,WYSIWYG.'

|

0050FE51 BA60125100 mov edx, $00511260 //Key

* Reference to: System.Proc_00404C80

|

0050FE56 E8254EEFFF call 00404C80

* Reference to Mainform

|

0050FE5B 8B45FC mov eax, [ebp-$04]

0050FE5E 0540060000 add eax, +$00000640

* Reference to Mainform

|

0050FE63 8B55FC mov edx, [ebp-$04]

* Reference to field TMainform.OFFS_0638

|

0050FE66 8B9238060000 mov edx, [edx+$0638]

* Reference to: System.Proc_00404C3C

|

0050FE6C E8CB4DEFFF call 00404C3C

0050FE71 8D45E8 lea eax, [ebp-$18]

* Possible String Reference to: 's?

|

0050FE74 BA9C125100 mov edx, $0051129C

* Reference to: System.Proc_00404C80

|

0050FE79 E8024EEFFF call 00404C80

* Reference to Mainform

|

0050FE7E 8B45FC mov eax, [ebp-$04]

* Reference to field TMainform.OFFS_0640

|

0050FE81 8B8040060000 mov eax, [eax+$0640]

* Reference to: system.@LStrLen:Integer;

|

0050FE87 E83050EFFF call 00404EBC //计算Email长度

0050FE8C 8BF8 mov edi, eax

0050FE8E 85FF test edi, edi

0050FE90 7E66 jle 0050FEF8

0050FE92 BE01000000 mov esi, $00000001 //开始计数,循环转换

* Reference to Mainform

|

0050FE97 8B45FC mov eax, [ebp-$04]

* Reference to field TMainform.OFFS_0640

|

0050FE9A 8B8040060000 mov eax, [eax+$0640]

0050FEA0 8A5C30FF mov bl, byte ptr [eax+esi-$01] //Email(esi-1)

0050FEA4 8B45EC mov eax, [ebp-$14]

0050FEA7 8A4430FF mov al, byte ptr [eax+esi-$01] //Key(esi-1)

0050FEAB 32D8 xor bl, al //Email xor Key

0050FEAD 81E3FF000000 and ebx, $000000FF //EBX and $FF

0050FEB3 33DE xor ebx, esi //EBX Xor esi

0050FEB5 83FB41 cmp ebx, +$41 //下面一段将EBX转换

0050FEB8 7D0B jnl 0050FEC5 //成小写字母

0050FEBA 8D441E16 lea eax, [esi+ebx+$16]

0050FEBE 8BD8 mov ebx, eax

0050FEC0 83FB41 cmp ebx, +$41

0050FEC3 7CF5 jl 0050FEBA

0050FEC5 83FB7A cmp ebx, +$7A

0050FEC8 7E0F jle 0050FED9

0050FECA 83EB1B sub ebx, +$1B

0050FECD 2BDE sub ebx, esi

0050FECF 83FB7A cmp ebx, +$7A

0050FED2 7FF6 jnle 0050FECA

0050FED4 EB03 jmp 0050FED9

0050FED6 83C304 add ebx, +$04

0050FED9 83FB61 cmp ebx, +$61

0050FEDC 7D05 jnl 0050FEE3

0050FEDE 83FB5A cmp ebx, +$5A

0050FEE1 7FF3 jnle 0050FED6

* Reference to Mainform

|

0050FEE3 8B45FC mov eax, [ebp-$04] //符合的跳到这里

0050FEE6 0540060000 add eax, +$00000640 //取出Email的字符首地址

* Reference to: system.@VarCopyNoInd;

|

0050FEEB E81C52EFFF call 0040510C

0050FEF0 885C30FF mov [eax+esi-$01], bl //回写到原地方覆盖

0050FEF4 46 inc esi

0050FEF5 4F dec edi

0050FEF6 759F jnz 0050FE97 //没有全部转换完毕的继续

0050FEF8 8D45E8 lea eax, [ebp-$18] //EDX里面就是转换的结果

到此。第一次转换结束,Email-->Email_1

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

接下来第二段是Code 的转换,函数ConvCode(EBX,Index)一样不变

将Code转换成中间字符,以便最后的校验。

函数为ConvCode((EBX Xor index)+&H29,Index)

0051015E 8B45FC mov eax, [ebp-$04] //EDX=Code

00510161 0560060000 add eax, +$00000660

00510166 BA0A000000 mov edx, $0000000A //只用10位

* Reference to: System.Proc_00405240

|

0051016B E8D050EFFF call 00405240 //留下10位

* Reference to Mainform

|

00510170 8B45FC mov eax, [ebp-$04]

* Reference to field TMainform.OFFS_0660

|

00510173 8B8060060000 mov eax, [eax+$0660] //Code10

* Reference to: system.@LStrLen:Integer;

|

00510179 E83E4DEFFF call 00404EBC

0051017E 8BD8 mov ebx, eax

* Reference to Mainform

|

00510180 8B45FC mov eax, [ebp-$04]

00510183 0560060000 add eax, +$00000660

00510188 8BD3 mov edx, ebx

* Reference to: System.Proc_00405240

|

0051018A E8B150EFFF call 00405240

* Reference to Mainform

|

0051018F 8B45FC mov eax, [ebp-$04]

* Reference to field TMainform.OFFS_0660

|

00510192 8B8060060000 mov eax, [eax+$0660]

* Reference to: system.@LStrLen:Integer;

|

00510198 E81F4DEFFF call 00404EBC

0051019D 8BF8 mov edi, eax

0051019F 85FF test edi, edi

005101A1 7E5C jle 005101FF

005101A3 BE01000000 mov esi, $00000001 //开始计数

* Reference to Mainform

|

005101A8 8B45FC mov eax, [ebp-$04]

* Reference to field TMainform.OFFS_0660

|

005101AB 8B8060060000 mov eax, [eax+$0660] //code10

005101B1 33DB xor ebx, ebx

005101B3 8A5C30FF mov bl, byte ptr [eax+esi-$01] //ebx=Code10(esi-1)

005101B7 33DE xor ebx, esi //ebx=ebx xor esi

005101B9 83C329 add ebx, +$29 //ebx=ebx +$29

005101BC 83FB41 cmp ebx, +$41 //将ebx 转换成小写字母

005101BF 7D0B jnl 005101CC

005101C1 8D441E16 lea eax, [esi+ebx+$16]

005101C5 8BD8 mov ebx, eax

005101C7 83FB41 cmp ebx, +$41

005101CA 7CF5 jl 005101C1

005101CC 83FB7A cmp ebx, +$7A

005101CF 7E0F jle 005101E0

005101D1 83EB1B sub ebx, +$1B

005101D4 2BDE sub ebx, esi

005101D6 83FB7A cmp ebx, +$7A

005101D9 7FF6 jnle 005101D1

005101DB EB03 jmp 005101E0

005101DD 83C304 add ebx, +$04

005101E0 83FB61 cmp ebx, +$61

005101E3 7D05 jnl 005101EA

005101E5 83FB5A cmp ebx, +$5A

005101E8 7FF3 jnle 005101DD

* Reference to Mainform

|

005101EA 8B45FC mov eax, [ebp-$04] //结束后,到这里

005101ED 0560060000 add eax, +$00000660

* Reference to: system.@VarCopyNoInd;

|

005101F2 E8154FEFFF call 0040510C

005101F7 885C30FF mov [eax+esi-$01], bl //覆盖到原先的位置

005101FB 46 inc esi

005101FC 4F dec edi

005101FD 75A9 jnz 005101A8 //循环直到全部转换

* Reference to Mainform

|

005101FF 8B45FC mov eax, [ebp-$04] //EDX=Code2

Code--Code2,要变成大写的用于后面的比较

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

最后就是Email2的获得和Email2与Code2的校验了

Email_1==>EMail_2的函数EmailConv_2(Email_1)

算法很烦的,简单提一提

0050DF7C 8B45FC mov eax, [ebp-$04]

* Reference to: system.@LStrLen:Integer;

|

0050DF7F E8386FEFFF call 00404EBC

0050DF84 83F80B cmp eax, +$0B

0050DF87 7F8D jnle 0050DF16

0050DF89 33DB xor ebx, ebx

* Reference to field TMainform.OFFS_0654

|

0050DF8B 8B8654060000 mov eax, [esi+$0654] //EAX=Email_1

* Reference to: system.@LStrLen:Integer;

|

0050DF91 E8266FEFFF call 00404EBC //字符长度

0050DF96 8BF8 mov edi, eax

0050DF98 E9BA000000 jmp 0050E057

0050DF9D 83FF15 cmp edi, +$15 //与$15比较,两条路

0050DFA0 7D03 jnl 0050DFA5 //〉=的jump

0050DFA2 43 inc ebx //< 的ebx+1

0050DFA3 EB15 jmp 0050DFBA

* Reference to field TMainform.OFFS_0654

|

0050DFA5 8B8654060000 mov eax, [esi+$0654] //>=的算法

* Reference to: system.@LStrLen:Integer;

|

0050DFAB E80C6FEFFF call 00404EBC

0050DFB0 B909000000 mov ecx, $00000009 //ebx=len(email) mod 9 ;余数==〉ebx

0050DFB5 99 cdq

0050DFB6 F7F9 idiv ecx

0050DFB8 8BDA mov ebx, edx

* Reference to field TMainform.OFFS_0654

|

0050DFBA 8B8654060000 mov eax, [esi+$0654] //两者会合的算法

* Reference to: system.@LStrLen:Integer;

|

0050DFC0 E8F76EEFFF call 00404EBC //eax=len(email_1)

0050DFC5 2BC3 sub eax, ebx //eax=eax-ebx

* Reference to field TMainform.OFFS_0654

|

0050DFC7 8B9654060000 mov edx, [esi+$0654]

0050DFCD 8A4402FF mov al, byte ptr [edx+eax-$01] //al=email_1(eax-1)

* Reference to field TMainform.OFFS_0654

|

0050DFD1 8B9654060000 mov edx, [esi+$0654]

0050DFD7 8A541AFF mov dl, byte ptr [edx+ebx-$01] //dl=email_1(edx-1)

0050DFDB 32C2 xor al, dl //Xor

0050DFDD 25FF000000 and eax, $000000FF //and $FF

0050DFE2 83C079 add eax, +$79 // + $79

0050DFE5 50 push eax

* Reference to field TMainform.OFFS_0654

|

0050DFE6 8D8654060000 lea eax, [esi+$0654]

* Reference to: system.@VarCopyNoInd;

|

0050DFEC E81B71EFFF call 0040510C

0050DFF1 5A pop edx

0050DFF2 885418FF mov [eax+ebx-$01], dl //保存回去

* Reference to field TMainform.OFFS_0654

|

0050DFF6 8B8654060000 mov eax, [esi+$0654]

0050DFFC 0FB64418FF movzx eax, byte ptr [eax+ebx-$01]//又取出来

* Reference to: MakeCHM.Proc_00504078

|

0050E001 E87260FFFF call 00504078 //convCode(eax,0)变成小写

0050E006 50 push eax

* Reference to field TMainform.OFFS_0654

|

0050E007 8D8654060000 lea eax, [esi+$0654]

* Reference to: system.@VarCopyNoInd;

|

0050E00D E8FA70EFFF call 0040510C

0050E012 5A pop edx

0050E013 885418FF mov [eax+ebx-$01], dl //写回去

* Reference to field TMainform.OFFS_0654

|

0050E017 8D8654060000 lea eax, [esi+$0654]

0050E01D 50 push eax

* Reference to field TMainform.OFFS_0654

|

0050E01E 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrLen:Integer;

|

0050E024 E8936EEFFF call 00404EBC

0050E029 8BC8 mov ecx, eax

0050E02B 2BCB sub ecx, ebx //len-ebx

0050E02D BA01000000 mov edx, $00000001

* Reference to field TMainform.OFFS_0654

|

0050E032 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrCopy;

|

0050E038 E8D770EFFF call 00405114 //截取字符,形成新的

* Reference to field TMainform.OFFS_0654

|

0050E03D 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrLen:Integer;

|

0050E043 E8746EEFFF call 00404EBC

0050E048 8BD0 mov edx, eax

0050E04A 2BD3 sub edx, ebx //再减一次=>len-2*ebx

* Reference to field TMainform.OFFS_0654

|

0050E04C 8D8654060000 lea eax, [esi+$0654]

* Reference to: System.Proc_00405240

|

0050E052 E8E971EFFF call 00405240 //在形成新的

* Reference to field TMainform.OFFS_0654

|

0050E057 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrLen:Integer;

|

0050E05D E85A6EEFFF call 00404EBC //计算长度

0050E062 83F80B cmp eax, +$0B //与$0B比较

0050E065 0F8F32FFFFFF jnle 0050DF9D //大于的继续循环,直到小于==>NewEmail

0050E06B 33DB xor ebx, ebx

0050E06D EB40 jmp 0050E0AF

0050E06F 43 inc ebx //ebx=ebx+1

* Reference to field TMainform.OFFS_0654

|

0050E070 8B8654060000 mov eax, [esi+$0654]

0050E076 8A4418FF mov al, byte ptr [eax+ebx-$01] //al=newemail(ebx-1)

0050E07A 3455 xor al, $55 //al xor $55

0050E07C 25FF000000 and eax, $000000FF //and &ff

0050E081 8D5346 lea edx, [ebx+$46] //

0050E084 33C2 xor eax, edx //eax xor ($46+ebx)

0050E086 8845FB mov [ebp-$05], al

0050E089 33C0 xor eax, eax

0050E08B 8A45FB mov al, byte ptr [ebp-$05]

* Reference to: MakeCHM.Proc_00504078

|

0050E08E E8E55FFFFF call 00504078 //变成小写convcode(eax,0)=>al

0050E093 8845FB mov [ebp-$05], al

0050E096 8D45F0 lea eax, [ebp-$10]

0050E099 8A55FB mov dl, byte ptr [ebp-$05] //dl=al

* Reference to: system.@LStrFromChar(String;Char);

|

0050E09C E8276DEFFF call 00404DC8

0050E0A1 8B55F0 mov edx, [ebp-$10]

* Reference to field TMainform.OFFS_0654

|

0050E0A4 8D8654060000 lea eax, [esi+$0654]

* Reference to: system.@LStrCat;

|

0050E0AA E8156EEFFF call 00404EC4 //附加到原来的字符后面,形成新的

* Reference to field TMainform.OFFS_0654

|

0050E0AF 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrLen:Integer;

|

0050E0B5 E8026EEFFF call 00404EBC //看看长度是否大于10了

0050E0BA 83F80A cmp eax, +$0A

0050E0BD 7D0E jnl 0050E0CD //>10 的继续

* Reference to field TMainform.OFFS_0654

|

0050E0BF 8B8654060000 mov eax, [esi+$0654]

* Reference to: system.@LStrLen:Integer;

|

0050E0C5 E8F26DEFFF call 00404EBC

0050E0CA 48 dec eax

0050E0CB 7FA2 jnle 0050E06F //到次结束

* Reference to field TMainform.OFFS_0654

|

0050E0CD 8D8654060000 lea eax, [esi+$0654]

0050E0D3 BA0A000000 mov edx, $0000000A //取10个

* Reference to: System.Proc_00405240

|

0050E0D8 E86371EFFF call 00405240

0050E0DD 8D55EC lea edx, [ebp-$14]

* Reference to field TMainform.OFFS_0654

|

0050E0E0 8B8654060000 mov eax, [esi+$0654]

* Reference to: sysutils.UpperCase(System.AnsiString):System.AnsiString;

|

0050E0E6 E8E9B1EFFF call 004092D4 //变成大写的

0050E0EB 8B55EC mov edx, [ebp-$14]

* Reference to field TMainform.OFFS_0654

|

0050E0EE 8D8654060000 lea eax, [esi+$0654]

* Reference to: System.Proc_00404C3C

|

0050E0F4 E8436BEFFF call 00404C3C

0050E0F9 8D45FC lea eax, [ebp-$04]

* Reference to field TMainform.OFFS_0648

|

0050E0FC 8B9648060000 mov edx, [esi+$0648]

* Reference to: System.Proc_00404C80

|

0050E102 E8796BEFFF call 00404C80

* Reference to field TMainform.OFFS_0674

|

0050E107 C6867406000001 mov byte ptr [esi+$0674], $01 //成功的标志,如果能锁定,呵呵!

0050E10E BF01000000 mov edi, $00000001

* Reference to field TMainform.OFFS_0674

|

0050E113 80BE7406000000 cmp byte ptr [esi+$0674], $00 //判断是否ok

0050E11A 741C jz 0050E138

* Reference to field TMainform.OFFS_0654

|

0050E11C 8B8654060000 mov eax, [esi+$0654]

0050E122 8A4438FF mov al, byte ptr [eax+edi-$01] //newEmail从前往后取出=〉al

0050E126 BA0B000000 mov edx, $0000000B

0050E12B 2BD7 sub edx, edi //对应后面的位置

0050E12D 8B4DFC mov ecx, [ebp-$04]

0050E130 8A5411FF mov dl, byte ptr [ecx+edx-$01] //Code2从后往前取出=〉dl

0050E134 32C2 xor al, dl //比较

0050E136 7404 jz 0050E13C

0050E138 33C0 xor eax, eax

0050E13A EB02 jmp 0050E13E

0050E13C B001 mov al, $01 //一样的,al=1

* Reference to field TMainform.OFFS_0674

|

0050E13E 888674060000 mov [esi+$0674], al

0050E144 47 inc edi //计数

0050E145 83FF0B cmp edi, +$0B

0050E148 75C9 jnz 0050E113

0050E14A EB2A jmp 0050E176 //成功跳出升天

好了,又写了一遍。

PS:上次忘了写了,

如果将解压后的软件在调试的时候察看的话,会看不见生成的NewEmail,只会出现“LLLLLLLLLF”相似的情况,

用Keymake跟踪源程序就不会有问题。

上次的注册机程序好像有一点问题,有些算出来不对,呵呵,比如DarkNess0ut在WinXP下就不行,呵呵,惨!

后来才发现是软件的BUG吧,11个用户名没有注册码,27个用户名也会出错。还有,密码为一个时,关闭程序,严重出错!

(出处:赢政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史