本帖最后由 shane007 于 2023-8-26 14:47 编辑
r4 a" Y. E9 g9 @% E% l3 P) }" e8 Y& z! g: U% y
这个有的在上一波(第4波)中进行了比较深入的分析。) S: w( l( S) }
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。4 Y( h: z+ K6 i" g. R
/ ]; |) w& g# r! N
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
% M1 V* C( n {# M' p c$ v 具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。9 [; M `) J |% g
5 a4 V6 J6 W& W# B( y* [《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。$ i6 T' k% S( u, O
) P# i8 _& @, T, E# h
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
/ d9 ?4 [ J6 q, Y) t从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
/ z/ B- U. L2 B) G这函数传入一个text_object,里边也许会有颜色和坐标。
( T0 j' b5 p" K' v- char_unicode = (unsigned __int16 *)(*str + 2 * counter);, ?" r6 H& [* B; Z1 D8 N
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
3 ?# ?' E f7 V4 Y& [$ A- M此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,- D( `. l0 _3 f: l+ K% Q8 ~
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
% ^3 F, S) E( L4 I( K8 [ I# k6 z
0 h3 {- a8 W4 ?6 P' x
以下是修改过变量名的代码。! R2 n9 s8 d U3 n/ A S
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)8 |0 W* s8 |9 \) C8 d$ _. X# h% y0 E
- {' Y& Z5 _: z: ~7 l8 B4 g, O- O
- _DWORD *text_object; // esi
0 r' x! f; ]6 a* l* r" G: y0 q Q; D - int offset; // ebx
+ X( {: J3 k5 u. t1 a0 j; B - int counter; // edi
/ ~2 Q# ? W% p: \( t* c& P - _DWORD *str; // eax
' M! D) ~: y+ k! r - unsigned __int16 *char_unicode; // ebp
8 r3 }, i2 z, L. t/ o) c, y - int v9; // edx* Y/ I1 V$ c8 z. |7 m: X
- 1 K1 I6 a: E7 ^
- text_object = this;+ {/ K' ~6 Z# `* x' k. F3 b6 a
- offset = 32 * length;/ v. [4 H3 t" q* s; T5 X
- counter = 0;" |) S$ c- c% }- @# y
- *(_DWORD *)(32 * length + this[21] + 8) = 0;5 [& }* Q. ? E1 m
- xctArray<unsigned short>::add(*a3, a3[2]);; c, @! k; X3 y1 }- }; `3 x
- if ( !show_subtitle_flag ), N1 C1 D9 I4 C
- {
; E5 @3 e9 U8 Q) z! b! ^5 w: J5 C - str = (_DWORD *)(offset + text_object[21]);
A0 t. k) Z- p. {" x - if ( str[2] > 0 ): X! q' N, W7 s& `. @- t1 m u# ?
- {& H7 \2 |! V2 m
- do
Q9 R8 b. E _/ T+ C9 G) r9 y7 t" p - {
9 q4 T9 ~3 I; |/ y6 {" s8 i - char_unicode = (unsigned __int16 *)(*str + 2 * counter);6 ]9 f, f, A4 F% X
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
7 C0 [$ P6 ?7 \! }; X2 V# Q - ++counter;
$ y% q. j- X+ ]6 ?& ?% H - str = (_DWORD *)(offset + text_object[21]);! G. p# W1 b! U4 }% ?9 }
- }
, K' w( C# Z0 q) w - while ( counter < str[2] );
: \( q# J4 q2 t* r9 G+ B$ v' Q - }: J% J8 E+ W# o8 d( u
- }+ a T7 j! \5 D8 A1 `/ k
- v9 = text_object[21];
! y5 [$ r4 ^3 K/ R - *(_DWORD *)(offset + v9 + 28) |= 4u;; h' h2 z" I) \4 z* S" Y
- return offset + v9 + 28;
5 x. g* c7 b y. F5 ?; D' @! n - }
复制代码
6 Z5 N$ n, R! s: {xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
4 R5 }8 w$ O" D. p1 a& [- h = CreateFontA(( j" p* A0 e, z1 }# M7 ~7 F
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
: l# g L' j" D* S - 0, // 字体宽度(0 表示由系统选择合适的宽度)6 x8 p3 W# k; D, N
- 0, // 文本输出方向角度
. R1 h! {" ]& ` - 0, // 字体基线方向角度
/ N, N- z8 \1 |1 u! B1 H - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD); b m2 W& `' k8 a+ i
- *((_DWORD *)a1 + 4), // 是否斜体
/ A( R- A$ y5 X# u8 O5 D - *((_DWORD *)a1 + 5), // 是否下划线6 Y7 K- ?) U7 I/ ]3 ~% m0 l. u
- *((_DWORD *)a1 + 6), // 是否删除线; K* z/ c. r2 t2 `
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)% t% e' D: e1 X1 L* p8 [- X
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)
- l7 |% c; M3 G - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
% t& e* F& ?2 i' [* { - 4u, // 字体质量(DEFAULT_QUALITY)
" z5 C& D! {: M$ H( Y. m - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS), g$ U0 i, F( f* x3 T
- *(LPCSTR *)a1); // 字体名称
复制代码
/ C. A& F4 [7 Q' b2 B用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。/ U$ Q& Z% g$ I: f/ q# i
, K/ g7 S. |' N! m# _- r
- # Time of Day Thread Module API Return Value Error Duration
' p9 @3 b! d4 v$ c - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
( Y# Z8 c6 E3 c8 W9 D- k+ r3 ]$ Z g - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
* c1 u8 \9 g4 p( {$ i
复制代码 2 P# e3 t: i! I6 f% H- |8 N+ l
; A" _: ^* ~- p$ f( j; q' {: Q
: E2 K. E) ?$ C
3 L5 x+ s2 L( A7 C! W( J/ d U
) T8 e; y, `6 T
1 }7 W' J. n1 D" Q1 j# \
) l& s1 z. b' R; c
|