本帖最后由 shane007 于 2023-8-26 14:47 编辑
3 m" t& Z- Z d" r8 D& p9 Z8 t/ G m. N4 } s2 E J5 V" _ x
这个有的在上一波(第4波)中进行了比较深入的分析。
w& B: ~) j9 S. j! G本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。! I Q/ `% D6 b& x$ j
$ w; z% r7 a; g. X7 u( k
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll9 _* M: C' C# s! w5 I: X
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。& @9 d2 x% v% Y4 O
5 u; k* U/ t& M8 u9 g T- H1 ]《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。6 \4 w4 V8 }& y' R$ v* `8 z) N
& v8 X+ r' w3 {) o
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。9 i+ h! A& s/ D; u0 j- [/ f5 u% Q# t7 H
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。, C# |5 e* k" E: s8 i' R
这函数传入一个text_object,里边也许会有颜色和坐标。: n0 {* R8 c+ `: f6 j; K
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);
5 H1 C9 V# u# T - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
# E: d7 a2 z! G' p0 R+ k此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
0 q( z' j, ?; n" }1 E因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
' }7 C' R/ V" l3 _3 ~; N$ l5 a8 O7 J0 w
' X+ L+ d+ L; m# m& s4 P
以下是修改过变量名的代码。
9 ^" g" X3 g3 ^, W9 }- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
k% O' S" b6 |4 T - {
# |2 o$ b* r7 v* L, v7 ?& B/ |! {/ s - _DWORD *text_object; // esi
" X, _# t# P9 j1 @9 i7 h - int offset; // ebx! R8 V( i4 C9 R- G
- int counter; // edi4 y' p( L @0 L) k0 e
- _DWORD *str; // eax
$ T w4 b/ }+ w1 x" c - unsigned __int16 *char_unicode; // ebp
1 b6 ^+ \# S3 v( `* [ l) n$ _ - int v9; // edx4 q9 b, c' y9 E7 {
3 i: y& C3 |: ]$ A1 \- text_object = this;3 Z) d) R" \6 M3 I { s3 B
- offset = 32 * length;9 Z7 ?2 u. L6 i7 R" R. J
- counter = 0;6 X2 h! m6 ` x& D, B+ g
- *(_DWORD *)(32 * length + this[21] + 8) = 0;
F3 L& l5 R1 S2 N$ _: ^2 T" x - xctArray<unsigned short>::add(*a3, a3[2]);
* g2 Y7 d, p7 l' f6 G3 o* N - if ( !show_subtitle_flag )
4 m% w* s' _! j - {" w9 J% q1 i- C- s8 r
- str = (_DWORD *)(offset + text_object[21]);
! b' a8 ~3 q* Q4 J - if ( str[2] > 0 )
* ?% Q, Y8 X1 P4 z F2 c - {
: S) }. F1 L1 k$ | - do
' _ ^2 q9 s7 l - {
/ j) U4 r3 e& c' `1 D - char_unicode = (unsigned __int16 *)(*str + 2 * counter);' y6 w5 B& ^+ {+ l4 d& |1 m
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);3 ]" F3 [# {) L% t1 C. n+ t% ]- r
- ++counter;- b9 z% Q, p" s ?
- str = (_DWORD *)(offset + text_object[21]);! K& Z1 c6 h- n% S N/ a0 N+ A
- }' H. D8 {* b6 f1 V7 m' i
- while ( counter < str[2] );3 w3 X+ z+ _8 ^' m6 c; Y
- }5 o& t+ x, V) {; b5 x8 U7 a
- }% d; ?, F3 d( \5 e8 _4 f% ?
- v9 = text_object[21]; j. a/ @4 d: k. B$ O4 o; C
- *(_DWORD *)(offset + v9 + 28) |= 4u;
6 E# r" V0 S5 f4 X v \ - return offset + v9 + 28;
$ ]5 f1 j6 h, _5 L! Z, Y3 Z# B - }
复制代码 8 Z. \+ Z& I" [
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
( }% A/ \; b1 d4 [7 j- }( f3 Y- h = CreateFontA(
6 D: O& f9 D3 ^ - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)) z$ a2 K8 _" Q/ Y5 R
- 0, // 字体宽度(0 表示由系统选择合适的宽度)
" i7 h) p6 I: ]/ k1 t. U - 0, // 文本输出方向角度
4 K/ N. `; d9 Q. N- A - 0, // 字体基线方向角度* d( J, B& D7 v& d% M
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD) F! z! e9 @ _" d* i) Q# w5 \
- *((_DWORD *)a1 + 4), // 是否斜体3 H( Z( t) T7 Y5 I! z
- *((_DWORD *)a1 + 5), // 是否下划线
2 V: M2 e# F% e- i s/ Y# |4 Y - *((_DWORD *)a1 + 6), // 是否删除线- B' y5 Y" O( Y! {$ d$ v: {, |
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
# ?* a) D' m/ w' I- _/ r - 6u, // 输出精度(OUT_DEFAULT_PRECIS)8 L) B. s3 p0 V- j5 i2 q
- 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)1 V& i: @, ], M& L" x1 |) i" {8 ?
- 4u, // 字体质量(DEFAULT_QUALITY)5 d: Y2 P/ J4 f% I- c
- 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
1 f% g! q8 R( @- i0 @( b - *(LPCSTR *)a1); // 字体名称
复制代码 3 c+ \3 o# Y+ c w: ]( ~
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。1 `' d2 ^+ R; Z9 M# A1 j
( r, R% X! n- R
- # Time of Day Thread Module API Return Value Error Duration7 S: X/ c( D; j: i5 t
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002
) u9 e) n6 N: i* Q) T - 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
2 m3 d& X4 y& Q8 T6 H' f r! x7 I
复制代码
8 _$ s, R" |3 d6 ?
0 S0 R+ \8 v9 M
B% Q1 Q i0 D" A, x1 X
; H& x) L5 L+ N' Z+ t, l' x( p' \( V, d% I
_1 |0 f- g7 Q+ F' t
8 j% |3 p5 U' M7 T! J% t+ W
|