冒险解谜游戏中文网 ChinaAVG

标题: 关于静物2的分析 [打印本页]

作者: jinxin8866    时间: 2010-3-28 11:21
标题: 关于静物2的分析
00403CE0  |> /3B96 10110000    /cmp edx,dword ptr ds:[esi+1110]
3 g& x8 _2 ?! V$ L00403CE6  |. |1BC9             |sbb ecx,ecx7 m7 Q7 G: }: @4 P! }) O. Y  A! L
00403CE8  |. |23D1             |and edx,ecx
4 l) O7 p" |0 l5 [00403CEA  |. |8B8E 0C110000    |mov ecx,dword ptr ds:[esi+110C]
% U* }# E# v5 x' F7 o& [00403CF0  |. |8A0C0A           |mov cl,byte ptr ds:[edx+ecx]
* {5 }& D5 ^0 v$ ]9 {+ A# I00403CF3  |. |3008             |xor byte ptr ds:[eax],cl                   ;  这个循环就是异或算法
' j# h$ N7 X7 ~, Y" b: L/ i9 q00403CF5  |. |83C2 01          |add edx,11 j" w! ?3 q! A& _! O4 I5 m
00403CF8  |. |83C0 01          |add eax,1% F1 t) m6 |" O0 N
00403CFB  |. |83EF 01          |sub edi,1
# {* Y+ c7 w! K5 o% e00403CFE  |.^\75 E0            \jnz short SL2.00403CE0& V- v* N2 @9 X( E+ J, G1 G

  b2 N) g7 B9 x5 Y8 E& n4 e' \
' Q( ^8 k  H& h; L0 U+ f" w/ g6 }00401A42  |.  8D4C24 18        lea ecx,dword ptr ss:[esp+18]
: E  u, O  @/ _: n. i! L. l00401A46  |.  51               push ecx
! V6 a( Y/ o# [: }/ V9 y; e00401A47  |.  8D4C24 24        lea ecx,dword ptr ss:[esp+24]4 y, I& H- n# G+ ]: w& S7 g
00401A4B  |.  C68424 58110000 >mov byte ptr ss:[esp+1158],1
% z0 M6 t' j" @) |( C/ Z! v00401A53  |.  C687 08010000 00 mov byte ptr ds:[edi+108],0
# _% g, j/ D3 {6 s0 q: d00401A5A  |.  E8 51240000      call SL2.00403EB0                           ;  读取字体函数的开始四个字节; z6 `& z: O( F% U1 C
00401A5F  |.  817C24 18 474D47>cmp dword ptr ss:[esp+18],42474D47          ;  此处可判断出开始的四个字节应该是魔幻数% r& B; X# t9 M2 w3 ]
+0 魔幻数
: X- H, z- z" |8 s" Y) [+4 段数,; r0 M4 V8 m/ K% q( l7 p
下面开始是每段的头部! z* _( R/ Q& M- B, k4 x" H1 L
+46EE 正文
2 R! D! C, X! o; b
; J, R  y# g! T/ {5 X' U0 x0203DDE0  2F 45 58 54 44 41 54 41 53 46 4F 4E 54 2F 41 52  /EXTDATASFONT/AR, V: h  D5 A/ S" s3 ]
0203DDF0  49 41 4C 20 31 31 2E 45 4E 00                    IAL 11.EN.+ L; f9 N! j0 k; S# _4 y

8 X/ |. T5 S3 }# l% N9 z; p0203DEE0              75 16 00 00 (EE 46) 00 00 2F 45 58 54      ..頕../EXT
, f0 A& v7 S& I0203DEF0  44 41 54 41 53 46 4F 4E 54 2F 41 52 49 41 4C 20  DATASFONT/ARIAL8 R; Z, }; x0 O
0203DF00  31 32 2E 45 4E 00                                12.EN.
/ z9 K; j7 u& s2 e5 O" S8 n% b
1 H  u, g; ^* |9 Q. J, ^6 d上面表中的数据除了括号中的(EE 46),其余全部与解包后文件数据一致,
9 @: M( p, \: |* Z1675是这个段的长度,46EE是这个在文件中的偏移,每段偏移值的算法如下:2 I7 c/ y' y( P! q" y% j5 ?, U5 }

+ B6 d7 A6 b* j00401AE0  |> /899401 08010000  /mov dword ptr ds:[ecx+eax+108],edx         ;  edx=46ee* g% V+ ^. z5 ^% s
00401AE7  |. |8B06             |mov eax,dword ptr ds:[esi]                 ;  [esi]存放读取字符的地址+ C% q3 E: Y# l% P7 Q# N
00401AE9  |. |039401 04010000  |add edx,dword ptr ds:[ecx+eax+104]
% u3 v/ Q2 z. z! x3 B00401AF0  |. |83C3 01          |add ebx,1
6 ?2 b" A" C5 a; Z5 V8 J' J' K00401AF3  |. |81C1 0C010000    |add ecx,10C
# d' l% [. o! e* Y* H  ^1 K00401AF9  |. |3B5C24 14        |cmp ebx,dword ptr ss:[esp+14]              ;  [esp+14]=1C29 z% [+ [, V' m/ J# r5 ~2 ]; p8 H% x
00401AFD  |.^\72 E1            \jb short SL2.00401AE0
作者: shane007    时间: 2010-3-28 11:32
首先对楼主的大力支持表示非常感谢!
5 |" g( h  I. u9 k+ F想问一下,通过以上分析,能得出什么阶段性的结论吗?
作者: shane007    时间: 2010-3-28 11:34
或者说是否已经可以把字体文件的结构写出来了?
作者: jinxin8866    时间: 2010-3-28 12:06
Sl2fnt.dat文件格式分析如下:# ^3 T. y% y0 K$ `3 A
+0 474D4742  这个魔幻数
' s6 m5 y. i/ @8 R( A: @' E. E+ n/ F% u* \* A: {8 g. |9 P) A" c
+4 C2010000  表示有01C2个文件
2 F. h: M$ i# o& D) v
- M% y: [( n. O+8 2F4558544441544153464F4E542F415249414C2031312E454E002 y- j% `& V! c. i
/EXTDATASFONT/ARIAL 11.EN.u  }' }% `. J8 w
这个应该是文件头部,ARIAL表示字体,EN表示英语 11表示字号8 w  A$ Z9 K; B+ i
1 d7 R4 F4 g# ~3 ^
   751600 表示这个文件的大小
$ U9 D8 ]# A( M  @2 [+ ~9 t  u
7 e7 ^7 l; l7 `4 ?每个文件的偏移由上文中的最后那个函数得出
9 w/ B! Y! s$ Y3 S- ^5 [6 {; m3 u6 c/ h" B2 j
, d) p9 q' V; H" I2 {
+46EE 此处开始是每个文件的正文- {+ ]& K4 j6 a
3 x: h6 ]5 {9 j- M6 e# x* Y! p
如上面我举的这个例子,文件正文内容起始地址+46EE,9 v( _! P7 E! i% r: M( w
结束地址为+(46EE+1675)
作者: shane007    时间: 2010-3-28 12:11
这个其实不用分析,这个dat是个包文件,已经有解包器了啊。. p- i9 o; R: u0 f2 `' J
需要分析的是里面解出来的字体文件。字体文件的magic number是XCPK.3 X- Q: x$ Y" F3 y" o' b6 |

+ C$ T% }& V5 |. R! B7 d! Z我想知道XCPK文件的结构。
作者: shane007    时间: 2010-3-28 12:16
http://aluigi.altervista.org/papers.htm
2 ?( r8 \% U6 s- b7 W9 k: G  W0 q: H# @4 A
这里有stilllife2 dat文件解包器,配合quickbms使用
作者: jinxin8866    时间: 2010-4-1 10:58
标题: 回 楼主(jinxin8866) 的帖子
写屏函数:* S3 R% y  K) s: O
02A0EA4C  |> /8B00        |/mov eax,dword ptr ds:[eax]
/ R, n: ^" U, K2 O0 ?% ?02A0EA4E  |. |0FB70450    ||movzx eax,word ptr ds:[eax+edx*2]                    ;  [eax+edx*2]存放字符的UNICODE码! S: s9 N! ~3 e4 j( q6 |! m6 X8 s
02A0EA52  |. |8B7C24 14   ||mov edi,dword ptr ss:[esp+14]
1 U1 o5 ^) n( W7 c) H2 P& z02A0EA56  |. |8B7F 2C     ||mov edi,dword ptr ds:[edi+2C]
0 C3 G) w9 }' r0 l/ A4 _) @( r. c! N" P( v02A0EA59  |. |8D04C0      ||lea eax,dword ptr ds:[eax+eax*8]! p  \' w' I6 F0 F
02A0EA5C  |. |8D0487      ||lea eax,dword ptr ds:[edi+eax*4]                     ;  eax存放字符编码表7 V, {* S0 C: n( G  ~
每个字符码表占24(16进制)个字节
) |; k# r* P' q02A0EA5F  |. |8B7C24 0C   ||mov edi,dword ptr ss:[esp+C]
  e9 ~2 ?7 w0 ?02A0EA63  |. |8D7C39 14   ||lea edi,dword ptr ds:[ecx+edi+14]                    ;  edi就是显存地址
5 K5 S, r1 I+ c02A0EA67  |. |D940 04     ||fld dword ptr ds:[eax+4]
- o# ~. X4 i2 ^, o+ J02A0EA6A  |. |83C2 01     ||add edx,1                                              字符个数加一
6 T+ G' X2 n& G02A0EA6D  |. |D95C24 30   ||fstp dword ptr ss:[esp+30]* b5 t+ P% a3 z- }6 k9 Y9 j0 J; M5 Q8 w
02A0EA71  |. |D900        ||fld dword ptr ds:[eax]# d: L8 M8 m, H: ?9 z6 O
02A0EA73  |. |D91F        ||fstp dword ptr ds:[edi]                              ;  edi就是显存地址
: M4 h, `9 L* w6 _! X  ~% [每个字符占1C个字节,最后的四个字节都是一样的,可以认为是结束标志- c3 G* y) g0 Z7 }
02A0EA75  |. |D94424 30   ||fld dword ptr ss:[esp+30]
7 o; {6 W6 q9 G# [02A0EA79  |. |D95F 04     ||fstp dword ptr ds:[edi+4]" Y- T/ l" R, \1 O: {
02A0EA7C  |. |8B7C24 0C   ||mov edi,dword ptr ss:[esp+C]$ `6 ]9 S2 N! O! B& B
02A0EA80  |. |D940 04     ||fld dword ptr ds:[eax+4]
9 c- a0 A, h/ L' n& I  \02A0EA83  |. |8D7C39 30   ||lea edi,dword ptr ds:[ecx+edi+30]( h4 e1 C/ T7 ~% z
02A0EA87  |. |D95C24 30   ||fstp dword ptr ss:[esp+30]
) r: ~) h/ f$ A( O$ I5 z02A0EA8B  |. |D940 08     ||fld dword ptr ds:[eax+8]
' r3 g7 Y$ u0 V02A0EA8E  |. |D91F        ||fstp dword ptr ds:[edi]& J$ J: G2 a: A% e
02A0EA90  |. |D94424 30   ||fld dword ptr ss:[esp+30]
7 r& Z7 y) ?9 z02A0EA94  |. |D95F 04     ||fstp dword ptr ds:[edi+4]$ k( X% R' S5 ?& [- L+ k2 b: l' d
02A0EA97  |. |8B7C24 0C   ||mov edi,dword ptr ss:[esp+C]
6 s0 h; p. m4 F1 \6 ?02A0EA9B  |. |D940 0C     ||fld dword ptr ds:[eax+C]
/ U$ a  X8 B) T2 [! H02A0EA9E  |. |8D7C39 4C   ||lea edi,dword ptr ds:[ecx+edi+4C]  s9 c! D3 k5 G( [9 e
02A0EAA2  |. |D95C24 30   ||fstp dword ptr ss:[esp+30]! l) Q/ R+ `' P% x3 H) m
02A0EAA6  |. |D900        ||fld dword ptr ds:[eax]. @4 J) v: Q' [+ n' B9 H: D8 w' m
02A0EAA8  |. |D91F        ||fstp dword ptr ds:[edi]( k% r5 L- t! M- p: _; {) L
02A0EAAA  |. |D94424 30   ||fld dword ptr ss:[esp+30]
/ U7 J' {5 V% S& c02A0EAAE  |. |D95F 04     ||fstp dword ptr ds:[edi+4]( b, H# n2 j0 A  {; ?  m6 I; B
02A0EAB1  |. |8B7C24 0C   ||mov edi,dword ptr ss:[esp+C]
$ M) [+ k- Y, N& d. ~( u' s02A0EAB5  |. |D940 0C     ||fld dword ptr ds:[eax+C]. O! j: a+ Y) u: i( j$ @
02A0EAB8  |. |8D7C39 68   ||lea edi,dword ptr ds:[ecx+edi+68]7 |& l# p: U; y5 M7 e
02A0EABC  |. |D95C24 30   ||fstp dword ptr ss:[esp+30]+ n9 D+ q; X+ [& m) c- i- w5 ]
02A0EAC0  |. |83C1 70     ||add ecx,70
* {, d4 r# i  w02A0EAC3  |. |D940 08     ||fld dword ptr ds:[eax+8]0 F! K0 y) h3 L( k' p
02A0EAC6  |. |D91F        ||fstp dword ptr ds:[edi]
' ?" n) w- ]) d7 {2 F) F02A0EAC8  |. |D94424 30   ||fld dword ptr ss:[esp+30]
7 p) A7 ^$ t) T! t5 E% G/ m02A0EACC  |. |D95F 04     ||fstp dword ptr ds:[edi+4]
# c3 _! H9 e  A/ f8 Y02A0EACF  |. |8B46 58     ||mov eax,dword ptr ds:[esi+58]1 F( Q) U* t  `3 T
02A0EAD2  |. |03C3        ||add eax,ebx. V! V* D' g6 M$ k4 r
02A0EAD4  |. |3B50 08     ||cmp edx,dword ptr ds:[eax+8]
* R$ Y/ K3 v, B( w+ E# ^/ H02A0EAD7  |.^\\0F8C 6FFFFF>|\\jl xcDxShad.02A0EA4C" X+ a( I/ G" t) y0 S

4 o) P  ~; e% {$ _: g本游戏字符编码采用UNICODE,& w2 K$ y  B# x4 b! Y
对字符码表的操作:% L7 d8 Z' w' A, l* l) W
10028807  |> /0FB702      /movzx eax,word ptr ds:[edx]        读字符的UNICODE码; ^7 l; L; }2 p# k# [
1002880A  |. |8D04C0      |lea eax,dword ptr ds:[eax+eax*8]- J! R7 A6 v/ E, E% ~! Q8 |
1002880D  |. |8D0483      |lea eax,dword ptr ds:[ebx+eax*4]   根据UNICODE码求得字符码表的地址
- V# J) ^3 B- x. X9 I10028810  |. |33C9        |xor ecx,ecx
' M3 Z8 M# F" J/ w. T* u10028812  |. |DB40 20     |fild dword ptr ds:[eax+20]
5 ~2 Z8 h8 v2 v10028815  |. |D95C24 14   |fstp dword ptr ss:[esp+14]
, r& d; K9 ^, {9 K10028819  |. |D94424 14   |fld dword ptr ss:[esp+14]
1 A! U9 F& E! O) V2 m1002881D  |. |D9C0        |fld st
9 ]. M  V# U' u4 C, W8 @; F8 `1002881F  |. |D84E 14     |fmul dword ptr ds:[esi+14]- x' @* V0 Q! U* x
10028822  |. |D94424 0C   |fld dword ptr ss:[esp+C]
& k5 y& T$ b. W' W+ {4 u4 |10028826  |. |D9C0        |fld st
4 g, d- u  ?5 P7 F  S/ P10028828  |. |DEC2        |faddp st(2),st# E8 t- @/ ?, [" |1 H
1002882A  |. |D9C9        |fxch st(1)
& R* _4 C) M  D: ~- _1002882C  |. |D95C24 14   |fstp dword ptr ss:[esp+14]
* ]( ^/ _5 X7 J" Z10028830  |. |D8D3        |fcom st(3)& K$ `. X5 e  a/ ?7 n/ F. k
10028832  |. |DFE0        |fstsw ax/ a  Z7 Q' Y( {8 V2 {/ V8 `
10028834  |. |F6C4 01     |test ah,1
5 X9 N* N# O/ f( D10028837  |. |74 2B       |je short xcEngine.10028864
8 ]# Y" D( l- e' T, r7 m  D% t( o10028839  |. |D94424 14   |fld dword ptr ss:[esp+14]& _1 S. U6 {/ d
1002883D  |. |D8D3        |fcom st(3)% N. r7 R' j- R, d
1002883F  |. |DFE0        |fstsw ax
6 H# {# K0 S! {; Y10028841  |. |F6C4 41     |test ah,41: `: A7 r0 G& \, W2 i) j: Y4 y
10028844  |. |7A 04       |jpe short xcEngine.1002884A
) F5 e7 [# k7 E$ [( I10028846  |. |DDD8        |fstp st! s* G7 L0 w1 G( V  B
10028848  |. |EB 1A       |jmp short xcEngine.10028864  d7 F3 P. i( ]
1002884A  |> |D9C9        |fxch st(1)
1 e) x: F7 Y& u# `, T. A6 V1002884C  |. |D8D3        |fcom st(3); G4 Q. y* |" p" U+ l9 ~8 F% t
1002884E  |. |DFE0        |fstsw ax4 \' M; b  M! O- F
10028850  |. |F6C4 05     |test ah,5
: B, r! r( f* J) u, _2 u( P% Z: H10028853  |. |7A 04       |jpe short xcEngine.10028859
$ C& x' j! z+ Y4 n3 t- g10028855  |. |DDD9        |fstp st(1)/ U0 ~7 h* g! b7 P) l1 E- o
10028857  |. |EB 0B       |jmp short xcEngine.10028864( J/ L8 `! |5 P' W6 O% h7 c" |
10028859  |> |D9C9        |fxch st(1)
7 G: p+ n# |. R( V( n1002885B  |. |D8DC        |fcomp st(4)5 @/ r! ?6 J* H) q) D- h4 `) N
1002885D  |. |DFE0        |fstsw ax
% L0 A7 O  _2 X, T- W* K( N1002885F  |. |F6C4 41     |test ah,41
: v3 D4 S6 i  q6 P3 B10028862  |. |75 05       |jnz short xcEngine.10028869
* j3 Y+ Z1 D' f6 [$ w10028864  |> |B9 01000000 |mov ecx,1
7 h3 {: k6 R  Z) g" `) G( S8 a) r10028869  |> |85C9        |test ecx,ecx
) I( L8 Q9 H( V$ T/ d! U% a/ Z. E9 C1002886B  |. |8B4424 18   |mov eax,dword ptr ss:[esp+18]
" o6 ~! F7 ^' o$ ?" v1002886F  |. |D940 14     |fld dword ptr ds:[eax+14]
* G/ T7 f/ ?5 G& P$ L5 B: w, D. n$ u10028872  |. |DECA        |fmulp st(2),st# p" v* o% N$ T8 x& \
10028874  |. |DEC1        |faddp st(1),st4 V. \  A5 Q- V/ P
10028876  |. |D95C24 0C   |fstp dword ptr ss:[esp+C]! x$ Y/ }% P" y4 d
1002887A  |. |75 05       |jnz short xcEngine.10028881
3 v$ p/ o% `0 I  c, x7 A* E1002887C  |. |834424 10 0>|add dword ptr ss:[esp+10],1
3 G7 i7 ?5 {) u# [& T" p# R6 b$ y10028881  |> |83C2 02     |add edx,2) R2 v7 p1 @) b1 a  X
10028884  |. |83EF 01     |sub edi,1* o% M8 I5 ^9 x, G
10028887  |.^\\0F85 7AFFFF>\\jnz xcEngine.10028807
7 j* V! @! C6 {& f由于算法采用了浮点数指令,本人不太懂,边学习边研究中。。。。。。。。。
作者: shane007    时间: 2010-4-1 11:13
加油!UNICODE码内核的游戏?
7 F1 [0 T! A, |, i1 T- x! v! H看来汉化有希望啊。
作者: shane007    时间: 2010-4-1 11:17
只要知道游戏读取字符图片以后,以何种格式,放到哪个内存地址。
  g/ t8 z, \2 p! z5 k即使我们无法解压字库,也可以通过内挂一个DLL,传入字符编码,把我们自己的字符图片写入对应的内存地址。从而达到汉化的目的。
作者: jinxin8866    时间: 2010-4-2 09:48
标题: 回 8楼(shane007) 的帖子
找到了内存中字库的地址,可在下面这个位置下断,  L% c; ~9 R8 x8 ~3 B! S

& K* F* t! [6 b( e: u# y( z  M* {02A0EA5C  |. |8D0487      ||lea eax,dword ptr ds:[edi+eax*4]                     ;  eax存放的就是字库的地址8 g- R8 B. N9 B  r
这个字库不是点阵的,经过修改,字符的形状可发生变化,应该是矢量字库
作者: shane007    时间: 2010-4-2 11:09
如果是矢量字库的话,看来用内挂就不太合适了。+ P: \, M, f" x3 N: M
必须要把字库结构分析清楚,然后在外面把字库修改好。
作者: jinxin8866    时间: 2010-4-9 15:11
标题: 静物2的解压算法
发现一段可疑的算法:
; I1 l+ W* s' T. n  @1008A43F   .  66:AD       lods word ptr ds:[esi]                     ;  esi:原文件数据缓冲区
0 b+ f3 q! W! U1008A441   .  8ACB        mov cl,bl
2 C4 e6 U1 n% j1 N) D1 |4 {( \1008A443   .  80C3 10     add bl,10
9 N0 A0 F* X" N2 Q6 X* n1008A446   .  D3E0        shl eax,cl  v4 |; H) t1 I' h, `$ t
1008A448   .  0BE8        or ebp,eax9 c8 j; d: ]# ?' [( G+ ?8 k  _
1008A44A   >  8B1424      mov edx,dword ptr ss:[esp]! {: x3 g- N# F! [2 W2 }% @
1008A44D   .  8B4C24 08   mov ecx,dword ptr ss:[esp+8]
- }. ^1 ^% O+ u9 O6 e1008A451   .  23D5        and edx,ebp. y. b9 m% M% r* z
1008A453   .  8B0491      mov eax,dword ptr ds:[ecx+edx*4]
7 E+ N2 i7 u5 P& a+ N- v5 }" p1008A456   >  8ACC        mov cl,ah
0 @! M. W* H4 S! Z- a& c! S  K1008A458   .  2ADC        sub bl,ah( X6 ~1 V+ }$ w. r
1008A45A   .  D3ED        shr ebp,cl
6 k7 o7 X! g- w0 \1008A45C   .  84C0        test al,al
1 B; Z+ k7 C5 a( @, J1008A45E   .  75 19       jnz short xcEngine.1008A479
' c' d. `0 r; g6 K1008A460   .  C1E8 10     shr eax,10
# K9 a8 U* a( j/ b  D$ \5 A  B1008A463   .  AA          stos byte ptr es:[edi]                    ;  edi:解压后文件数据缓冲区
! D% C# ?7 E7 {% [: Q" ~$ \8 r原文件数据缓冲区经跟踪就是Sl2fnt.dat异或后的数据,解压后的部分数据如下:
作者: shane007    时间: 2010-4-9 17:11
收到,感觉逐渐接近中。。。
作者: shane007    时间: 2010-4-9 18:46
对了,jinxin8866 你说这个游戏是矢量字库。
3 V) [, L( N! W  k我又仔细想了一下,觉得不是。. O4 I9 [5 l7 h9 Z3 X
理由是这个游戏的字体,每种语言都有不同大小字号的多个。
$ |, K+ `- W4 y5 p; Y如果是矢量字库的话,1种字体只要1种就行了,因为可以自由缩放嘛。
作者: jinxin8866    时间: 2010-4-13 13:42
字体Yellowjacket 18.EN占39B7个字节,解压后得到3个文件详见附件,其中dump3是索引表
作者: shane007    时间: 2010-4-13 17:13
内存dump下来的东西?/ O- v/ |0 z2 [
怎么会有3个文件呢? - y7 [/ G- d. @$ P
猜测:
8 c1 w) w  N4 F: O. U. ?& g第1个好象是字库,第2个应该是字库定义文件的位置部分,第3应该是字库定义文件的索引部分
作者: jinxin8866    时间: 2010-4-13 21:10
是的,又发现了以下数据,可能是对第二个文件格式的解析,继续研究中。。。。。。。。。。。
3 ]3 ^' K# M8 q6 e* C6 ~: f$ t034EA490                           6E 61 6D 65 13 00 00 00          name...( N: _% `8 L6 r2 i) ^
034EA4A0   59 65 6C 6C 6F 77 6A 61 63 6B 65 74 31 38 77 34  Yellowjacket18w4
  l5 t5 l6 E) _9 X034EA4B0   30 30 00 66 6C 61 67 04 00 00 00 00 00 00 00 77  00.flag.......w
