本帖最后由 shane007 于 2023-8-26 14:47 编辑
7 f3 e* q; a/ r U0 v" c# c
' j T$ g' [. C" Q8 D/ s这个有的在上一波(第4波)中进行了比较深入的分析。* G9 {8 d/ ~6 C# L$ I! i$ B% Q
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
4 y! J1 h; E/ G: E& g
3 r3 ?# J! p: J' j7 l. v; b/ D6 ?《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll, o( d+ k" `2 k. D1 A) u. ^3 C; J
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。8 h+ S5 ^* Y; |. K* c
0 N& x6 g- p6 h
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。1 n s2 }: g. H: c9 A
2 ^% m. v. E* N- x9 p+ v
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
2 F4 M- @: l U, u! B3 ~0 C( b6 K从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。+ l4 b- |2 r4 p
这函数传入一个text_object,里边也许会有颜色和坐标。1 D& W* M) @* ]" W, r9 C
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);, w/ u8 V w9 [9 T
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码 $ K# E( k' c- x/ M" {
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,4 }. _% b: W3 Y% S* A7 F7 G
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
7 a7 P; o$ |. M: O+ |' W9 F" h) p8 c5 C* k$ @
5 ~: f' i8 y8 Z. d8 a
以下是修改过变量名的代码。2 z4 w: N: \% M
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
8 V) J# I+ s9 n# |3 J* F - {
/ b: Q7 S1 Z, R) O# c5 \2 C4 u - _DWORD *text_object; // esi) u4 f/ K1 D. r2 B1 s/ g
- int offset; // ebx
( n9 {$ T9 j- [) g, E: b @ - int counter; // edi
7 G4 N; x8 O- A5 U4 n - _DWORD *str; // eax
# \# Z7 m& z* {8 y6 N* w8 l- z { - unsigned __int16 *char_unicode; // ebp
. `) N7 G3 m. B3 c. h/ f6 Y - int v9; // edx
4 l, k; I1 i- [% _ - 1 v7 Y$ i& f9 N) D* F( Q
- text_object = this;
; Q' A7 C U& X% Z - offset = 32 * length;
# w& Q6 d/ ?1 K4 t( R* g. K - counter = 0;
/ T% j. h% C$ f+ K1 L U% } - *(_DWORD *)(32 * length + this[21] + 8) = 0;' {' C1 M% e: ?1 E5 {
- xctArray<unsigned short>::add(*a3, a3[2]);. W s# S0 Q% K) {* L+ v
- if ( !show_subtitle_flag )2 e0 a: K7 X, O% c2 N8 O$ I% N3 J% k
- {' U" a5 i. v3 `9 l
- str = (_DWORD *)(offset + text_object[21]);
# u, n1 P# l$ b! N% D - if ( str[2] > 0 )( h" k2 W4 h8 w7 e, z$ H
- {" W1 H1 r; e6 k
- do) ^ B; f: x, i; L1 n% Q+ @
- {6 g! ~7 |7 P) v/ X; X* K2 S# i+ g
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
A7 F: d! D6 o - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
- ^) |+ K& B% W* u2 ]% u - ++counter;
7 k% d7 a# h' S - str = (_DWORD *)(offset + text_object[21]);
H1 `5 t0 q0 ^. W7 n! a - }% D" c8 g6 K1 y8 D. U$ D) v- z
- while ( counter < str[2] );
' B" j- C2 Y( ~1 f* @1 z* m - }' [$ s) N2 h4 F3 m) a
- }* L8 `$ M- i' c, c4 f6 w
- v9 = text_object[21];4 K- F9 t% f* N' ?) f1 }5 c# P
- *(_DWORD *)(offset + v9 + 28) |= 4u;* b7 [% p E7 D! v( p: T
- return offset + v9 + 28;
2 w1 S( D P5 d - }
复制代码 9 J* M# r% d/ X9 X# R
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。7 Y5 v. F) Q& s" w% U. I4 d
- h = CreateFontA(: p% s$ j+ s% B( q# {: j* q2 K
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)( n3 ], m$ l. b& Y- Z5 c7 g/ I Q' S
- 0, // 字体宽度(0 表示由系统选择合适的宽度)3 t7 f. h) F7 b0 q# G7 K- ^8 v
- 0, // 文本输出方向角度7 n- H5 Q8 Y& _* |
- 0, // 字体基线方向角度# L' }; ?8 Z4 K. k+ E& V' |
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)8 y$ E" z% O) _9 o" q) `- q" h9 V
- *((_DWORD *)a1 + 4), // 是否斜体9 o5 |! a6 G$ ~0 V0 U& p
- *((_DWORD *)a1 + 5), // 是否下划线
( r* ~+ O4 I2 m; P% r - *((_DWORD *)a1 + 6), // 是否删除线$ |- _( e9 q: @+ f- _3 W
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)' S9 u: q+ @3 f; L$ b
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)7 |. a' p' q4 r7 t' @% [& X
- 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
# O- F0 H* [9 ]# V+ }1 _* q( R" J - 4u, // 字体质量(DEFAULT_QUALITY)
2 e* |$ V! O. ^$ O& f7 F - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS), k3 @* g V, z; P7 r4 v; V8 N5 S+ @
- *(LPCSTR *)a1); // 字体名称
复制代码
2 ]2 v0 F Q0 `; R/ d用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。1 j2 d* e+ U" U" o& V
" P5 Q. P/ E( I5 V$ s
- # Time of Day Thread Module API Return Value Error Duration' x7 ]7 ?/ S+ u" f+ e8 P
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.00000022 I1 I. t! a7 {
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.00000014 g7 x: m4 i4 K
复制代码 , K3 J- @: ~ U M! b/ Q& j' Z3 D9 F- x
, C$ j1 ~3 j4 L# ]4 O4 |) g1 F" K9 }# ?$ }
* y! r0 I9 n5 i, z, Q" E, y, k
: p* r& V5 I. O6 f0 A6 x% ^% i/ W9 s3 ^' W, a4 Y+ g% P6 m
* q0 J% h5 }- M; Y% O+ t
|