本帖最后由 shane007 于 2023-8-26 14:47 编辑
: U3 J, j, q5 r; R0 U" ?5 _% M: N& v" L! A& K6 @
这个有的在上一波(第4波)中进行了比较深入的分析。
8 `: `: m7 N1 \( |本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
) V5 M( y( w t/ N) I6 V- z" _( ?4 H6 I. E4 {! s
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll4 ^" e! @0 r7 l$ X; k: T8 [
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
5 ~3 a& \- F/ z% b& ~) A. {9 E) X7 X6 i0 c/ \- u6 N n& R
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。$ n1 ^( c3 ]$ ~$ d' K' M
5 t7 _$ `$ ^( V. o
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
' X8 k/ q8 H$ C$ j" [4 z B从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。( {3 A I( m; i' _! Q4 Z" i3 K0 ], A
这函数传入一个text_object,里边也许会有颜色和坐标。
0 d2 y4 [! X4 X+ _; O7 ]& Q8 F- M- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
( k1 v9 t2 c) D9 Y - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码 ' l- ^4 m6 H+ E9 X: d- E& Y
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,! R+ c: I4 d- u+ }3 _0 ]9 f A' n( @
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。2 f6 o8 C* p& u( p6 x
" W% n" H X3 n8 Z' d7 b: c
- U+ g1 G! p, d! u以下是修改过变量名的代码。: ^1 S& R. L! s0 s( m% L
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
* [/ q8 q; G' p4 K - {
# p* Y- q7 x6 p( i5 j: m0 N - _DWORD *text_object; // esi5 r6 Z- X" O3 N
- int offset; // ebx. ?) V! P1 h: k6 ~$ n, t
- int counter; // edi3 h: J8 ^0 H7 w+ }
- _DWORD *str; // eax' u S# T N! M
- unsigned __int16 *char_unicode; // ebp5 p5 Y2 ^3 M m/ {3 `! _5 J
- int v9; // edx
4 Y- Z3 x1 Z f# i
2 c+ H1 P0 i' h, U8 [+ [; A- text_object = this;. f9 `! j9 Y0 m1 n5 B
- offset = 32 * length;
3 z2 J2 j3 J5 m/ N - counter = 0;' S8 x7 @5 u; `2 F7 i
- *(_DWORD *)(32 * length + this[21] + 8) = 0;* H2 O0 d5 W6 Q6 K
- xctArray<unsigned short>::add(*a3, a3[2]);, Q' L& H; l; E& Y5 E+ J
- if ( !show_subtitle_flag )
H3 I+ L4 v: @% h4 G% [ - {
* R* G I H2 ]3 J3 C - str = (_DWORD *)(offset + text_object[21]);! _, @( }, O% S% J+ j9 r/ d
- if ( str[2] > 0 )8 u, ~) f! E, j
- {* m" v0 W, ~+ M% A# i* |
- do8 A- W. ?) D+ R( B5 G
- {
5 o5 J! y% }& B7 y; O - char_unicode = (unsigned __int16 *)(*str + 2 * counter);4 X- ]2 @: F: E0 @' _( k4 e j& m
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
% g3 }4 t0 H( Z4 f w) @' l0 ]- P - ++counter; o* H9 e* ]9 O# M, C0 m! P" Z
- str = (_DWORD *)(offset + text_object[21]);
: U0 Y& w4 Q) ^& F; k5 O- Z - }
2 k1 T2 L0 e: Y: m; s3 b' v - while ( counter < str[2] );5 y, \; N3 t4 B) ^" E
- }% w0 H% ?' h) g& J4 y% F& N& P. r7 s
- }1 D8 P% g1 n% u8 X
- v9 = text_object[21];9 C7 ?1 R* j4 @, d/ X+ z
- *(_DWORD *)(offset + v9 + 28) |= 4u;
" v( h) o$ w1 K+ G! S0 Q - return offset + v9 + 28;
- s; }+ L( U9 r: f' Z - }
复制代码
# N+ h5 B/ U) j+ X' {xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。6 k. h; `: B5 N: }" f4 e% [
- h = CreateFontA(
- l( V! V( X, L - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
; F' |# u- o- l) r. X5 q. n - 0, // 字体宽度(0 表示由系统选择合适的宽度)6 P% r* Y* t# g' y) U: ]2 e
- 0, // 文本输出方向角度$ f& z/ Z$ E2 z9 u8 O7 ]0 h+ s
- 0, // 字体基线方向角度 _( O8 r" g. @! |0 p# L$ v. i
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
1 D/ L' E( @! l, j H% ? - *((_DWORD *)a1 + 4), // 是否斜体4 I- K" Z5 O4 y+ r
- *((_DWORD *)a1 + 5), // 是否下划线$ j! D1 N# B7 f3 J% V6 O& a
- *((_DWORD *)a1 + 6), // 是否删除线9 Y# t- |# g; A4 A7 Q
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
9 B; P+ b4 n. O9 X5 m, }3 R - 6u, // 输出精度(OUT_DEFAULT_PRECIS)
. i# T9 t2 p7 H8 x - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
& p; {. E0 u; P* s# k - 4u, // 字体质量(DEFAULT_QUALITY)# `4 F: ^$ s7 r& P+ s6 R+ h
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS), B) p* G5 [/ _( @- S, Q# Q+ {0 c
- *(LPCSTR *)a1); // 字体名称
复制代码 6 O: k i9 b0 D) I. t' V/ n5 N5 x1 @
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
- U8 K/ e$ Q! A9 z v) a$ A! G
% l, c4 F& M {9 ?8 ^: I- # Time of Day Thread Module API Return Value Error Duration. C0 ?( M x/ {5 i. {
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002% E5 x' J/ \: B
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001+ g6 }+ _9 ?6 y( h5 n$ a! X q
复制代码
# i; e6 c% S) B" @1 m
; f. m; C# e1 S5 C# z
0 J4 o8 F9 A5 R- i) S5 z* j: ]( d. [# |( J, q! S8 }
9 h/ l/ T4 D7 c1 r8 t
9 R5 }* F' q& @ G; x1 m. S/ Y) ^; q
|