本帖最后由 shane007 于 2023-8-26 14:47 编辑
1 t7 l: K- T! a6 c/ T2 _1 W
7 q F/ p' q; G# x M! f0 r3 Q这个有的在上一波(第4波)中进行了比较深入的分析。. C7 Z; {% P# W+ t. J
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
2 b5 d+ J! g+ D, y; }5 M' D4 X5 w2 T1 q* X6 U, K$ s) I
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
3 P P4 ]/ m. n' r) r. g 具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。0 K1 t9 A! |0 L' I) `
0 p: o5 J& _0 d5 h+ b8 \% i: T《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。1 J& X9 y; s) @/ J f6 q( a4 C3 P
( r$ X- G% x1 A' R! j关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
% ^4 Q+ F1 Z# {9 \; p, }从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。( v- R7 Z u3 Y8 L9 t+ u9 ~- p
这函数传入一个text_object,里边也许会有颜色和坐标。: o# E# p/ ~! g0 U
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);: Q- A, Q3 {" Y8 Y! t; v! [
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码 : [) r+ X' O( z$ i( ^1 D
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,0 O' S: {4 O" E. j6 d
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。( @% t8 m% r( t" Q" g
- G) y6 M d2 K" I# P# A; s
9 U9 W7 p, v, C! t以下是修改过变量名的代码。/ L& h: J+ k8 n! D, ]" a
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
" j# J9 X4 Z' D8 R& L9 m - {& D* g; k& h' y# t4 m! m' m
- _DWORD *text_object; // esi6 Q# D9 F) l3 T8 @. ?( M5 n
- int offset; // ebx7 f3 J. Y& W1 r6 D
- int counter; // edi
+ E: y# S3 S: h, s7 m - _DWORD *str; // eax
: B4 |3 |. ^4 Y' c- X$ { - unsigned __int16 *char_unicode; // ebp
8 V+ E; g* Z. b1 u, @( b, @) a - int v9; // edx
; s Q$ \ j9 @+ g. ]' c - ) z1 n1 w9 S* S7 H7 r
- text_object = this;
9 L- q& R: v n" y/ b* z - offset = 32 * length;0 |+ Y5 L+ K! G4 h* B
- counter = 0;" _# N: O+ w# p
- *(_DWORD *)(32 * length + this[21] + 8) = 0;: q+ n, `+ h$ Y
- xctArray<unsigned short>::add(*a3, a3[2]);3 b* c# P w4 H0 p: S* e
- if ( !show_subtitle_flag )8 c0 l9 e* A3 |6 t) S
- {
9 J) s6 E7 {8 y/ c - str = (_DWORD *)(offset + text_object[21]);
" s5 t! H4 c& \) j+ E+ f" {: d - if ( str[2] > 0 )$ q& c0 \5 ^. O
- {1 R& H- V7 O2 o: I4 f9 T4 b& U
- do6 H0 G' v% J4 y- Z( f- I
- {9 z& o2 u" ~' ^
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);2 |3 K! m5 _, @& Z. x% O. z
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);* s4 K; T" K* S" r: c' ^, v
- ++counter;
8 k F i" y/ Y) D: |7 i! m - str = (_DWORD *)(offset + text_object[21]);4 k3 s" r/ c. E( O
- }8 w) H+ q( L1 i9 T' }: R
- while ( counter < str[2] );
7 B% l, y- x$ t. l8 A7 ]( q# z; m - }
" q0 i8 s6 P/ `) J0 Y - }+ Q. X/ c/ L& W0 t
- v9 = text_object[21];5 o+ U( `2 a# |' q6 J, J* C9 v
- *(_DWORD *)(offset + v9 + 28) |= 4u;
$ T6 i; Z) S% G$ n+ `+ n* H - return offset + v9 + 28;
7 |- z1 `( x" q, m) R0 D) b - }
复制代码 * w8 d2 |+ g( ^0 t* K8 a2 h* x' V8 W
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。- c* I9 B3 M: z! \& J4 S
- h = CreateFontA(
" r+ ^# S/ F/ ^- E - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
0 V2 v% m" r3 F4 y( y" i - 0, // 字体宽度(0 表示由系统选择合适的宽度)- x9 p# _, _9 S. A6 |' D+ g3 T
- 0, // 文本输出方向角度
. m0 p5 p0 N- z- }: K, O# [ - 0, // 字体基线方向角度; C w$ S% h4 n& D* [
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
( ^* i9 b$ i2 B6 s - *((_DWORD *)a1 + 4), // 是否斜体
+ B. c+ f$ W) |' c6 {/ v7 V e, H - *((_DWORD *)a1 + 5), // 是否下划线
: ~9 t! m1 r$ C, E2 C) G - *((_DWORD *)a1 + 6), // 是否删除线
7 u9 g0 d5 B; `& ` - *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
' |+ J& _5 b1 K: S$ i - 6u, // 输出精度(OUT_DEFAULT_PRECIS)0 V$ D* x; y/ z7 J: w
- 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS): | y2 L1 ?) x% V9 A+ y
- 4u, // 字体质量(DEFAULT_QUALITY)- L2 W( h9 c& |
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)( ~+ U' h9 M6 H Y% i, i
- *(LPCSTR *)a1); // 字体名称
复制代码
8 W3 v, i- m9 L2 t! x+ W* f% m/ Y用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
. v9 V9 X' J3 O5 j. n, X/ @- o8 F1 {- k
! k8 Q7 C8 K# E" C( k2 e5 q7 M- # Time of Day Thread Module API Return Value Error Duration+ [" A7 `( ~- V- O* B0 l1 B
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002/ p* {0 C% @7 T) f# t( l6 I7 s
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001; t" c/ F4 F% z; N" ]# Q4 T
复制代码
9 F- j* L. U" K" x$ ~8 W% T! _1 h, o( S, h
k! x! G6 K+ |7 O3 g6 W
; ?8 p9 L$ c0 e$ Y; O0 U+ t. A
' D* g. `- ~2 T7 C- d. X/ s, v8 M$ l* f, ~
; {8 `- ~; [- K% d) x, f' u) N
|