• 标 题:Visual CHM 4.0的算法“特别破解” (8千字)
  • 作 者:NewHand 
  • 时 间:2004-02-10 16:48:48
  • 链 接:http://bbs.pediy.com

Visual CHM 4.0的算法“特别破解”

【软件名称】:Visual CHM 4.0

【软件简介】:运行于多种 Windows 平台,包括 Windows 95/98/Me/NT 4.0/2000/XP。一款不错的CHM制作和反编译于一身的利器! 
              Features of Visual CHM:

                Compile and decompile HTML help files 

                Add a batch of HTML files at one time 

                Integrate with windows explorer 

                WYSIWYG (What you see is what you get)

                Easily edit HTML files
                Support multiple language (Include English, Chinese, German, Spanish, and more)
【软件大小】:1570 KB    主程序:407KB

【软件主页】:http://www.wekasoft.com/vchm

    【作者】:NewHand[BCG]

【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! 

【调试环境】:Win98、OllDBG、PEiD、Aspackdie1.4

————————————————————————————————— 
【过程】: 请出PEiD,侦得是Aspack,那就先用Aspackdie1.4脱壳,虽然手脱很容易,但用此工具脱会廋身些!会知编写语言是:Borland Delphi 6.0 - 7.0,软件说有编辑15个标题的限制,就运行软件试试,然后知道软件在你导入编辑标题时进行数量统计,如你没注册,则统计到数量为16时就弹出提示;若你注册假码则不会提示你。并且“编译”的菜单和按钮会变灰,在Language的中文.ini里发现:
[RegForm]
Caption=注册
LabelReg.Caption=注册成功!
Label1.Caption=机器码:
Label2.Caption=用户名:
Label3.Caption=注册码:
ButtonOK.Caption=确定
ButtonCancel.Caption=退出
ButtonBuyNow.Caption=购买
ButtonBuyNow.Hint=在线时点击
Error=用户名的长度必须在 6 到 32 个字符之间!
Over=请重新启动本软件,检查注册!

Dede的使用我还不行,好了就用OD调戏它!
既然“导入编辑标题时进行数量统计,如你没注册,则统计到数量为16时就弹出提示”,即有会使用Messageboxa对话框函数:有了OD,又岂用在这函数下断,用OD载入主程序或Attach它,导入标题,使其弹出提示对话框,然后在OD里暂停并在当前指令下断点,回主程序点“确定”,会提示OD拦截成功,点return按钮或“Ctrl+F9”,按一下F8,是否返回了主程序领空?爽吗?那么你会想到判断的地方多数在附近吧,于是你就要向上翻找找Cmp register,(fh,10h)+Jmp类的指令了,怀疑的就断来看看改改的^_^
改了(参:☆★☆:***爆破①)后就是为了避开检测注册信息同时也使程序省省力气--太过疲劳不好^_^;再来验证是否成功了,结果是“编译”按钮和菜单没再变灰,但点“编译”时标题的数量在某程度上会不工作,呵呵,看来是有暗桩的,有人说Delph程序很清晰条理,果然,我们查找一下“字符串参考”,看看有没有“Compile”的家伙,发现了吗:
004E3577   .  68 2C394E00   PUSH VCHM.004E392C                         ASCII "Start Building ... "
004E357C   .  8D45 D4       LEA EAX,DWORD PTR SS:[EBP-2C]
004E357F   .  50            PUSH EAX
004E3580   .  A1 00164F00   MOV EAX,DWORD PTR DS:[4F1600]
004E3585   .  8B00          MOV EAX,DWORD PTR DS:[EAX]
004E3587   .  B9 48394E00   MOV ECX,VCHM.004E3948                      ASCII "BeginCompile"
004E358C   .  BA 60394E00   MOV EDX,VCHM.004E3960                      ASCII "MainForm"
同样也是向上找找一些关键的比较、跳转作分析,然后跟踪看看改改的^_^(参:☆★☆:***爆破②),你也完全可以在点按下“编译”前,下断一些你认为能够中断的函数……进行你自己的跟踪^_^

输入的“用户名:”和“注册码:”只检测用户名长度,并会分别保存到注册表"SoftWare\XgSoft\Visual CHM 3.0\"的"Email"和"RegisterCode",在重启才计算注册码和用户名》
004D46A9  |.  E8 1628FAFF   CALL VCHM.00476EC4
004D46AE  |.  B1 01         MOV CL,1
004D46B0  |.  BA 28484D00   MOV EDX,VCHM.004D4828                      ASCII "SoftWare\XgSoft\Visual CHM 3.0\"
……
004D46ED  |.  83F8 21       CMP EAX,21
004D46F0  |.  7E 2B         JLE SHORT VCHM.004D471D
004D46F2  |>  68 50484D00   PUSH VCHM.004D4850                         ASCII "The length of the user name must range from 6 to 32"
……
004D4755  |. /74 26         JE SHORT VCHM.004D477D                     
004D4757  |> |68 B0484D00   PUSH VCHM.004D48B0                         ASCII "Please restart the progamme and make sure of the successful registration !"

