本帖最后由 shane007 于 2023-8-26 14:47 编辑 G2 Y1 Y5 w& \6 I
; e1 \; `. ]1 f
这个有的在上一波(第4波)中进行了比较深入的分析。
9 R# x' l6 q$ v% g8 z- W: ]5 d6 E本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。- q( {2 h8 b2 ]; d- ^
5 u8 {8 j- w* X" F, o9 K* x& J《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll0 M, ~9 I& R; S1 i3 u
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
8 A. y5 ~6 f: M a! r5 @9 U
; Q. y) ^6 ~* i' V4 L. f- A k《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
( i, K+ u! o, L3 K6 h8 M6 W" M2 V! ?, J8 E3 e8 E1 F
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
9 f- b4 R& R, l, |% _& I$ p6 I从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
- J! S. f3 p7 q: r这函数传入一个text_object,里边也许会有颜色和坐标。7 L; A( x2 v8 @) _* d& Y: |
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
0 s( T# O5 b) z5 I - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码 ) s9 Y( d }$ W& C
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,: w: T2 ^( W' z& S8 C' @# X
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
( T, ~* _3 |( |- L e' A
4 g7 ~) W1 r" s1 D5 m
1 M2 B6 o9 G- y' z6 T以下是修改过变量名的代码。
' {2 c0 K4 @) J( _9 w+ c+ c! g+ B- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag). I6 X/ Z6 [9 G9 g0 O W
- {1 Z* u/ Z6 s- C# Q& `/ t7 i
- _DWORD *text_object; // esi
" e! I0 Y+ l+ z) L0 d& y4 a - int offset; // ebx0 M* |1 e: U n& u8 ~2 |8 S; B) G9 }
- int counter; // edi, Q' o0 B9 J, I/ g* I
- _DWORD *str; // eax
- o: B9 e8 n& P% Q- q- ? - unsigned __int16 *char_unicode; // ebp# h, M9 w( {" K, w- g1 f- N
- int v9; // edx
, G4 R) _9 s2 K - # z; Q! C6 I8 q3 I6 Q+ o- ^( T
- text_object = this;
1 L3 b( G4 L+ ^) _/ d - offset = 32 * length;- ?/ P/ @- F6 A, d
- counter = 0; a1 L: q7 o! a
- *(_DWORD *)(32 * length + this[21] + 8) = 0;
" s1 N; H% Y: r% D% J! B _' R - xctArray<unsigned short>::add(*a3, a3[2]);5 g4 ?* k z5 M& i( ]- f. `
- if ( !show_subtitle_flag )4 M, x* v3 V8 n( A* S8 D7 {
- {
, Q) k! z: @0 j' E. o; c0 O0 u9 U7 r, y - str = (_DWORD *)(offset + text_object[21]);
0 Q+ l5 |- S8 g5 S3 D - if ( str[2] > 0 )
# n6 u" |* b; [ - {
7 ?$ s* ^/ Q! O% [7 M - do
- J# B( r' i5 @+ a - {; r6 P8 M# I# j9 b
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);) S: c# i) k* |) E! C7 B( o
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
1 |. P l; S' w% p( ?& c - ++counter;
7 k. I5 p2 b7 M& a( t5 K# k# h - str = (_DWORD *)(offset + text_object[21]);
5 ]) \( W% w* C% ` - }# V+ F& Z. a8 Y+ i2 Z# D+ V1 K
- while ( counter < str[2] );1 V' I9 a3 H& e; H4 n( ?/ A7 o
- }
6 Z2 I/ i9 w' d - }
. Z2 s) V0 _! X( d, A H - v9 = text_object[21];; J' U" X5 {2 g" i! I/ {
- *(_DWORD *)(offset + v9 + 28) |= 4u;* u( C$ t3 E$ m; `) K) p3 i f
- return offset + v9 + 28;
1 {! G% w/ g, I, T9 t* v& p - }
复制代码
& M0 t+ x) C0 K4 @1 F0 [xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
- R" i1 l) }/ o' v2 q- h = CreateFontA(9 D0 ~! M) L0 _& I) E. l3 D# z
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)7 b# {3 G$ z/ J h+ W) {
- 0, // 字体宽度(0 表示由系统选择合适的宽度)3 v1 w; l p5 e2 N
- 0, // 文本输出方向角度1 K3 B; y3 c Y( k4 L
- 0, // 字体基线方向角度
1 D) L2 F+ ?9 n- M& | - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
# @4 @/ C+ G @/ B" r0 \ - *((_DWORD *)a1 + 4), // 是否斜体
- K7 j: @% [ v& `! k - *((_DWORD *)a1 + 5), // 是否下划线3 S9 G2 u- t/ K/ v3 o/ ^
- *((_DWORD *)a1 + 6), // 是否删除线 ^+ Y- ?: |& |. X3 Q
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET): i7 u) X' z* i. ~% ^6 W
- 6u, // 输出精度(OUT_DEFAULT_PRECIS); X# Z5 m5 I/ z& |4 _3 A' [5 Z
- 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS); ^ x8 r8 V# [) o1 B
- 4u, // 字体质量(DEFAULT_QUALITY)
' B! F+ d! C- j6 G/ H - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)7 C; j0 ~5 ~' a: k0 m, V% n% |
- *(LPCSTR *)a1); // 字体名称
复制代码 & a3 C d! U4 Q3 j
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
$ d+ G0 `- R6 z% u0 N' K. e& j0 r
% [% m/ l; s* e- # Time of Day Thread Module API Return Value Error Duration
5 D$ [" V9 o3 k0 @1 c3 V* A - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
$ A* s" q# Q& e {$ l - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
6 t+ V% K5 l4 o/ @) Z* o
复制代码
, g% F! n# E0 B$ M. z0 ^# h; f5 q
0 B/ |6 M C. M1 f. ~! G$ L7 a) h# b+ N0 D5 e
( X1 L) W6 S3 }. u# g. U! x& U- M2 s. [/ [ W' c
" u9 p5 k! o7 H( x7 `+ a
- j9 l+ K# k6 h Y: N% ] |