本帖最后由 shane007 于 2023-8-26 14:47 编辑 ! i5 d* s" D+ `, I' r5 e m
4 O1 t: k% I2 _3 S. ]9 p4 e: K
这个有的在上一波(第4波)中进行了比较深入的分析。
" f/ r9 |+ y/ A% ~$ n/ G& L9 a I! C本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
4 O7 E. B- j( D2 Y3 m t
$ D/ M- y' H; C! \( g《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll% G$ e$ h0 C' U0 p1 [, l
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
7 j) ?( d6 C* x' g% S/ d) n3 {2 R# p' T% h# P8 A8 ]
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。8 V5 z# I" o# o- }/ K3 K: [( p
# c2 z3 E( z- w- d$ k9 A关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
4 H9 i2 T% A! f0 Y' O& W! l从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
) h7 |* ~ u" i1 U$ ^, C9 `这函数传入一个text_object,里边也许会有颜色和坐标。- m9 @$ d N" k! _, R# |
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);+ b6 l7 B7 P1 j# ?1 @
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
6 S3 U! e5 b# W6 ~3 {* Z3 \此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
0 U; l" x+ E$ b, a. i$ l- A! C因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
. q5 O% I% J8 j. V2 R
5 Y7 D+ ]* @3 I5 U) {& G) S$ E- A5 ]. |' S' u6 d5 ?5 V
以下是修改过变量名的代码。
7 ?# T# Y3 h) a+ f6 A- c- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)& w/ H0 E8 V/ S, ]; y
- {2 G9 K8 q: O$ {' b& V. m; _
- _DWORD *text_object; // esi
4 r0 ^9 z i' F - int offset; // ebx
7 m5 f A" x# f6 n - int counter; // edi
# V l; f3 E* q1 ]+ r+ z* K - _DWORD *str; // eax
% p7 |' T h6 I* [ - unsigned __int16 *char_unicode; // ebp
* W5 U! J! e) w4 @1 v, W - int v9; // edx
+ V# X) z, l N& l* A - ; X2 E' o" m3 G9 O# R
- text_object = this;3 _7 I/ c2 B+ A
- offset = 32 * length;
) s ?- ^# l9 X0 o6 U - counter = 0;
; g1 J0 R$ }. a2 F! a - *(_DWORD *)(32 * length + this[21] + 8) = 0;
E# X5 P( [9 l - xctArray<unsigned short>::add(*a3, a3[2]);
1 G$ `0 P1 R4 v: e - if ( !show_subtitle_flag )
" O# { j* b( d' m9 G8 V; i9 P: W - {% Z- k4 W+ {- G* |/ Y
- str = (_DWORD *)(offset + text_object[21]);
. L: F/ m" J7 @* |+ o4 k - if ( str[2] > 0 )' ], o/ r [+ F7 s# K7 F
- {( u+ V9 z7 l) ?
- do6 X$ Z; |' ]. D
- {, k7 A N0 [ _" W+ [
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);; H! b- c z( K6 x, e
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);0 O5 _0 z. K+ o6 ?' E8 x+ a$ _: s
- ++counter;
; Z; F* V" R0 ?) e. M - str = (_DWORD *)(offset + text_object[21]);
( T% G; B: A" E5 Z - }9 u! p( U: j* `% V, a# k
- while ( counter < str[2] );
7 c4 e0 H x3 X9 x% g - }
' P% Y9 n; D; k9 b. b/ S - }% {% T. Z$ V& g
- v9 = text_object[21];/ g( l+ O X3 `! a7 W; ~
- *(_DWORD *)(offset + v9 + 28) |= 4u;
8 }8 A# z' n. e6 h/ i - return offset + v9 + 28;& B; A& {1 F4 T9 m4 k4 c
- }
复制代码
- K ^8 ]8 u( Z: y# S5 g- oxcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
! R6 _+ ~/ D) h6 a. C6 X/ {2 h- h = CreateFontA(
; `/ E/ L1 x3 C - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)& n( C& F1 w3 R8 ^
- 0, // 字体宽度(0 表示由系统选择合适的宽度)
0 S" h# O% s9 j/ b, u5 }0 O - 0, // 文本输出方向角度
, F1 |" a! q& x P# w$ b - 0, // 字体基线方向角度
0 o8 h, R& ~+ h3 }/ e& n2 c - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)8 V" H9 T/ ?! t. ~3 p4 o |: T9 v+ N0 J1 e
- *((_DWORD *)a1 + 4), // 是否斜体
8 ]* |2 _9 B1 Q, Z$ N# ^ - *((_DWORD *)a1 + 5), // 是否下划线0 }' ?7 ]1 T9 |: M) u0 f* ^6 }( w8 I
- *((_DWORD *)a1 + 6), // 是否删除线+ w+ G* @/ b# w$ J
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
4 M7 [+ l7 v1 k - 6u, // 输出精度(OUT_DEFAULT_PRECIS)
$ y" d: ^" H3 \' L; c! T7 q - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
: d3 U& h4 N: ]% u& Q - 4u, // 字体质量(DEFAULT_QUALITY)
! T9 a) Y6 }& ?: S8 M# ~ - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
$ L, [& P P+ ?+ U* s) s7 n - *(LPCSTR *)a1); // 字体名称
复制代码 " d9 G; Y. Q4 Y& Q6 @7 @
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。7 r/ Y: s$ C8 W9 u
5 n5 z0 Q, t! ~% {4 h- # Time of Day Thread Module API Return Value Error Duration
9 P v3 Y5 K9 }, | - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
: Y4 C# P2 L! }& d+ V! J) U$ s/ e - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
~7 ?* X) b" p$ _
复制代码 % S" ^8 i5 R7 i8 J7 F }1 N
2 H- X( ~9 G. h6 S: K) M3 G( _8 L9 b2 Y# Z8 X6 k
3 @. t* i+ O# D0 X6 r8 K$ ` ^3 |3 N8 z( x! f
& Y) U& `4 i! [
+ L) E1 Q9 {- H( H |