• 标 题:某国产字体的破解兼最土的查看UniCode编码汉字方法兼压缩资源释放。 (7千字)
  • 作 者:Passion
  • 时 间:2002-9-30 23:52:574
  • 链 接:http://bbs.pediy.com

某某某某字体破解
Passion慢慢研究
2002-09-27

淘垃圾邮件的时候发现众多广告信中的一封是一款字体。去看了看,某某某某(国产,隐去名称)的确比较美观,奇怪的是作者居然将字体做成了限制时间运行需要注册的形式。本人的印象中字体就是一个ttf文件,哪还谈得上什么注册可言?现在见到这东西,马上来了兴趣。于是动手。

某某某某.exe文件必须先运行后,字体列表中才会出现这一款字体,因此必须从EXE文件下手。直接反一下乱得很,看来加了壳,FI以及GTW看一看是ASPACK,而ASPACKDIE直接脱不太成功。于是用TRW2000载入,PNEWSEC后到Code段入口中断,然后--倒霉的是TRW2000忽然没有PEDUMP命令了!用MAKEPE提示输入表重建错误,看来什么都得手工来。
PNEWSEC到入口452F3C,将入口的PUSH EBP等改成JMP 452F3C作死循环状,退出TRW,启动Procdump,Full Dump该“某某某某.exe”,Rebuild PE,再修改其入口为52F3C,保存后用UltraEdit打开,查刚才改的“E9 FB FF FF FF”,改回原来的“55 8B EC 83 C4”,保存后正常运行,脱壳成功。

GTW已经说它是用Delphi编的了。用DeDe反,有俩Form,一个是主窗口,另外一个却不是注册窗口,而是一个含有系统托盘区PopupMenu的隐藏窗口。另外该程序八成是用Delphi 6写的,因为窗体的dfm资源保存的是UNICODE的形式,汉字全是#38544#34255#31383#21475的形式,没法子,想了个歪主意,利用网页来看它。

题外话:用网页来看#21475形式的UNICODE内容的办法如下:

*******************************************************

<html>
<head>
<title>NewPage1</title> <meta http-equiv="Content-Type"
content="text/html; charset=UTF-16"> 关键是UTF-16
</HEAD>
<body>
<p>&#38544;&#34255;&#31383;&#21475;
<p>&#20351;&#29992;&#24517;&#35835;'(&S)
<p>&#27880;&#20876;&#36719;&#20214;'[&R]'
<P>&#36864;&#20986;'(&X)'
</body>
</HTML>

*******************************************************

把上面的#38544#34255#31383#21475等贴进来,#号前加上&数字后加上;就基本行了,该网页在IE中显示出正确的汉字如下:

隐藏窗口

使用必读'(&S)

注册软件'[&R]'

退出'(&X)'

--这是手头没工具时的应急法子。
好了,回到DFM文件, 

    object Regist: TMenuItem
      Caption = #27880#20876#36719#20214'[&R]'
      OnClick = RegistClick
    end

这是“注册软件”菜单,点击会弹出注册窗口。对应的452C6C处的RegistClick代码如下:

00452C6C  53                    push    ebx
00452C6D  8BD8                  mov    ebx, eax

* Reference to pointer to GlobalVar_00454C70
|
00452C6F  A14C3F4500            mov    eax, dword ptr [$00453F4C] { 注册标志;  }
00452C74  833800                cmp    dword ptr [eax], +$00
00452C77  750C                  jnz    00452C85        // 非0则表示未注册。

* Possible String Reference to: '软件已注册.版权归xx字业 '
|
00452C79  B8082D4500            mov    eax, $00452D08

* Reference to : TMessageForm._PROC_0042B3BC()        // 已经注册的话,弹出提示并Exit。
|
00452C7E  E83987FDFF            call    0042B3BC
00452C83  5B                    pop    ebx
00452C84  C3                    ret

00452C85  6A01                  push    $01
00452C87  A1944C4500            mov    eax, dword ptr [$00454C94]
00452C8C  50                    push    eax
00452C8D  6A0F                  push    $0F

* Reference to: Forms.Proc_00452174
|
00452C8F  E8E0F4FFFF            call    00452174    

// 这里会调用一个DLL的函数,动态跟踪的时候才能看到。

* Reference to pointer to GlobalVar_00454C70    
|
00452C94  8B154C3F4500          mov    edx, [$00453F4C] { 注册标志;  }
00452C9A  8902                  mov    [edx], eax
00452C9C  33D2                  xor    edx, edx

* Reference to pointer to GlobalVar_00454C48
|
00452C9E  A1103E4500            mov    eax, dword ptr [$00453E10]
00452CA3  8B0D944C4500          mov    ecx, [$00454C94]
00452CA9  0FB60C11              movzx  ecx, byte ptr [ecx+edx]
00452CAD  8908                  mov    [eax], ecx
00452CAF  42                    inc    edx
00452CB0  83C004                add    eax, +$04
00452CB3  83FA0A                cmp    edx, +$0A
00452CB6  75EB                  jnz    00452CA3