004D40BB  |.  BA F0434D00   MOV EDX,VCHM.004D43F0                      ASCII "RegForm"
004D40C0  |.  8BC3          MOV EAX,EBX                                注册对话框标题
……
004D40E1  |.  B1 01         MOV CL,1                                   下面是对“注册对话框”输入内容进行读取
004D40E3  |.  BA 00444D00   MOV EDX,VCHM.004D4400                      ASCII "SoftWare\XgSoft\Visual CHM 3.0\"
004D40E8  |.  8BC6          MOV EAX,ESI
004D40EA  |.  E8 392EFAFF   CALL VCHM.00476F28
004D40EF  |.  8D4D FC       LEA ECX,DWORD PTR SS:[EBP-4]
004D40F2  |.  BA 28444D00   MOV EDX,VCHM.004D4428                      ASCII "Email"
……
004D4107  |.  E8 80B8F7FF   CALL VCHM.0044F98C
004D410C  |.  8D4D F8       LEA ECX,DWORD PTR SS:[EBP-8]
004D410F  |.  BA 38444D00   MOV EDX,VCHM.004D4438                      ASCII "RegisterCode"

004E3071   .  8338 00       CMP DWORD PTR DS:[EAX],0                   是否导入了*.VCM
004E3074   .  75 10         JNZ SHORT VCHM.004E3086
004E3076   .  8B15 70144F00 MOV EDX,DWORD PTR DS:[4F1470]              VCHM.004F2C3C
004E307C   .  8B12          MOV EDX,DWORD PTR DS:[EDX]
004E307E   .  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
004E3081   .  E8 3EAEFFFF   CALL VCHM.004DDEC4                         询问保存位置和类型
004E3086   >  A1 04124F00   MOV EAX,DWORD PTR DS:[4F1204]
004E308B   .  8338 00       CMP DWORD PTR DS:[EAX],0                   是否点按了“取消”
004E308E   .  0F84 21080000 JE VCHM.004E38B5
--往后有一段段验证算码的,呵呵这里就不贴了……

☆★☆:
多次跟踪,发现重启只对注册码和用户名进行计算,而不作比较,验证会放在导入标题数目过15、点击“编译”标题数目超过52项、和打开注册对话框。
那么光解除功能限制,只需爆破两处地方:
004E430A  |.  83F8 10       CMP EAX,10                                 限制编译15个标题跳向验证的地方
004E430D  |.  7D 34         JGE SHORT VCHM.004E4343                    ***爆破①:将这句指令改成nop***

004E3433   .  83F8 34       CMP EAX,34                                 比较是否超过 52 项跳向验证的地方
004E3436   .  7E 0A         JLE SHORT VCHM.004E3442                    ***爆破②:将Jle改成Jmp***
004E3438   .  807D EF 00    CMP BYTE PTR SS:[EBP-11],0                 [EBP-11]=[77FA23]值关键比较之一

004E335A      32C0          XOR AL,AL                                  ***爆破②:关键点之一 改成XOR AL,DL***
004E335C   .  74 04         JE SHORT VCHM.004E3362
004E335E   >  33C0          XOR EAX,EAX
004E3360   .  EB 02         JMP SHORT VCHM.004E3364
004E3362   >  B0 01         MOV AL,1                                   标志位之一
004E3364   >  8845 EF       MOV BYTE PTR SS:[EBP-11],AL

★☆★:
改算法(有局限性:只支持等于10位长度的用户名):
由于计码实在太长,要看个清清楚楚明明白白实在折磨人(烤你耐性),有机会再搞出来,偶只是找出生成关键比较码的某地方!
004E6F5D  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]                 启动检测
004E6F5F  |.  BA EC874E00   MOV EDX,VCHM.004E87EC                      ASCII "Email"
004E6F64  |.  E8 B702F9FF   CALL VCHM.00477220
004E6F69  |.  8B85 28FEFFFF MOV EAX,DWORD PTR SS:[EBP-1D8]             用户名
……往后有一大段检测和算码的,这里就不贴了……
004E771E  |.  E8 B1D9F1FF   |CALL VCHM.004050D4
004E7723  |.  885C30 FF     |MOV BYTE PTR DS:[EAX+ESI-1],BL            ***这里产生最终之一计算用户名(与用户名长度相等)关键比较码的地方***
……
004E7B26  |.  E8 A9D5F1FF   |CALL VCHM.004050D4
004E7B2B  |.  8B55 E0       |MOV EDX,DWORD PTR SS:[EBP-20]
004E7B2E  |.  885C10 FF     |MOV BYTE PTR DS:[EAX+EDX-1],BL            ***这里生成10位关键对比码的地方 ***

在验证比较时,会取和,如果的长度不为10,就会再度进行计算,这会令比较码又变来变去了,但好像始终没变,呵呵,偶就想了个偷懒的办法(用户名要求必须10位长度,用户名、注册码任意!)

……
004E770C      83FB 61       CMP EBX,61                                 改成:"MOV BL,41"+"Nop"
004E770F      7D 05         JGE SHORT VCHM.004E7716                    改成:JMP SHORT 004E7716
……
004E7AD5      48            DEC EAX                                    改成:Nop去
004E7AD6      83F8 00       CMP EAX,0
004E7AD9  |.  7C 60         JL SHORT VCHM.004E7B3B
……
004E7B14      83FB 61       CMP EBX,61                                 改成: "MOV BL,41"+"Nop"
004E7B17      7D 05         JGE SHORT VCHM.004E7B1E                    改成: JMP SHORT 004E7B1E

这样改了:输入特定长度用户名后重启打开注册对话框时,就发现了“注册成功!”字样和“购买”按钮不见了,同时注册填写处锁死了、功能开放了,应该跟真正注册差不多吧!