本帖最后由 shane007 于 2023-8-26 14:47 编辑 - z8 d: v# L- U1 U
4 g. f& _4 A5 e9 W" k% w) {# }这个有的在上一波(第4波)中进行了比较深入的分析。
3 }: d% {+ e/ s! |8 }3 n1 o本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
' I( q# ^5 `( \* }- _' z/ v- F5 i# k! e- k. J0 [# z
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll$ Z: B& X: L) T
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
0 O G$ W0 `' |2 U) n+ D$ E* I" Q- t g8 F* [3 M/ }/ v4 A# h/ E
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
: g; R$ q6 [1 R0 {1 ] ~* i: V( c+ W
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
5 K: d. A" ^' r! R. U. l从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
+ O* n% ~1 @: |9 n% L0 y4 x( ^这函数传入一个text_object,里边也许会有颜色和坐标。; @& x; ^: i T, _0 Z
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);5 @. r V" u) i0 J+ F+ p: n
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
. i5 p/ ~. [) H, ` Q此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,8 e6 @: t/ O' F2 g) m% a' T
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
% h0 v [2 D+ J3 {: ^1 F8 v: }
( U# J! _9 a9 {& C* a0 _ `( p
以下是修改过变量名的代码。
6 S/ u+ D" j ?9 u3 Q r1 ]% Z- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
" \7 W% |2 V2 {* x- P' U+ }0 v( }2 ~ - {) r- w2 J" f- b! l
- _DWORD *text_object; // esi
' T9 q% N- f9 u1 ] - int offset; // ebx0 G. H; m, B5 b7 L8 c( H4 _
- int counter; // edi0 n) n" q8 z( i! s- x% R2 {
- _DWORD *str; // eax
" u9 [+ v0 r! m; ^9 B/ I1 Y, X - unsigned __int16 *char_unicode; // ebp' I, f* {, E6 p0 C
- int v9; // edx
; ^' u5 T6 {, ?7 ^6 Z
$ f4 ]+ x7 I# \* v8 |- text_object = this;
0 j! l' \ B0 d" B1 p% `5 F/ s7 h1 Y - offset = 32 * length;! R# i4 v2 T& S: c4 V1 G
- counter = 0;: G8 g: z) I$ l
- *(_DWORD *)(32 * length + this[21] + 8) = 0;" c1 z0 W5 X2 ]2 \2 p V
- xctArray<unsigned short>::add(*a3, a3[2]);5 p- Q, C7 Z* {
- if ( !show_subtitle_flag )
" r* p5 f6 |3 C: W. p! d - {' e$ ^4 Y) Z8 w# w! |
- str = (_DWORD *)(offset + text_object[21]);" R( T: N# x' d! U# B
- if ( str[2] > 0 )# o4 l* \9 E* o) ~! U4 M
- {
7 j% T5 ]5 S" [. G - do$ ?5 V2 k1 @; N, @& P3 @1 @
- {
2 W0 `3 \$ j7 ?8 h5 v - char_unicode = (unsigned __int16 *)(*str + 2 * counter);$ G8 _! `0 V6 E5 k, W9 k& A9 l5 f
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
, p L# r% g3 T - ++counter;" a+ F- G- v% a9 d3 j: j1 k$ |
- str = (_DWORD *)(offset + text_object[21]);
' x6 K% @2 [& ]4 W% k' `4 a# ^ - }
: G; ~$ t- f, H2 P - while ( counter < str[2] );
* X5 k2 Z# d U" C8 A, U h# @6 o - } _# M @" @8 {2 [" S! e
- }9 `7 x2 W; q ?! M' I
- v9 = text_object[21];! _6 x& d7 G, z# \
- *(_DWORD *)(offset + v9 + 28) |= 4u;) [& ~0 ]4 J, |) R/ a# p& _
- return offset + v9 + 28;: F6 c A6 l* L
- }
复制代码
5 J% Z! a% K# d' P& i8 X! v7 ^xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。& I+ |+ y! C& n( g6 R1 p
- h = CreateFontA($ i2 s( W; i9 k" L
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
" K, S/ V, d& o, M$ a) q3 G. ~1 w - 0, // 字体宽度(0 表示由系统选择合适的宽度)
# A( v. B* z2 D" o: @' m# A - 0, // 文本输出方向角度
/ z2 o4 @# U8 N - 0, // 字体基线方向角度' c* j& r" E h g" _, f% n/ v
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)/ l0 P9 P+ u" S" X0 x7 l
- *((_DWORD *)a1 + 4), // 是否斜体
/ K5 N5 M# H; L - *((_DWORD *)a1 + 5), // 是否下划线, a, f# ~3 c( z1 u2 N, w& a' n J
- *((_DWORD *)a1 + 6), // 是否删除线$ ^6 L& K( w6 J" q+ a) n# Q
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
, S, B1 ]0 e6 l; U, f A1 @, E8 ^ - 6u, // 输出精度(OUT_DEFAULT_PRECIS)
* s# L7 E p- Z6 O' n& v& W - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
* z2 {+ `3 \& \% l. P0 j5 ^ - 4u, // 字体质量(DEFAULT_QUALITY)
* C. E' R+ A( `% x3 Y( q$ Z6 f6 P; G - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
6 \6 k$ K u; w5 g$ D" M - *(LPCSTR *)a1); // 字体名称
复制代码 5 W( G# P# w' c. [3 n
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。5 D! ]' X4 t: Z5 N
$ z0 G. i% ]9 J( ^2 S9 c4 C
- # Time of Day Thread Module API Return Value Error Duration
! { P$ @9 e0 Z1 X7 m0 P - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002% ], l& w# W2 F9 s5 @5 V
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
' U1 }, | z/ z
复制代码 / V9 M/ G" S3 o
0 C. R& ~4 U! T, ^; l
6 r! J- n7 r8 z9 V0 L: _) u6 s O/ S a% ^ F) G0 C2 d7 K+ m
0 S# K% y7 @; i1 j: X9 C% ]) P8 e
3 F/ l* t( G- g2 x, C
! W) f! N1 i. m$ \0 G& \
|