本帖最后由 shane007 于 2023-8-26 14:47 编辑
' e% `' F( W6 d# \2 t$ t2 m S
6 k( b7 s* ^7 W/ }& t这个有的在上一波(第4波)中进行了比较深入的分析。( M5 X3 E& g% k
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。8 A; ]5 ]2 z8 f; ^, x7 l
) F8 y8 i: O% e3 z1 r0 M《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll' d5 y0 Q E: p7 ~
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
7 H7 U! [8 \0 Z+ p4 G4 s6 I
9 N( G2 p1 t, x* p《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
4 F0 a, k2 n9 S- u4 s1 `6 I- L! E3 a1 ]- U( o1 W2 E
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。' S1 `3 S6 N: |% y
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
2 V5 ]: m2 G r- A& }4 l+ Y这函数传入一个text_object,里边也许会有颜色和坐标。* o& f7 Y6 b7 i/ l" b- k
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
2 S' y! ?: ~5 G8 `6 S5 z - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码 ) I' \8 T$ C$ K L& o) I, x
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
& j" @/ U" U. S7 i3 u- p因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
4 h6 }+ L& Q$ |+ B% _
( M5 d3 T" d) O6 Q( l( E- v( {0 t+ J, l5 N+ h s1 T" e2 y2 C
以下是修改过变量名的代码。9 n W% r. ^/ [! C0 }, A- B) p1 \
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag): a: b- o: s+ {1 x% Y
- {
6 \' s. [. s$ Z3 x9 x0 F$ D& A - _DWORD *text_object; // esi
, r& p' x" i5 N% [ - int offset; // ebx
1 d& f# i, X8 S! g0 | - int counter; // edi9 k9 {! a) m& v$ x
- _DWORD *str; // eax. ^2 u5 f" Y% K0 `- G$ J2 h4 I0 d
- unsigned __int16 *char_unicode; // ebp6 ^3 D; w* R; w) r! [/ M
- int v9; // edx
. I3 T3 J' V; E
" K2 f6 c t9 Z5 `) H- text_object = this;
3 x" g+ L2 Q$ Y# m+ T$ M - offset = 32 * length;9 J6 X7 T0 s7 i u
- counter = 0;; c4 r6 A0 U6 l* h4 r O
- *(_DWORD *)(32 * length + this[21] + 8) = 0;
1 d y2 g! O x5 w - xctArray<unsigned short>::add(*a3, a3[2]);
& W2 m, Y6 ?5 f, F0 O! B1 _' C - if ( !show_subtitle_flag )
( Y$ W9 v& Q6 H: c7 c9 ^6 G/ L - {
% k3 Y6 k! K1 r3 M7 c1 X2 {" f) l - str = (_DWORD *)(offset + text_object[21]);# @' H/ i% ?- N( c" h
- if ( str[2] > 0 )+ h; \6 f! C' I6 M, ]
- {
% T0 H2 x0 M" T - do0 a: y5 E" {8 ]
- {
. @3 Z5 i! ^' B - char_unicode = (unsigned __int16 *)(*str + 2 * counter);' B6 `6 X: L8 j3 g1 Y
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
6 h* {4 {7 \/ b0 r7 Z2 P - ++counter;/ w0 M7 h3 Q/ r+ L$ l; S
- str = (_DWORD *)(offset + text_object[21]);1 Q, T2 ]$ }' I/ m+ D1 ^
- } s3 T8 g$ A) c/ }, A6 r
- while ( counter < str[2] );8 A0 y; @- [* P' G8 `, V
- }
0 j4 H# S0 J6 k0 C - }
* X, O2 v+ x3 @/ q" @# p* { - v9 = text_object[21];6 L# z; X) B5 z, R1 R. o
- *(_DWORD *)(offset + v9 + 28) |= 4u;! O9 I8 ?, X1 ^" u {4 V/ l0 E
- return offset + v9 + 28;, E5 g/ x4 B' T& M: w0 m. J: n* `
- }
复制代码 ) f8 p1 j' z+ C9 L* U
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
; t' N8 G; I5 ~$ B- h = CreateFontA(
1 i e' S. r Q - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
. [' h7 N, \8 a- \3 \9 [ - 0, // 字体宽度(0 表示由系统选择合适的宽度)
" I" h8 ?: P @: X, ] - 0, // 文本输出方向角度
0 u* v$ q" I; ~. u - 0, // 字体基线方向角度
) Y- I& \/ T# ?' e - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)0 ~* X+ X& L( h3 k! q D8 b& p
- *((_DWORD *)a1 + 4), // 是否斜体
l1 Z3 W; V/ T9 X" O2 M - *((_DWORD *)a1 + 5), // 是否下划线# c' f" \' M; ?1 q4 s4 v8 C
- *((_DWORD *)a1 + 6), // 是否删除线
j( |& { w7 |$ Q+ ? - *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
& [6 K% l3 l1 N) D - 6u, // 输出精度(OUT_DEFAULT_PRECIS)
! Q i9 C8 a, ` - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)4 x6 K( \/ A3 w1 s
- 4u, // 字体质量(DEFAULT_QUALITY)% d& J" h& c" e& O2 ?8 ?3 f; [ k
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
. ~ ?* O0 r# [/ L j - *(LPCSTR *)a1); // 字体名称
复制代码 & y/ t9 a/ N& h: g; [3 W
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。# L# P/ H. M4 z" H5 K+ ~
3 r. S! A- P1 `. ~3 _- # Time of Day Thread Module API Return Value Error Duration
+ k: S+ S+ l+ A - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
0 L5 s, L* }% h) x F4 d5 U: @ - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
% e0 K2 |5 C8 C# w' F
复制代码
8 s# h1 |; C$ Y5 `( `$ a# ^' ?
& P- }7 C3 ~5 D
! {: i; d- u# I$ c1 ^, f
. R$ ]9 b3 P w& T' U1 b4 D; `- M
B3 U {& y) [
: ]6 i7 e- w( W3 i6 [' c/ @
$ D4 p6 T/ B5 t9 x0 \ |