/ G8 q+ a* L  _034EA4C0   64 74 68 04 00 00 00 00 01 00 00 68 67 74 68 04  dth......hgth
) }3 |3 m7 ]# f0 Q) ?034EA4D0   00 00 00 00 01 00 00 66 6D 74 20 04 00 00 00 15  ......fmt ...
9 l) N0 }/ Z$ a! n034EA4E0   00 00 00 6D 69 70 63 04 00 00 00 01 00 00 00 58  ...mipc......X
9 J6 F4 h2 _: J+ @1 v% i! Q034EA4F0   43 54 47 8B 26 00 00 6E 61 6D 65 13 00 00 00 59  CTG?..name...Y
) R$ Z, R7 h- O- f& g/ R6 m! j; I, U034EA500   65 6C 6C 6F 77 6A 61 63 6B 65 74 31 38 77 34 30  ellowjacket18w40( Q! x7 q8 l0 f- ~
034EA510   30 00 62 6D 61 70 04 00 00 00 01 00 00 00 68 67  0.bmap......hg7 o( a1 ^4 w  t, i* z2 p; Q
034EA520   68 74 04 00 00 00 00 00 B8 41 74 6F 70 20 04 00  ht.....窤top .5 @, ]9 H& X0 ]
034EA530   00 00 00 00 88 41 62 74 6F 6D 04 00 00 00 00 00  ....圓btom.....
5 K& X( A, Y' v; a  m0 B034EA540   C0 C0 63 74 65 72 04 00 00 00 00 00 B0 40 63 6C  览cter.....癅cl7 O' _7 A, w$ K
034EA550   73 74 24 24 00 00 00 00 00 BB 00 00 00 BB 00 00  st$$.....?..?.0 c9 u9 V; u/ R* l
034EA560   00 3B 00 00 00 3B 00 00 80 BF 00 00 80 BF 00 00  .;...;..
作者: shane007    时间: 2010-4-13 21:28
第一个文件估计是256个32x32点的rawdata点阵字库。
. f7 W5 J: E% _5 d8 c正在想找个能查看的工具。
作者: solidji    时间: 2010-4-23 15:21
标题: 殊途同归
接上,一点点来,先把写屏函数分析完:
: ?; f6 g2 ~. x, @9 R写屏函数:
  1. 02A2EA4C  |> /8B00              |/mov eax,dword ptr ds:[eax]
  2. 02A2EA4E  |. |0FB70450          ||movzx eax,word ptr ds:[eax+edx*2]                         ;  //取出第edx个字符
  3. 02A2EA52  |. |8B7C24 14         ||mov edi,dword ptr ss:[esp+14]
  4. 02A2EA56  |. |8B7F 2C           ||mov edi,dword ptr ds:[edi+2C]                             ;  //003E69F0
  5. 02A2EA59  |. |8D04C0            ||lea eax,dword ptr ds:[eax+eax*8]
  6. 02A2EA5C  |. |8D0487            ||lea eax,dword ptr ds:[edi+eax*4]                          ;  //eax存放的就是字库的地址(实际上是单个字符的坐标)
  7. 02A2EA5F  |. |8B7C24 0C         ||mov edi,dword ptr ss:[esp+C]                              ;  //129CE000
  8. 02A2EA63  |. |8D7C39 14         ||lea edi,dword ptr ds:[ecx+edi+14]
  9. 02A2EA67  |. |D940 04           ||fld dword ptr ds:[eax+4]
  10. 02A2EA6A  |. |83C2 01           ||add edx,1                                                 ;  //多少个需要渲染的字符
  11. 02A2EA6D  |. |D95C24 30         ||fstp dword ptr ss:[esp+30]
  12. 02A2EA71  |. |D900              ||fld dword ptr ds:[eax]
  13. 02A2EA73  |. |D91F              ||fstp dword ptr ds:[edi]
  14. 02A2EA75  |. |D94424 30         ||fld dword ptr ss:[esp+30]
  15. 02A2EA79  |. |D95F 04           ||fstp dword ptr ds:[edi+4]
  16. 02A2EA7C  |. |8B7C24 0C         ||mov edi,dword ptr ss:[esp+C]
  17. 02A2EA80  |. |D940 04           ||fld dword ptr ds:[eax+4]
  18. 02A2EA83  |. |8D7C39 30         ||lea edi,dword ptr ds:[ecx+edi+30]                         ;  // 14 + X,Y + 14 ==30
  19. 02A2EA87  |. |D95C24 30         ||fstp dword ptr ss:[esp+30]
  20. 02A2EA8B  |. |D940 08           ||fld dword ptr ds:[eax+8]
  21. 02A2EA8E  |. |D91F              ||fstp dword ptr ds:[edi]
  22. 02A2EA90  |. |D94424 30         ||fld dword ptr ss:[esp+30]
  23. 02A2EA94  |. |D95F 04           ||fstp dword ptr ds:[edi+4]
  24. 02A2EA97  |. |8B7C24 0C         ||mov edi,dword ptr ss:[esp+C]
  25. 02A2EA9B  |. |D940 0C           ||fld dword ptr ds:[eax+C]
  26. 02A2EA9E  |. |8D7C39 4C         ||lea edi,dword ptr ds:[ecx+edi+4C]
  27. 02A2EAA2  |. |D95C24 30         ||fstp dword ptr ss:[esp+30]
  28. 02A2EAA6  |. |D900              ||fld dword ptr ds:[eax]
  29. 02A2EAA8  |. |D91F              ||fstp dword ptr ds:[edi]
  30. 02A2EAAA  |. |D94424 30         ||fld dword ptr ss:[esp+30]
  31. 02A2EAAE  |. |D95F 04           ||fstp dword ptr ds:[edi+4]
  32. 02A2EAB1  |. |8B7C24 0C         ||mov edi,dword ptr ss:[esp+C]
  33. 02A2EAB5  |. |D940 0C           ||fld dword ptr ds:[eax+C]
  34. 02A2EAB8  |. |8D7C39 68         ||lea edi,dword ptr ds:[ecx+edi+68]
  35. 02A2EABC  |. |D95C24 30         ||fstp dword ptr ss:[esp+30]
  36. 02A2EAC0  |. |83C1 70           ||add ecx,70                                                ;  //每70一个顶点结构
  37. 02A2EAC3  |. |D940 08           ||fld dword ptr ds:[eax+8]
  38. 02A2EAC6  |. |D91F              ||fstp dword ptr ds:[edi]
  39. 02A2EAC8  |. |D94424 30         ||fld dword ptr ss:[esp+30]
  40. 02A2EACC  |. |D95F 04           ||fstp dword ptr ds:[edi+4]
  41. 02A2EACF  |. |8B46 58           ||mov eax,dword ptr ds:[esi+58]
  42. 02A2EAD2  |. |03C3              ||add eax,ebx
  43. 02A2EAD4  |. |3B50 08           ||cmp edx,dword ptr ds:[eax+8]
  44. 02A2EAD7  |.^\\0F8C 6FFFFFFF     |\\jl xcDxShad.02A2EA4C
复制代码

2 p( [4 f5 `4 d6 }5 v# r+ }实际上这里是定义了一个顶点结构,那一串浮点运算就是根据003E69F0处的字符在字库中的坐标信息建来赋值自己定义的顶点结构 * r8 W/ [# {. }( G5 Q/ [
  TLVertex vertices[] = $ D) b3 N1 J8 r
  { " m4 U; q4 N) j0 C3 K
   { 248.6f, 222.2f, 0.5f, 1.0f, 0xffffff00, a, b },
. W/ @9 V/ w: R6 j   { 262.6f, 222.2f, 0.5f, 1.0f, 0xffffff00, c, b }, ; X1 @3 `8 j6 k+ b/ b
   { 248.6f, 240.2f, 0.5f, 1.0f, 0xffffff00, a, d }, $ c6 G3 m/ \4 O4 Z7 T1 v7 w
   { 262.6f, 240.2f, 0.5f, 1.0f, 0xffffff00, c, d } 9 J- ~/ [. ~3 u( A/ J5 W2 V! C+ ]
  }; //129CE000 指向vertices,0xffffff00表示颜色,这里应该是白色
0 u! `' K* [" h+ ]' p3 c- q) {0 E
( M9 O  J9 L4 a3 T: J: [ [a,b,c,d] = {0.02929688, 0.5410156, 0.08398438, 0.6113281}; //003E69F0
9 a9 Y# ~: s( {7 {' i2 U2 a* t, [1 k9 i0 v! H+ ]1 V
PS:“每个字符占1C个字节,最后的四个字节都是一样的,可以认为是结束标志”
! h' H) G) ]/ Q$ h: _* |其实是每个字符占0x70个字节,每个字符有4个顶点信息,你可以把它想像成那个字符的四个角,
4 e* {2 p. ~# t# ?5 v; T* F/ ^每1C个字节就是一个顶点信息,倒数第三个字节表示颜色,他们之间的颜色渐变是由DXD来实现的
/ g  z3 q+ L; W6 k这是一张DDS格式的图片字库
作者: solidji    时间: 2010-4-23 18:54
  1. 00401AC0 . 81C7 0C010000 add edi,10C ; //单个字体文件结构长度
  2. 00401AC6 . 3BD8 cmp ebx,eax
  3. 00401AC8 .^ 72 C9 jb short SL2.00401A93
  4. 00401ACA . 8B7C24 1C mov edi,dword ptr ss:[esp+1C]
  5. 00401ACE > 8B9424 3C110000 mov edx,dword ptr ss:[esp+113C]
  6. 00401AD5 . 33DB xor ebx,ebx
  7. 00401AD7 . 85C0 test eax,eax
  8. 00401AD9 . 76 24 jbe short SL2.00401AFF
  9. 00401ADB . 8B06 mov eax,dword ptr ds:[esi]
  10. 00401ADD . 33C9 xor ecx,ecx
  11. 00401ADF . 90 nop
  12. 00401AE0 > > 899401 08010000 mov dword ptr ds:[ecx+eax+108],edx ; aD3dErrorD3dHea
  13. 00401AE7 . 8B06 mov eax,dword ptr ds:[esi]
  14. 00401AE9 . 039401 04010000 add edx,dword ptr ds:[ecx+eax+104]
  15. 00401AF0 . 83C3 01 add ebx,1
  16. 00401AF3 . 81C1 0C010000 add ecx,10C
  17. 00401AF9 . 3B5C24 14 cmp ebx,dword ptr ss:[esp+14]
  18. 00401AFD .^ 72 E1 jb short <SL2.aD3dErrorD3dHea>
  19. 00401AFF > 8BC5 mov eax,ebp ; //算出文件长度EDX
  20. 00401B01 . 8D50 01 lea edx,dword ptr ds:[eax+1]
  21. 00401B04 > 8A08 mov cl,byte ptr ds:[eax]
  22. 00401B06 . 83C0 01 add eax,1
  23. 00401B09 . 84C9 test cl,cl
  24. 00401B0B .^ 75 F7 jnz short SL2.00401B04
  25. 00401B0D . 2BC2 sub eax,edx
  26. 00401B0F . 8D3428 lea esi,dword ptr ds:[eax+ebp] ; //算出文件名长度EAX
复制代码
3 Q4 r% ?3 {8 B, W
6 v. t3 l. x8 z& s6 J6 q$ i" z. G
这一段解压代码拦不到,不知是不是因为我是DEMO版的原因?
0 c9 D) b" \' t- G2 k' N1008A43F . 66:AD lods word ptr ds:[esi] ; esi:原文件数据缓冲区
作者: shane007    时间: 2010-4-23 19:51
solidji 加油!就看你的了。
6 T; g! ?. g& d1 r! q% |+ K, Z, G7 \2 x
应该和DEMO版没关系吧。
作者: jinxin8866    时间: 2010-4-23 21:36
加油!!!!!一边看一边学习.....................
作者: solidji    时间: 2010-4-25 04:52
拦到了解压的函数
# B9 b( A' B6 c
  1. 1008A1E0   $ /E9 03010000       jmp xcEngine.1008A2E8
  2. 1008A1E5     |8D49 00           lea ecx,dword ptr ds:[ecx]
  3. 1008A1E8   . |46 61 73 74 20 64>ascii "Fast decoding Co"
  4. 1008A1F8   . |64 65 20 66 72 6F>ascii "de from Chris An"
  5. 1008A208   . |64 65 72 73 6F 6E>ascii "derson",0
  6. 1008A20F     |90                nop
  7. 1008A210   . |69 6E 76 61 6C 69>ascii "invalid literal/"
  8. 1008A220   . |6C 65 6E 67 74 68>ascii "length code",0
  9. 1008A22C   . |69 6E 76 61 6C 69>ascii "invalid distance"
  10. 1008A23C   . |20 63 6F 64 65 00>ascii " code",0
  11. 1008A242     |8BFF              mov edi,edi
  12. 1008A244   . |69 6E 76 61 6C 69>ascii "invalid distance"
  13. 1008A254   . |20 74 6F 6F 20 66>ascii " too far back",0
  14. 1008A262     |8BFF              mov edi,edi
复制代码
  1. 1008A2E8   > \\57                push edi
  2. 1008A2E9   .  56                push esi
  3. 1008A2EA   .  55                push ebp
  4. 1008A2EB   .  53                push ebx
  5. 1008A2EC   .  9C                pushfd
  6. 1008A2ED   .  83EC 40           sub esp,40
  7. 1008A2F0   .  FC                cld
  8. 1008A2F1   .  8B7424 58         mov esi,dword ptr ss:[esp+58]
  9. 1008A2F5   .  8B7E 1C           mov edi,dword ptr ds:[esi+1C]
  10. 1008A2F8   .  8B56 04           mov edx,dword ptr ds:[esi+4]
  11. 1008A2FB   .  8B06              mov eax,dword ptr ds:[esi]
  12. 1008A2FD   .  03D0              add edx,eax
  13. 1008A2FF   .  83EA 0B           sub edx,0B
  14. 1008A302   .  894424 2C         mov dword ptr ss:[esp+2C],eax
  15. 1008A306   .  895424 14         mov dword ptr ss:[esp+14],edx
  16. 1008A30A   .  8B6C24 5C         mov ebp,dword ptr ss:[esp+5C]
  17. 1008A30E   .  8B4E 10           mov ecx,dword ptr ds:[esi+10]
  18. 1008A311   .  8B5E 0C           mov ebx,dword ptr ds:[esi+C]
  19. 1008A314   .  2BE9              sub ebp,ecx
  20. 1008A316   .  F7DD              neg ebp
  21. 1008A318   .  03EB              add ebp,ebx
  22. 1008A31A   .  81E9 01010000     sub ecx,101
  23. 1008A320   .  03CB              add ecx,ebx
  24. 1008A322   .  895C24 3C         mov dword ptr ss:[esp+3C],ebx
  25. 1008A326   .  896C24 28         mov dword ptr ss:[esp+28],ebp
  26. 1008A32A   .  894C24 10         mov dword ptr ss:[esp+10],ecx
  27. 1008A32E   .  8B47 4C           mov eax,dword ptr ds:[edi+4C]
  28. 1008A331   .  8B4F 50           mov ecx,dword ptr ds:[edi+50]
  29. 1008A334   .  894424 08         mov dword ptr ss:[esp+8],eax
  30. 1008A338   .  894C24 0C         mov dword ptr ss:[esp+C],ecx
  31. 1008A33C   .  B8 01000000       mov eax,1
复制代码
这算法挺长的,我看看把它弄成个DLL导出函数; E) R6 N! N' K( m  M
dump下來的部分字库文件. P  t( c8 K+ c+ O7 \  N- J9 m
[attach]15990[/attach]
; O6 ~+ B) _4 u4 R大概看了下,和jinxin8866取出来的数据很相似" b" {& ^) i& f
拿到这部分解压算法之后,搞清楚解压后数据的结构就可以了吧?
作者: shane007    时间: 2010-4-25 08:22
标题: 楼上字库的抓图
恩,需要以下东西。
' d% e: q7 m; r. e4 H8 O/ l, x5 d2 F% i  h6 S
1.  解压算法 ; W: I5 S4 d( v: k' ?! {
2.  由解压算法推算出magic number为XCPK的文件的结构 / g2 C' Y" ~' X* ]* s
3. 制作解压工具
# ], w: O/ b0 Y$ E& ]' g6 N4. 根据解压算法推算出压缩算法。
3 e" [9 ~; Z; u9 T. ~5. 制作出magic number为XCPK的文件的压缩工具
, h9 A' _- o/ D9 e% S; E1 N: V4 [4 `5 E& H. ?/ T+ n* U
以下是楼上字库的抓图$ j  N( ?/ D* n- ?
[attach]15991[/attach]
作者: jinxin8866    时间: 2010-4-25 20:55
dump2数据结构分析:
' f9 f8 `% @/ E) ?( e( Z' c/ l" J+0  在字库中的X开始坐标
# H& M( |- h- W- w+4  在字库中的Y开始坐标
6 X/ F3 Y" X$ B$ u' q+8  在字库中的X结束坐标/ }- p% u7 \2 M3 K: Z1 I
+C  在字库中的Y结束坐标
( ^' r$ G  P0 J  t+10 浮点数,字宽,向前伸缩
3 l0 [/ I8 n6 f/ [+14 浮点数,字高,负数表示正向,正数表示倒向* O% W0 k7 ]: ~/ f9 q
+18 浮点数,字宽,正数表示正常,负数表示反向( C$ H& _; Y4 d; ?
+1C 浮点数,字高,字符上顶点不动,底下可以伸缩* _8 F% o% e6 j* _, F5 [- `
+20 后间距,包含自身宽度
4 ]  f9 y. j& K, i0 k4 Y* y; k7 b4 L" j6 v, |" y0 X3 Q" P
solidji所说的顶点结构TLVertex vertices就是由此数据结构推算过来的
3 L1 m: [' d( T/ MTLVertex vertices[] =
5 ^. h6 M) E3 i2 M7 j$ `  {
7 J  z/ {! g$ S# R4 g; P5 ^( c   { 248.6f, 222.2f, 0.5f, 1.0f, 0xffffff00, a, b },
, ]2 A) v& H/ u( F4 q1 p+ _* u   { 262.6f, 222.2f, 0.5f, 1.0f, 0xffffff00, c, b }, . d/ ~, }5 g+ v- r3 D  `& r- ?+ @3 o
   { 248.6f, 240.2f, 0.5f, 1.0f, 0xffffff00, a, d }, 1 c, a! z$ `0 r, H0 A
   { 262.6f, 240.2f, 0.5f, 1.0f, 0xffffff00, c, d } # L, B: j6 S- k( \
  }; //129CE000 指向vertices,0xffffff00表示颜色,这里应该是白色
作者: jinxin8866    时间: 2010-4-25 21:04
02A0EA4E  |. |0FB70450    ||movzx eax,word ptr ds:[eax+edx*2]                    ;  [eax+edx*2]存放字符的UNICODE码
  a' g3 \- c8 J$ a0 M$ C3 S% \4 C02A0EA52  |. |8B7C24 14   ||mov edi,dword ptr ss:[esp+14]1 m% ?7 v7 j) W0 X& ?" w
02A0EA56  |. |8B7F 2C     ||mov edi,dword ptr ds:[edi+2C]  ?/ E- A+ c# R0 d9 N+ W! M
02A0EA59  |. |8D04C0      ||lea eax,dword ptr ds:[eax+eax*8]
; _6 L' g$ a/ i% v02A0EA5C  |. |8D0487      ||lea eax,dword ptr ds:[edi+eax*4]   ;  eax:存放字符编码表 即dump2中的数据结构
. r6 X% V1 i) {02A0EA5F  |. |8B7C24 0C   ||mov edi,dword ptr ss:[esp+C]
* `1 ^' y4 W1 r02A0EA63  |. |8D7C39 14   ||lea edi,dword ptr ds:[ecx+edi+14] ;  edi: solidji所说的顶点结构TLVertex vertices  i0 e9 [* r: {6 {) T; _
02A0EA67  |. |D940 04     ||fld dword ptr ds:[eax+4]
作者: shane007    时间: 2010-4-25 21:34
加油,不过楼上还是在分析dump文件。$ z& E' a% W5 e$ \$ p2 H! O
希望尽快进入分析xcpk文件格式的阶段。。。! C; l# [. R8 [9 h
期待中。。。
作者: solidji    时间: 2010-4-26 15:16
标题: decoding
知道那段解压代码无法拦到的原因了,这段解压算法是引擎xcEngine提供的,其中使用了MMX指令 # f" H" H5 |7 {& ]* Z+ v9 r- j
1008A3BE > /833D 00A00F10 02 cmp dword ptr ds:[100FA000],2 ; //存放CPU类型信息,主要看是否支持MMX指令
3 O- d  H7 {5 B0 k9 ^4 L这里判断了CPU对MMX指令的支持程度,最终我的机器使用到的解压循环是
  1. 1008A674   >  0FD3C1            psrlq mm0,mm1
  2. 1008A677   . |83FD 20           cmp ebp,20
  3. 1008A67A   . |77 12             ja short xcEngine.1008A68E
  4. 1008A67C   . |0F6EF5            movd mm6,ebp
  5. 1008A67F   . |0F6E3E            movd mm7,dword ptr ds:[esi]
  6. 1008A682   . |83C6 04           add esi,4
  7. 1008A685   . |0FF3FE            psllq mm7,mm6
  8. 1008A688   . |83C5 20           add ebp,20
  9. 1008A68B   . |0FEBC7            por mm0,mm7
  10. 1008A68E   > |0FDBE0            pand mm4,mm0
  11. 1008A691   . |0F7EE0            movd eax,mm4
  12. 1008A694   . |0F7FDC            movq mm4,mm3
  13. 1008A697   . |8B0483            mov eax,dword ptr ds:[ebx+eax*4]
  14. 1008A69A   > |0FB6CC            movzx ecx,ah
  15. 1008A69D   . |0F6EC9            movd mm1,ecx
  16. 1008A6A0   . |2BE9              sub ebp,ecx
  17. 1008A6A2   . |84C0              test al,al
  18. 1008A6A4   . |75 19             jnz short xcEngine.1008A6BF
  19. 1008A6A6   . |C1E8 10           shr eax,10
  20. 1008A6A9   . |AA                stos byte ptr es:[edi]
  21. 1008A6AA   > |397C24 10         cmp dword ptr ss:[esp+10],edi
  22. 1008A6AE   . |0F86 1C020000     jbe xcEngine.1008A8D0
  23. 1008A6B4   . |397424 14         cmp dword ptr ss:[esp+14],esi
  24. 1008A6B8   .^\\77 BA             ja short xcEngine.1008A674
复制代码
2 e- u2 y0 N4 Z: x  ^

' _' P  m1 j( }- g; O" }+ ~" \& b* d: u3 K- l
str[] = {pbuffIn, lenIn, unknow, pbuffOut, lenOut, unknow1, NULL, str1};
4 [* Y5 a$ c) _. Nbool decoding(&str) ;//解压函数,这个接口我会通过DLL导出函数提供
# e* `; B( D" W& P' ?/ \( m- c; s* _; `. r2 ^8 K5 `0 T* B
1.  解压算法 -----------decoding - g( ?/ g4 U. _! B7 Y
2.  由解压算法推算出magic number为XCPK的文件的结构-------------那么现在我开始看这部分,相对简单 ( j* d$ Z4 F4 U. J1 P4 X
3. 制作解压工具--------decoding封装下 / n7 t% F5 N4 J$ h) ?# K
4. 根据解压算法推算出压缩算法。---------就是上面这段代码了,要花时间,建议先HOOK加载跳过这部分工作,以后在补 " a! s* `0 D; y
5. 制作出magic number为XCPK的文件的压缩工具----------同上
作者: shane007    时间: 2010-4-26 17:11
收到,感觉进入冲刺阶段了,加油!
作者: jinxin8866    时间: 2010-4-26 21:26
引用第8楼shane007于2010-04-01 11:17发表的  :
  Z. i% `, \: S) A3 |, }6 z& I只要知道游戏读取字符图片以后,以何种格式,放到哪个内存地址
& b7 x* Q( h! x* e2 q" @9 K即使我们无法解压字库,也可以通过内挂一个DLL,传入字符编码,把我们自己的字符图片写入对应的内存地址。。从而达到汉化的目的。
0 w9 M# O/ g1 @! U" c' |
现在我们已经分析出了字库文件解压后的三种文件格式,我觉得没必要再分析XCPK文件,把我们自己的字符图片写入以下结构对应的内存地址6 N0 v$ \$ z! g3 l3 D. C
可以了- P  P9 K) |& C7 U- w

. {3 R; P5 L4 i8 W" I3 I* F& `8 Tstr[] = {pbuffIn, lenIn, unknow, pbuffOut, lenOut, unknow1, NULL, str1};
9 U* X* K' H% ^" M3 J2 X# Zbool decoding(&str) ;//解压函数,
作者: shane007    时间: 2010-4-26 22:03
引用第29楼jinxin8866于2010-04-26 21:26发表的 : : b9 C5 F3 L; l& g2 a

/ u8 t) L, A4 v% q现在我们已经分析出了字库文件解压后的三种文件格式,我觉得没必要再分析XCPK文件,把我们自己的字符图片写入以下结构对应的内存地址
8 X; N5 \1 A& o. H* O+ p可以了 : g3 Q/ _/ ]1 T& H9 t, |  g

+ l+ I, O2 z' ~- g' z$ istr[] = {pbuffIn, lenIn, unknow, pbuffOut, lenOut, unknow1, NULL, str1};
3 P% j  y5 l  @' z; B.......
$ f4 c. P/ P: N3 T% X

% f5 O5 ]/ R: l理论上说的确是可以,不过这个些编程对我来说还有些难。
0 u# S4 K6 K: `% @3 V0 hjinxin8866会不会做个内挂DLL来实现这些功能?
% g* `. J; V9 e) q9 H
  |# q% B0 E* C& v我能做的是等xcpk格式分析出来后,在外部对xcpk文件作修改。
作者: solidji    时间: 2010-4-27 00:36
XCPK的格式我也大概看了下,结构并不复杂,就是分支跳转多一点' {" K5 c) v' S+ k& o
我在找更简洁些的解压接口,应该是有的2 k, ]& \/ n4 `
) x; U# K! N! e6 P% r* ]2 v
我们可以把XPCK的明文全部DUMP出来,你修改好之后,挂个DLL写回去, z2 _/ ~% I/ V( Z0 e4 \
这个不难
: l8 R. x- p- e$ x' N分析道这种程度,理论上来说SL2的汉化确定是可以了4 y# c' M5 w* f8 f+ i* f
剩下一些程序上的细节,明天继续。。
作者: shane007    时间: 2010-4-27 08:00
加油!
; C. o+ |1 ~/ v3 k8 H/ j+ y7 l
$ ]. r  Q' V/ n如果在exe加内挂的话,最好在正式版的exe上做。# v( j. R4 m+ t# L
能否在xcengine.dll里面加内挂呢?& n! t# t4 i1 A# I
$ l% e7 N* e1 B: {, A7 i% O
xcengine.dll----->proxy.dll.decoding()--->decode.decoding()
作者: solidji    时间: 2010-4-28 18:31
标题: rererererer
[attach]16021[/attach]
: C# {0 P6 v  y8 R) K4 ?xcengine.dll----->proxy.dll、 % o5 [, S" p0 L) L4 p+ n
为xcengine.dll做代理是很难实现的,没有开放接口的开发库,最多模仿个类指针来调用一下 8 K. G" \& d! K% C4 n5 j, ~
关键又是由类似COM接口的对象注册方式,整个解压流程都是以对象方法来调用的
# d& B8 N- b, n/ n
7 L, D6 e( w5 I5 Z! ]& y" t! K注释的那两个就是XcFileZip和XcBitmap对象
  1. 10020316  |.  8B7C24 18         mov edi,dword ptr ss:[esp+18]
  2. 1002031A  |>  8B4E 10           mov ecx,dword ptr ds:[esi+10]
  3. 1002031D  |.  8B01              mov eax,dword ptr ds:[ecx]
  4. 1002031F  |.  8B40 34           mov eax,dword ptr ds:[eax+34]
  5. 10020322  |.  6A 04             push 4
  6. 10020324  |.  8D5424 1C         lea edx,dword ptr ss:[esp+1C]
  7. 10020328  |.  52                push edx                                                        ;  //前面比较过是否XCPK头
  8. 10020329  |.  FFD0              call eax                                                        ;  // ::Read
  9. 1002032B  |.  85C0              test eax,eax                                                    ;  //根据长度与名字Yellowjacket 18读取完整的xpck文件
  10. 1002032D  |.^ 0F85 55FFFFFF     jnz xcEngine.10020288                     ;  //本次是读取39B3,到88 A9 4E 03,在往下正好是下个XCPK头
复制代码
3 @  F  K8 W% c
上面方法本身类结构
  1. 003EDF50  BC 8E 0A 10 00 00 00 00 03 00 03 00 01 00 00 00  紟..........
  2. 003EDF60  00 00 00 00 04 00 00 00 90 B0 12 00 01 00 00 00  .......惏....
  3. 003EDF70  88 A9 4E 03 00 00 01 00 B3 39 00 00 D0 54 4E 03  埄N...?..蠺N
复制代码

9 \" p& _, w+ K# N4 W88 A9 4E 03 指向从Sl2fnt.dat读进来并XOR之后的内容,B3 39 00 00 本次读取长度,D0 54 4E 03 指向返回类
, }) C& m- a/ _) X* h' e& e6 i. ~9 Q
返回类指针指向结构
  1. 034E54D0  9D A9 4E 03 9E 39 00 00 15 00 00 00 4C B0 12 00  潻N?.....L?.
  2. 034E54E0  00 00 00 00 08 00 00 00 00 00 00 00 D8 82 4E 03  ...........貍N
  3. 034E54F0  00 6E 07 10 20 6E 07 10 00 00 00 00 05 00 00 00  .n n.......
复制代码

% x' T! l5 [( P% ^# l9D A9 4E 03 表示目前未读的缓冲区指针,9E 39 00 00为剩下长度,15 00 00 00 表示已经解压长度,4C B0 12 00  解压缓冲区尾指针
" f* Q; v" b4 s1 |4 z4 {# M+ L3 ^+ J
4 w: |0 R2 }4 L+ c这里可以看到读取地址根据之前的GMGB文件来获取
  1. 02220C98  B7 39 00 00 CF 7A 40 00 2F 45 58 54 44 41 54 41  ?..蟴@./EXTDATA
  2. 02220CA8  53 46 4F 4E 54 2F 59 45 4C 4C 4F 57 4A 41 43 4B  SFONT/YELLOWJACK
  3. 02220CB8  45 54 20 31 38 2E 46 52 00 00 00 00 00 00 00 00  ET 18.FR........
  4. 0012ADF8    00501684  /CALL 到 SetFilePointer 来自 SL2.0050167E
  5. 0012ADFC    00000690  |hFile = 00000690 (window)
  6. 0012AE00    00407ACF  |OffsetLo = 407ACF (4225743.)
  7. 0012AE04    0012AE18  |pOffsetHi = 0012AE18
  8. 0012AE08    00000000  \\Origin = FILE_BEGIN
复制代码

- a/ ]  N3 d0 P0 U4 a1 o; T* U. D
. b2 Z* q1 T( o2 T! y# d接下来看看XCPK文件解压前的结构
  1. 10020431  |> /8B4E 10           /mov ecx,dword ptr ds:[esi+10]
  2. 10020434  |. |8B11              |mov edx,dword ptr ds:[ecx]
  3. 10020436  |. |8B52 34           |mov edx,dword ptr ds:[edx+34]
  4. 10020439  |. |6A 08             |push 8
  5. 1002043B  |. |8D4424 2C         |lea eax,dword ptr ss:[esp+2C]
  6. 1002043F  |. |50                |push eax
  7. 10020440  |. |FFD2              |call edx                                                       ;  XCTGX
  8. 10020442  |. |85C0              |test eax,eax
  9. 10020444  |.^|0F85 3EFEFFFF     |jnz xcEngine.10020288
  10. 1002044A  |. |817C24 28 5843544>|cmp dword ptr ss:[esp+28],47544358
  11. 10020452  |. |0F85 81010000     |jnz xcEngine.100205D9
  12. 10020458  |. |8B46 10           |mov eax,dword ptr ds:[esi+10]
  13. 1002045B  |. |8B4C24 2C         |mov ecx,dword ptr ss:[esp+2C]
  14. 1002045F  |. |8B40 14           |mov eax,dword ptr ds:[eax+14]
  15. 10020462  |. |03C1              |add eax,ecx
  16. 10020464  |. |894424 24         |mov dword ptr ss:[esp+24],eax
  17. 10020468  |. |894C24 1C         |mov dword ptr ss:[esp+1C],ecx
  18. 1002046C  |> |8B4E 10           |/mov ecx,dword ptr ds:[esi+10]
  19. 1002046F  |. |8B11              ||mov edx,dword ptr ds:[ecx]
  20. 10020471  |. |8B52 34           ||mov edx,dword ptr ds:[edx+34]
  21. 10020474  |. |6A 08             ||push 8
  22. 10020476  |. |8D4424 34         ||lea eax,dword ptr ss:[esp+34]
  23. 1002047A  |. |50                ||push eax
  24. 1002047B  |. |FFD2              ||call edx                                                      ;  //Read 依次读取标记字符(bits,name,flag,wdth,hgth,fmt ...)
  25. 1002047D  |. |85C0              ||test eax,eax
  26. 1002047F  |.^|0F85 03FEFFFF     ||jnz xcEngine.10020288
  27. 10020485  |. |8B46 10           ||mov eax,dword ptr ds:[esi+10]
  28. 10020488  |. |8B0B              ||mov ecx,dword ptr ds:[ebx]
  29. 1002048A  |. |8B5424 18         ||mov edx,dword ptr ss:[esp+18]
  30. 1002048E  |. |8B78 14           ||mov edi,dword ptr ds:[eax+14]
  31. 10020491  |. |8B0C0A            ||mov ecx,dword ptr ds:[edx+ecx]
  32. 10020494  |. |8B01              ||mov eax,dword ptr ds:[ecx]
  33. 10020496  |. |8B40 08           ||mov eax,dword ptr ds:[eax+8]
  34. 10020499  |. |037C24 34         ||add edi,dword ptr ss:[esp+34]
  35. 1002049D  |. |56                ||push esi
  36. 1002049E  |. |8D5424 34         ||lea edx,dword ptr ss:[esp+34]
  37. 100204A2  |. |52                ||push edx
  38. 100204A3  |. |FFD0              ||call eax                                                      ;  // LoadChunk 根据标记字符读取一个块并解压
  39. 100204A5  |. |8B4E 10           ||mov ecx,dword ptr ds:[esi+10]
  40. 100204A8  |. |8B11              ||mov edx,dword ptr ds:[ecx]
  41. 100204AA  |. |8B42 3C           ||mov eax,dword ptr ds:[edx+3C]
  42. 100204AD  |. |6A 00             ||push 0
  43. 100204AF  |. |57                ||push edi
  44. 100204B0  |. |FFD0              ||call eax
  45. 100204B2  |. |8B46 34           ||mov eax,dword ptr ds:[esi+34]
  46. 100204B5  |. |B9 F8FFFFFF       ||mov ecx,-8
  47. 100204BA  |. |2B4C24 34         ||sub ecx,dword ptr ss:[esp+34]
  48. 100204BE  |. |014C24 2C         ||add dword ptr ss:[esp+2C],ecx
  49. 100204C2  |. |85C0              ||test eax,eax
  50. 100204C4  |. |74 49             ||je short xcEngine.1002050F
  51. 100204C6  |. |DB4424 14         ||fild dword ptr ss:[esp+14]
  52. 100204CA  |. |8B4C24 2C         ||mov ecx,dword ptr ss:[esp+2C]
  53. 100204CE  |. |85C9              ||test ecx,ecx
  54. 100204D0  |. |8B56 38           ||mov edx,dword ptr ds:[esi+38]
  55. 100204D3  |. |DC05 A0570B10     ||fadd qword ptr ds:[100B57A0]
  56. 100204D9  |. |52                ||push edx
  57. 100204DA  |. |DB4424 30         ||fild dword ptr ss:[esp+30]
  58. 100204DE  |. |7D 06             ||jge short xcEngine.100204E6
  59. 100204E0  |. |D805 38580B10     ||fadd dword ptr ds:[100B5838]
  60. 100204E6  |> |DA7424 20         ||fidiv dword ptr ss:[esp+20]
  61. 100204EA  |. |51                ||push ecx
  62. 100204EB  |. |DEE9              ||fsubp st(1),st
  63. 100204ED  |. |DC0D 20590B10     ||fmul qword ptr ds:[100B5920]
  64. 100204F3  |. |DA7424 18         ||fidiv dword ptr ss:[esp+18]
  65. 100204F7  |. |D95C24 28         ||fstp dword ptr ss:[esp+28]
  66. 100204FB  |. |D94424 28         ||fld dword ptr ss:[esp+28]
  67. 100204FF  |. |D91C24            ||fstp dword ptr ss:[esp]
  68. 10020502  |. |FFD0              ||call eax
  69. 10020504  |. |83C4 08           ||add esp,8
  70. 10020507  |. |85C0              ||test eax,eax
  71. 10020509  |.^|0F85 92FDFFFF     ||jnz xcEngine.100202A1
  72. 1002050F  |> |837C24 2C 00      ||cmp dword ptr ss:[esp+2C],0
  73. 10020514  |.^|0F87 52FFFFFF     |\\ja xcEngine.1002046C
复制代码

" L3 m0 D1 E! H3 c* w, ~1 i2 S9 ^, O: l
"XCPK" "bits" len <bits内容,也就是之前dump下来的字库块> "name" len <文件名Yellowjacket 18.en > "flag" <字库的像素度,长宽等信息>........."XCPK"(下一个XCPK文件头)
: W1 B% i2 I) ]% K' Y3 \- v( L7 v
先Read到字符串"bits",然后把"bits"作为参数LoadChunk 实际内容,然后一直循环到结尾
作者: solidji    时间: 2010-4-28 18:57
说得比较混乱,不过相关代码和结构都提了下,自己跟一下应该就清楚了3 \: J0 x# ^& U3 O( a" L8 Q
总结XCPK文件就是; \1 U9 \* m3 z
xcpk bits bitslen (一段bits具体内容) name namelen (文件名Yellowjacket 18.en)....
  [( I4 W3 \* [" i: H9 @3 L这样一直到结尾遇到下个xcpk 字符9 m6 R& y! L3 r7 Y
分析差不多就这样了,代码怎么写,怎么来打这个钩子有空QQ上讨论分工下吧
! }" \  b9 F0 ^, J& t& k我最近都没太多时间coding
作者: shane007    时间: 2010-4-28 19:11
收到,我先仔细看一下。
作者: shane007    时间: 2010-4-28 19:20
我想先提个问题。4 j% p1 C1 ~0 K& I
游戏里可能有不少XCPK格式的图片,不仅仅是图片字库。" ]; r: j' N4 k9 X
我们把内挂打上去以后,如何来替换呢?# e, T+ T2 V" ~" Z
如何判断哪个图片是哪个呢?
作者: canmover    时间: 2010-5-10 17:55
jinxin8866,你是怎么把图片从内存Dump出的?
作者: solidji    时间: 2010-5-17 14:57
标题: rerererere
解压部分最后的程序看来没人接上,看我有没有时间补完吧 3 O" m" [* M" R  V

5 T! [# L6 ]* ~7 e2 w! v另外我一直研究的通用代理D3D的汉化方式,有了关键性的突破,已经能完整在自己的设备窗口重现游戏字幕了
8 b& f& T2 z* C7 H; o4 n, u% w如图 / B3 e/ q/ _; |) o4 w
[attach]16180[/attach]
: i- y1 u2 Q( G( k) [8 f- b4 ]) o[attach]16181[/attach]5 Y/ }6 |) {/ N& `

7 ^6 {2 c) O4 A5 I* rSL2也是可以用这种方式搞定的,剩下的是将文字数据做MD5与中文数据映射
7 R- m' Q" I, K# `5 G# J" w- a  @最终易用性和性能上如何优化还待定,欢迎各位汉化前辈多给建议
作者: shane007    时间: 2010-5-17 17:08
看到楼上有了关键性的突破真是非常高兴,期待早日放出相关的程序和工具,早日开工。
作者: shane007    时间: 2010-5-17 17:09
对了,做MD5会不会比较费时间?
作者: solidji    时间: 2010-5-21 18:54
MD5很快的,% u0 c: |; ]3 X4 M: x
如果不追求通用的话,也可以按他原来的顶点格式写回去,然后自己调整颜色,字体。
2 G# _1 q, G: y; ^# C9 [7 l# N花了点时间从火炬上移植过来了: h( q1 G6 O( i
看是做SCR还是写回去吧
5 ?% Z% u: p) O' x7 J: x [attach]16228[/attach]
作者: shane007    时间: 2010-5-21 20:40
太好了,估计就差md5和原文译文转换部分了吧?
+ m  G5 q' z( [3 `- h$ C! ?等你进一步的好消息。
作者: solidji    时间: 2010-5-27 11:22
标题: rererere
初步设计好了,大概分三个部分! B( t$ w* {# f9 Y( G' t4 \
1是提取原始纹理数据流,根据MD5做成map,如果有译文则替换,无译文则保存
$ h- v5 ~5 P4 x8 H8 C( B5 ]2是将保存下来的数据流显示成画面以供查看
" l: ~2 p3 E; g4 S* r3是根据译文生成替换数据流6 G* Z( c* j3 Y4 @" b  j" |2 l
这是第二部分的一个示例0 t! E9 J4 m& b* G7 y0 n6 \, q
[attach]16286[/attach] / W: ^7 G% w+ ^+ v, U% w
现在主要是第三部分的代码,我得去找个自己的中文字库先
% \/ V2 J* y1 ]8 P0 k3 p暂时先不考虑支持自己调整颜色,字体特效这些功能了
作者: shane007    时间: 2010-5-27 19:00
好啊,终于看见一点实际的东西了。
1 D' m/ i, T2 X; k7 o3 q' L5 D, [+ C8 {# Y
这个演示程序是把预先生成好的替换数据流显示出来,是吧?) f, P( b* i( V7 I9 ]
这样说的话,要预先把所有的字幕都预先生成替换数据流吧?
作者: solidji    时间: 2010-5-27 20:47
恩,这个是将保存下来的原始英文字符串,由数据流转成可视画面,完善下界面就可以在后面人工输入替换的中文文本,( F" D9 J$ b; y2 u" c

9 l& t1 d& {, v% I! {$ ~第三部分才是将人工输入的中文文本,逆过来转变成数据流
$ C! F. e! a% `" |+ I然后由第一部分读取后替换,这样看到的就是自己填入的东西了
作者: shane007    时间: 2010-5-27 23:40
引用第45楼solidji于2010-05-27 20:47发表的 :
' R9 i! l% ]% }# h0 Y% j恩,这个是将保存下来的原始英文字符串,由数据流转成可视画面,完善下界面就可以在后面人工输入替换的中文文本, & z) x$ X* o! ?" N' W* O

# A1 T" X" j7 e第三部分才是将人工输入的中文文本,逆过来转变成数据流 * T( n  a- a! ]$ N$ N7 G4 F
然后由第一部分读取后替换,这样看到的就是自己填入的东西了
0 S; ^1 _% Z+ t% ~
6 `' K( n" w* Q/ x/ V
收到,加油!期待进一步的进展。# ~9 b: r" m9 j7 N
不知道第1步具体是如何做的,目前是只能针对sl2无法通用的吧?
作者: 哲学人生    时间: 2011-11-5 13:48
何日出汉化,把酒问青天
作者: shane007    时间: 2020-11-30 08:34
顶上来
作者: shane007    时间: 2021-1-31 13:41
顶上来




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