本帖最后由 shane007 于 2023-8-26 14:47 编辑 5 l3 \0 p G- W. f4 ~' F
; x/ l/ X( n7 A% d: H8 a; Z$ w
这个有的在上一波(第4波)中进行了比较深入的分析。+ W+ y2 e/ i/ A' X1 ~" q
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
% _( \" K" l+ k0 b" |# A2 x I* M* b% s- f, _& P. [2 b# [
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
5 x# X6 h& d0 a1 @" `/ S0 o) l 具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
% m4 R$ c, Z1 d! _1 y1 o& w7 L& Q. v7 `0 M
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
: W9 S: s+ M; |# S, Z, {/ A0 {' H
9 h$ q/ y# q' D! ~0 q" A4 c! E+ V5 C7 ^关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
) v; Y8 j9 @* s4 t$ V从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。. ~, A3 P, m" V
这函数传入一个text_object,里边也许会有颜色和坐标。* o5 i, s' v. Q9 ]/ A# g
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
- q* y5 L( Z [: Q4 U) ^: }3 z- T+ y - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
( Z7 \9 @( e) v% D, E) [0 T0 X1 _此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
( P; f* m. o. A$ ]% @* e: _& b因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。3 b4 ~, }. z# G" |
" q' q& q1 ?5 |) R- [
, D T2 Y f v! Z
以下是修改过变量名的代码。
' g" Y3 K. F# A9 Q, |) G. V- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)" K3 x/ h5 n) l; t: t
- {
: E( B! m. I. ]/ O0 G4 B - _DWORD *text_object; // esi
* @6 w' K( ~7 s5 N# A - int offset; // ebx
$ g- V) }' z# S - int counter; // edi! W5 f0 p# L: U) O# q2 D
- _DWORD *str; // eax
4 i$ }9 u) a5 L& G - unsigned __int16 *char_unicode; // ebp
# R6 D$ k2 ~" n8 g - int v9; // edx
# I( u7 i! W1 d) k1 j9 x - ( Z7 C) a/ T$ i7 z3 Z
- text_object = this;6 h ^6 y3 [1 b: d/ \, S8 m
- offset = 32 * length;# z4 B. r+ N# u8 X' h- ]" Y
- counter = 0;
# Y) `3 G0 R5 s0 J. ~; j" Q, Z - *(_DWORD *)(32 * length + this[21] + 8) = 0;1 R. Z! T' I. e
- xctArray<unsigned short>::add(*a3, a3[2]);0 B# K' N/ [! o% p% D/ @4 t
- if ( !show_subtitle_flag )! J9 C |8 I/ Q9 t
- {" @9 W2 e; s# l0 z8 V
- str = (_DWORD *)(offset + text_object[21]);
1 E7 ?/ o; z1 c3 p - if ( str[2] > 0 )4 ?9 q9 \' x' V
- {
* K5 u- L; r+ Q1 r t' ?; Z - do
% z; G7 g. @3 O+ u7 n - {
4 W5 R# B/ S% ~" z$ F, V1 d - char_unicode = (unsigned __int16 *)(*str + 2 * counter);, F1 u; _1 N6 \7 E$ w' w
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);' e5 T" l+ |3 C- y% L/ E# N
- ++counter;
, z+ @5 R S" `' C7 g' L5 z - str = (_DWORD *)(offset + text_object[21]);: r& |+ C5 ^% C, p& e U$ D
- }
, L& M- K5 ^& ?8 F0 i6 X: p/ B - while ( counter < str[2] );' o! }/ h& O9 n! p
- } C% A7 y- A H. ?! a
- }% |5 A& o; J% M6 _. D% N
- v9 = text_object[21];
% w3 Z* P3 q2 V- `6 { - *(_DWORD *)(offset + v9 + 28) |= 4u;( s9 O9 E5 h5 p4 M0 ^/ W/ K7 e" q
- return offset + v9 + 28;) x; m" \1 x% |) t7 m" i6 [
- }
复制代码 ( |' Z' s' M9 Q! A0 ]' S3 n
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。! p! `* L+ c6 e; p0 C p
- h = CreateFontA(
+ v r. C# c! j, }+ j - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)7 q- f% j6 }" E. S( {
- 0, // 字体宽度(0 表示由系统选择合适的宽度)
) m! t0 ^" `4 I# h - 0, // 文本输出方向角度; D% @9 _; i3 r2 Y
- 0, // 字体基线方向角度
( d1 B4 J+ G9 [& a8 k r; c - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)' H3 w1 v+ n) {2 l0 ^
- *((_DWORD *)a1 + 4), // 是否斜体; L5 ?5 A' A+ u1 i9 |
- *((_DWORD *)a1 + 5), // 是否下划线
1 r0 o- s4 G) M; G. H& \ - *((_DWORD *)a1 + 6), // 是否删除线# f3 D) r0 S* ]" Z5 p; P
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)/ T! r" B( {: V
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)" W! y- i4 }: \
- 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS) Z5 Z, ^2 y/ n8 k& P* s
- 4u, // 字体质量(DEFAULT_QUALITY). \: _" }, t# z
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)/ p: o z! W, M/ C1 H) y
- *(LPCSTR *)a1); // 字体名称
复制代码 ; z- C. e0 q& c" H: o* b5 c/ U
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。- J% v' u+ M6 \8 i
' ?, _$ X) k1 S' f+ Z) F- # Time of Day Thread Module API Return Value Error Duration% d6 H$ R9 d' ?1 {( r7 L8 H
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
& m% |; o" E! `* C) M$ [ - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
% \. n& i8 H" Q) H/ Q* p+ c ]
复制代码
0 U1 j; J' y3 d& \8 I G- M _( |% }6 X+ }+ j
: A$ q" Y' T+ [" `' m6 I3 Q
6 Z( {. w& o. n7 h- I
; o- [6 g. W, t7 `) i; H3 {8 b
/ B8 ^ G+ _9 Y3 G; b' k8 ~) J: G' g: A8 L$ O1 P$ _2 P5 I1 N
|