冒险解谜游戏中文网 ChinaAVG

标题: [转贴] GF汉化详细教程[内核修改篇] [打印本页]

作者: shane007    时间: 2008-10-6 10:42
标题: [转贴] GF汉化详细教程[内核修改篇]
  " S8 r* _' X1 O! N
经过前边的字库改造,已经完成了一半的工作,剩下最关键的显示汉字部分了。字库已经是中文的了,但是能让中文显示出来却不是件容易的事。不信现在进游戏试试,看到的中文全是乱码。为何?因为中文是双字节,两个字节才代表一个汉字。游戏显示英文字体的函数是为显示单字节的英文设计的,是不适合显示中文的,必须要修改。因为不可能得到程序的源代码,修改方法只能采用比较极端的修改可执行文件的方法了,即所谓的逆向工程。
; ^, O3 `; R- [' z8 f% t: p# z* x- O9 @5 v7 X
于是操起常用的调试工具Ollydbg开始调试游戏。经过2天的不懈努力,终于找到了显示字库的函数,以下列出读取字符的函数部分代码: - S; p- j3 \) L1 K
2 A+ O- H' v" X- _% [$ J
004AA909   8A08          mov cl,byte ptr ds:[eax]        
6 o& J) [4 U- U8 _$ V$ @4 D. F# U5 J1 R7 U
. N! c/ U1 i+ Y# J) I004AA90B   40            inc eax                                                                       
( ?! h! C" }9 y9 x/ |; U5 {1 q7 ~0 J2 ]6 G  \0 B" |1 E$ I2 V0 X# b8 N
004AA90C  8BF1           mov esi,ecx                     
: p4 N% d3 u+ d" X% G% j: x3 m
  M8 z/ M/ o* R# ~, |004AA90E  8BD6           mov edx,esi                     5 ?/ `  d0 v* M4 Y" @

( [5 ^5 K7 h# W8 s5 q004AA910  F7DA           neg edx                         - S5 K" B' ~0 O1 z8 j
. q7 v: m) D# d- V8 O, r) u
004AA912  1BD2           sbb edx,edx                     , Q1 q8 I6 m& [- ~8 L
: ]  y4 I) v" O4 V! j5 A
004AA914  23D0           and edx,eax                     1 T9 r. t* Y5 [2 K4 j: D5 F
6 G$ D# o. q9 a+ V, I" J7 h
004AA916  85F6           test esi,esi                    * @- Q1 @8 h5 j7 @* {) g5 y
, L+ g7 [; {+ ]* U/ @: [
004AA918  8917           mov dword ptr ds:[edi],edx      * u; b9 F, A3 O; S
) ^0 [( B1 v/ v7 n
  : d( U0 O* d: g1 C6 C
: l$ k& s0 p. m) s
函数开始Eax指向脚本文件grim.tab文件中某行脚本的第一个字符。例如主菜单”Control Help”中的C位置。004AA909一行的意图很明显,读取字符串中当前位置的的一个字符的ASCII码到放到cl中,然后Eax加一,指向下一个字符。然后会将此cl中的字符当作参数,调用另外一个显示字符的函数,完成读取字库文件并显示字符到屏幕的功能。 & U. j9 A; ^( T/ H. R

2 q" A* ^+ u* f* O我们需要对此部分做改造。如当前Eax指向一个英文字符,则还沿用程序原来的部分,读取一个字节到cl,并使Eax增一;如当前Eax指向一个中文汉字,则需要程序读取2个字节到cx中,并使Eax增二,指向下一个字符的正确位置。那么如何判断当前Eax指向的是一个英文字符还是中文汉字呢,GB2312汉字的编码有一个的特性:两个字节编码最高位(第8位)一定是1。每次读取字符时,先判断第8位是0还是1,如果是1一定是中文,是0则是英文。
: W- ?1 y9 i) p; X; p! u6 A. v
" R- Z6 s5 q: ?6 f6 Q有了思路,对读取字符的函数做如下修改,红色为新增代码: 4 v5 n+ [/ ?) O+ q
' J# b9 O" }) Q$ Z0 C
004AA909       8A08         mov cl,byte ptr ds:[eax]  
0 |; o" k, Q* R+ E" P
& Z- q" M  I$ A004AA90B       40            inc eax                    : h. E. A# b! l( Q9 U. F1 j8 p
( ]' r6 D- x+ ?  L$ ^& z' n4 x
                      f6c180       test cl,80h               0 O/ Z  I. j+ h0 T8 H

5 }: o/ ^9 X  J+ o. r% f                     7406           je 4aa90c                 
0 |1 X% M$ L5 _. O5 B. {/ c: P; E- v. @+ v2 Q: O
                     c1e108       shl ecx,08h               
4 K7 d" Q5 x9 X! j) N# h2 r7 k8 R) g* X: q/ b# P
                      8a08          mov cl,byte ptr ds:[eax]  7 b7 \# b5 i7 P
. f1 x2 I0 G- \$ b& Q# D0 g
                      40              inc eax                            4 G. o0 v: N7 c4 o
       004AA90C     8BF1           mov esi,ecx                3 t: y  ?6 O1 m( w; P

: Y( d3 p, p) w8 [: u# u2 Z004AA90E     8BD6           mov edx,esi               # q" \/ @. r4 j2 z0 r! `. ?

' F( D5 o: c9 j2 b+ W004AA910     F7DA           neg edx                  
7 t9 a- y8 |; q+ T& N! j
1 Y; Q, L- F2 c/ L. H3 C3 e# L004AA912     1BD2           sbb edx,edx               6 M; F# v# x5 f0 v; k& Y. A: g: S

8 Z1 L- }1 s7 @3 B' o004AA914     23D0           and edx,eax               
2 b' x" m& w5 f$ |' ^. y9 D/ r
/ |1 {& U  @( ?. W! \004AA916     85F6           test esi,esi              
6 y0 l- s  N- V
: i9 p% h9 V) V. ~004AA918     8917           mov dword ptr ds:[edi],edx 6 W" E0 R" f/ z9 e  K
7 z" A5 r3 c2 X$ I
  
' M7 ]# W9 s- d- D- z7 t% e2 Q
0 G$ J9 m% k7 q  U8 u先放Eax一个字节到cl中,然后判断cl的第8位是否为1,如果是0,说明是英文字符,则按程序原来的进度跳转到004AA90C这行的代码继续执行。如果是1,则要将cl向左移8位,为汉字第二个字节留下位置,然后再取一次Eax的值,把第二个字节放到cl中。最后Eax增一(Eax增了两次1)。此时Ecx的数值正是一个汉字两个字节的内码。Finish!
- m  I1 @7 z0 D2 O3 s2 p8 I4 M& H$ I- U7 U
然后用Uedit打开可执行文件,找到一段nop(90)比较多的位置,最后将红色部分的机器码加到合适位置就OK了。
! b: |; g, |: a, n( V" v+ ~2 s6 {  e6 w4 C: c! g) Z
原贴地址
6 K# P9 v0 Q+ u" t! p9 C8 [http://www.cnblogs.com/pscj/archive/2005/05/10/152760.html




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2