本帖最后由 shane007 于 2023-8-26 14:47 编辑 & W2 R" Y% n) C Y; z
7 A" b9 Y. y5 `
这个有的在上一波(第4波)中进行了比较深入的分析。
( H# w1 {# x6 h9 j% k' _4 t本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。& R, v- E2 { y, A' U' U' H# [% m
. |! d/ _' g+ P: N7 d- t9 ~7 [$ T
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
4 w0 {* I3 ]; X) Z. u n 具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。 R) p+ K! ]; b* J$ ?/ H
) ~; C2 ?$ N- G o% f' G# W+ N5 y《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。6 P7 x! L0 ^/ v9 ?
9 J6 ^* I& [2 J2 S% g
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。4 F' g' m! L1 r* F M( B
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。/ k' B# E, Z; ^0 `
这函数传入一个text_object,里边也许会有颜色和坐标。
) @" a. G8 J- c* Q9 y( P- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
& @0 j. c# l# `0 W( e; _- Y! @; m - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
% T0 M. C! e/ X; o4 R此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,' o! b9 D+ Z: l) a. [
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
' o4 _' h5 g) e0 f) j/ a+ _% a. ?9 d8 B3 w7 ~$ F, z
+ p1 S' i2 I4 K/ `8 s
以下是修改过变量名的代码。
" i, }8 k: O$ z! }8 I- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
" c; m0 z1 l K/ q6 q" I7 @! B - {$ P( p3 r# H. E' W
- _DWORD *text_object; // esi% }% ~, p" c% U
- int offset; // ebx
9 M+ \8 U* {( e% `& J* d7 Q - int counter; // edi2 C8 Y. c* e0 S1 u4 r& z% c
- _DWORD *str; // eax8 d: o6 L: y: `' Z- V
- unsigned __int16 *char_unicode; // ebp
0 E3 S5 y) m$ r t2 v! y - int v9; // edx
& }7 h2 y1 B8 }! T% w1 K$ l - # h' u- J h. Z/ r
- text_object = this;
, n* q2 u& w* U/ }) F - offset = 32 * length;
, k6 G8 s3 C" P+ K - counter = 0;2 G0 |! M* x! ^, }7 m5 F
- *(_DWORD *)(32 * length + this[21] + 8) = 0; B$ i6 Y) x# B E
- xctArray<unsigned short>::add(*a3, a3[2]);5 o' G1 B; d# S5 x5 c% {7 n
- if ( !show_subtitle_flag )/ s; I) i2 H4 X, c- t2 S5 Q0 e& Y
- {
9 S, f: f( ^& B+ N( f2 r/ A/ b3 J& Z - str = (_DWORD *)(offset + text_object[21]);2 @& b/ H* Z- ^& C1 E
- if ( str[2] > 0 )+ v: D' m1 X2 W* s2 O. W& E% P
- {
4 L) K4 q( t" Y' P# q ?! g* k/ d - do
6 L8 @, I3 f5 A- o- z; P - {
, z5 D, I* H3 F - char_unicode = (unsigned __int16 *)(*str + 2 * counter);
3 N: P/ _4 d+ {! ` - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
- J$ p/ T! H6 A5 L1 c2 d) \: O - ++counter;
: j* A+ F6 {/ n, S3 K: `: u' G - str = (_DWORD *)(offset + text_object[21]);
& V! Q2 x0 s: |) J2 j, l - }5 Z0 I! ?+ N4 L- `3 ~% {
- while ( counter < str[2] );
+ C, c7 b# b! `" S: q$ j - }/ a2 Y( Q: T4 L& H4 |
- }& |& z! N( \# R' z
- v9 = text_object[21];2 |9 ?$ f- P" c! r1 u: j: C4 C
- *(_DWORD *)(offset + v9 + 28) |= 4u;3 B2 d7 U9 e. f/ b8 f4 o3 r2 I
- return offset + v9 + 28;/ P l3 j* C0 O& C
- }
复制代码
, c/ B% h, o0 t& A6 j bxcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
8 c; f* A5 E8 _" L7 B- h = CreateFontA(3 W2 H2 x' a$ D+ W9 ^# a& J0 p
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
7 r" p' w, z2 a - 0, // 字体宽度(0 表示由系统选择合适的宽度)
* l6 C4 n$ B4 @, I" k6 f# e - 0, // 文本输出方向角度* j, d+ F. b. u) U' ^) k
- 0, // 字体基线方向角度# t/ r& L; M6 @. J; Z1 N( L
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
* L6 q! M4 p/ c" j4 ~ - *((_DWORD *)a1 + 4), // 是否斜体7 F4 t0 i; `! P9 T9 N
- *((_DWORD *)a1 + 5), // 是否下划线. H5 g- u( s, J! ]5 x/ r
- *((_DWORD *)a1 + 6), // 是否删除线/ v7 I7 ?, T" |9 w; H
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
% q( Y- J4 u. R1 c - 6u, // 输出精度(OUT_DEFAULT_PRECIS)
$ f- C5 P% c/ t2 f - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
: V+ [3 k+ k; p' A7 N: z - 4u, // 字体质量(DEFAULT_QUALITY)8 F, r5 G" N$ j5 E" h& _; ?! Y1 R5 s4 x
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)4 A, C1 R2 P; W" e
- *(LPCSTR *)a1); // 字体名称
复制代码
# o; M! A' Q: A用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
& A7 ~2 a" A p" }8 |0 z; G0 Q4 v1 I1 b1 ~% z2 D: p; x) a
- # Time of Day Thread Module API Return Value Error Duration
T0 V) O x* I& n0 c( H9 I/ k - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.00000023 ]# |9 Q8 a! P! m1 c; ~. e3 Z
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
2 c6 s' ?7 ?0 T- ]8 |: e1 Q w7 M, b( K+ S
复制代码
( y% g: v$ |8 W4 p; i7 ~- f' K
' W7 [; o: E V; M# }, a. A9 b; G, R2 Y5 @# y. o2 U
% G d; X+ Z# H9 Z( n9 E8 F* n
; u, N4 F8 t s- i% ]8 @3 H) Z% [2 W* h6 [6 U, z: \
+ x1 _; b0 P# a/ V/ B0 B; _5 p |