* Reference to pointer to GlobalVar_00454C70
|
00452CB8  A14C3F4500            mov    eax, dword ptr [$00453F4C] { 注册标志;  }
00452CBD  833800                cmp    dword ptr [eax], +$00
00452CC0  750F                  jnz    00452CD1

* Possible String Reference to: 'heng.dll'
|
00452CC2  68242D4500            push    $00452D24

* Reference to: Unit_00406678.Proc_00406848
|
00452CC7  E87C3BFBFF            call    00406848

* Reference to GlobalVar_00454C90
|
00452CCC  A3904C4500            mov    dword ptr [$00454C90], eax
00452CD1  B201                  mov    dl, $01
00452CD3  8BC3                  mov    eax, ebx

* Reference to: Unit1.Proc_00452864
|
00452CD5  E88AFBFFFF            call    00452864

* Reference to control Regist : TMenuItem
|
00452CDA  8B83FC020000          mov    eax, [ebx+$02FC]

* Possible String Reference to: '注册信息'
|
00452CE0  BA382D4500            mov    edx, $00452D38

* Reference to: Menus.Proc_004427EC
|
00452CE5  E802FBFEFF            call    004427EC

* Reference to pointer to GlobalVar_00454C70
|
00452CEA  A14C3F4500            mov    eax, dword ptr [$00453F4C] { 注册标志;  }
00452CEF  8338FF                cmp    dword ptr [eax], -$01
00452CF2  7509                  jnz    00452CFD
00452CF4  33D2                  xor    edx, edx
00452CF6  8BC3                  mov    eax, ebx

* Reference to: Unit1.Proc_00452864
|
00452CF8  E867FBFFFF            call    00452864
00452CFD  5B                    pop    ebx
00452CFE  C3                    ret

中间看不见什么敏感信息,倒是有个神秘的CALL,经动态跟踪看看,原来是Call LIUYS!HblKey306

* Reference to: Forms.Proc_00452174
|
00452C8F  E8E0F4FFFF            call    00452174    

看来作者也有些防DeDe全反而采取的调用DLL来进行注册的措施。看看SYSTEM目录下,果然有个LIUYS,也有个输出函数是HblKey306,要命的是又加了壳。--我对脱DLL的壳不太在行。抱着Try一Try的心态用ProcDump来一下,嘿嘿,脱出一个比原大79K大不少的150多K的DLL来,反反看,没问题,运气好又脱成了。

反一把,发现里头实在太长太复杂了。而且脱壳后的DLL连输入函数也看不见,看来这步分析算法不容易走通。

于是转到从外边动手。FormCreate事件里调用了这个DLL中的HblKey306函数,并把返回值EAX放入[$00453F4C],如果这里把返回值改作0,那么这个软件就注册了。

***************************************

FormCreate事件如下:
00452A78  53                    push    ebx

…………

00452A9D  6A0F                  push    $0F

* Reference to: Forms.Proc_00452174
|
00452A9F  E8D0F6FFFF            call    00452174 { LIUYS!KBLKEY306 } 看返回值是否注册

* Reference to pointer to GlobalVar_00454C70
|
00452AA4  8B154C3F4500          mov    edx, [$00453F4C] { 注册标志;  } 
00452AAA  8902                  mov    [edx], eax    // EAX会返回是否注册,0代表已经注册。

    // 改成              mov    [edx], 0    就什么事都没了。

…………

00452BAA  C3                    ret

好了,暴力破解通过。但还是不够爽。想想看,要用一种字体,居然还得启动一个可执行的程序?要是能从里头淘出一个fon文件就好了。下面来玩这个……

看看该字体的安装目录,并没有什么特殊的东西,连个DLL也不见一个(除了uninstall的)。回想ProcDump脱壳的时候,该exe文件使用了两个名字不太眼熟的DLL,一个是处理注册问题的LIUYS.dll,那么理论上另外一个就应该是包含字体信息的DLL了,而且字体信息差不多就是以资源的形式放在该DLL中的。
在SYSTEM目录下找到这个HENG.DLL,一看一M多,八成加了壳(因为汉字字体文件都是两三M的)复制出来,用ExeScope一看,有个FONTDATA的资源,看来就是了,不过不能查看。看来软件作者比较偏好ASPack,所有的可运行的全部用这个压缩加壳。

对付这个DLL不像上面的Procdump,光Dump一下用Exescope一看,资源仍然无法查看,似乎还是没有解压缩。正没法子的时候,想起了有个资源解压缩的工具freeres,用它打开,提示资源已经压缩,是否解压?解压后保存为xxxx.fon文件,复制进Windows/Font目录,打开写字板敲几个字选选字体看看,嘿嘿,行了。