本帖最后由 shane007 于 2023-8-26 14:47 编辑 2 W% ?* ?. X* {+ k. _1 ]
5 G3 g! R8 W6 z. d. T# _这个有的在上一波(第4波)中进行了比较深入的分析。* S! `. e# C1 U+ m0 U O T* F
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
1 W B+ p6 B+ A. ~' _( }" H; s+ @+ G
$ c0 q: M$ |" g, H《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll0 F7 j! X I, A0 `1 E" g
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
) y4 |/ W7 \; l, b& p6 u2 V+ X2 v4 O& i' K( v! s
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
& Z* b' A1 h e c# f/ T, _- C) i5 c- [/ X
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
7 z6 u5 k/ e2 |0 X2 _* g从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
. G7 {+ R# P( U, T3 r* e$ J8 H; p6 ]这函数传入一个text_object,里边也许会有颜色和坐标。
, @: ~3 W1 d0 R5 c6 j" v+ Q3 C- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
% L ^8 k/ G7 I% g - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
% U1 G% i6 H/ h$ W此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
5 e/ R/ ?) M1 w0 X* m7 `) l1 l因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。0 ]0 I1 @) Q( z2 K9 z
7 k! E( i! w- B: h% ]
# B" s7 v7 U2 }4 @4 u" U
以下是修改过变量名的代码。& \: l/ S) G" ?) W) b& A
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)# ?9 A5 k+ Z9 y$ l, \/ [2 H4 y, w; N
- {" U' X, \& o+ b3 C# g) ^, W: o
- _DWORD *text_object; // esi
0 R0 |3 T8 P, [, T L - int offset; // ebx
p' C( X. t! }" z - int counter; // edi9 F: V" B4 W# L$ D& w1 o
- _DWORD *str; // eax
7 n6 H. G& W: m5 N; v - unsigned __int16 *char_unicode; // ebp# S' z9 T& l4 h" p X2 x' N
- int v9; // edx
5 x) `" A {( T I+ _/ i' t
) m" P5 F4 _2 E- text_object = this;/ z! c/ F0 {# A- G9 X
- offset = 32 * length;% o: R& T3 a0 p+ m
- counter = 0;8 A9 [( n4 X/ i7 t/ o7 [
- *(_DWORD *)(32 * length + this[21] + 8) = 0;
: S. G C9 v1 z3 Q# x) z( |( y+ Q - xctArray<unsigned short>::add(*a3, a3[2]);
1 G( b+ l# e5 i' L+ h - if ( !show_subtitle_flag ); V5 _$ c4 M0 s y- _3 N
- {0 p& n9 S8 }2 p+ R; A! Y& o
- str = (_DWORD *)(offset + text_object[21]);+ P# e+ T4 U3 N5 A. ~+ T* F A
- if ( str[2] > 0 )& w$ _+ `9 d4 U
- {. w/ p6 ~" t: L
- do& n* o3 ^ W/ q8 ~/ e: A$ J' Z
- {. f# P3 K8 V; {" F4 [% }& f
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
) ~' x6 y5 p: w* z - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
1 W4 X' u! u8 j7 \; N& u: M5 h - ++counter;
* Y7 W/ I7 c- t# B - str = (_DWORD *)(offset + text_object[21]);
% d5 M3 s5 ^& [3 W6 C5 d7 T0 o - }
4 ]# m: [- J8 y0 J5 j$ q - while ( counter < str[2] );# `) l, v, M0 i* }' o+ c0 i. m* c
- }
/ W! @6 |* H+ D A/ }0 N+ [' W - }
. ^3 b1 b; T1 V% w; S2 ` - v9 = text_object[21];/ F4 F7 L- V2 w/ h/ h
- *(_DWORD *)(offset + v9 + 28) |= 4u;. q- ~( Y7 Y8 i. n# w# C @ q1 c
- return offset + v9 + 28;+ e/ z3 \: \6 [. i
- }
复制代码 1 s" }& J4 U+ F* i
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
, ?% w+ b; ^/ |' M0 l- h = CreateFontA(9 p5 f% R% s* y3 K9 H& o
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)* y: K0 ^& N# s
- 0, // 字体宽度(0 表示由系统选择合适的宽度)3 ?* P7 E$ B/ i) i! m; }; a
- 0, // 文本输出方向角度
1 a- b* L' Q' Q9 A B: v0 u- c - 0, // 字体基线方向角度
% _/ H7 ]9 y8 S8 z - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
8 T. }( {% S1 @6 x0 X& K& D, w1 n3 b - *((_DWORD *)a1 + 4), // 是否斜体3 t" y( Q5 F' i
- *((_DWORD *)a1 + 5), // 是否下划线3 i7 D. y* `) L) T8 G6 a8 ]6 u
- *((_DWORD *)a1 + 6), // 是否删除线6 @# F+ [* ]7 G
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)7 K/ }* q4 | L
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)
/ h! [3 l7 [* Z7 N) e - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)' e* t# d5 R" |+ o, w2 D
- 4u, // 字体质量(DEFAULT_QUALITY)
6 \$ @2 m/ L7 k - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)$ }9 E6 F6 s/ q
- *(LPCSTR *)a1); // 字体名称
复制代码 $ d# M. P6 g! i6 ?! H9 r0 K1 x
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
& \; @) q R( s# G! P
* W+ K0 u) {. Q3 X6 [9 w- # Time of Day Thread Module API Return Value Error Duration9 E* L }9 K" r# S. q) w
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002" n6 X! L2 u4 e1 T2 B
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001* O& k1 a. H1 V" v9 C
复制代码 ' a0 U! d% t' u/ o
$ T* s, [! D- X. D9 L
( C; s. x4 y4 T* i: V9 q
0 |% h z" S( j$ o6 @- P3 @7 |/ Z$ d3 Y3 J6 q j: p
! @1 e' w, N+ k& C' A. l. c8 v
3 G, a. ~* E" w" B' k0 T; U4 H |