本帖最后由 shane007 于 2023-8-26 17:10 编辑
8 E1 o+ j+ l2 H# e
) D6 J& V; N% W& Y( W这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
3 J2 b, O4 N: y6 H" `% J6 H$ z用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。3 T7 W' s( Z; k# x' g# f% N, V
_; `/ ?" i* j& G! M
- # Type Name Pre-Call Value Post-Call Value
/ ]$ q# f( F. V# z$ g - 1 int nHeight 0xfffffff0 0xfffffff0
% Q5 K* [ j$ m- {3 W0 w) M1 ~ - 2 int nWidth 0x00000000 0x00000000
- O' x F* ~% q: [ - 3 int nEscapement 0x00000000 0x00000000
7 b! B* o/ j2 m4 P- d* \8 ~! _% l - 4 int nOrientation 0x00000000 0x000000009 \0 ~1 N. |4 j U! o
- 5 int fnWeight FW_NORMAL FW_NORMAL
2 F1 R5 U y% d! w$ _ - 6 DWORD fdwItalic 0x00000000 0x00000000% }7 Z9 p& g- v% K _: [8 L) }
- 7 DWORD fdwUnderline 0x00000000 0x000000001 q0 O8 C* o Z; \
- 8 DWORD fdwStrikeOut 0x00000000 0x000000006 F7 U% E T: W' v( s/ f
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
: Y" @- ^# J# z; ] - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS8 u" C, h+ l" E# n& g0 @/ b
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
. ^9 U- M( S7 `! Q' o - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
0 _9 o0 @* D- f+ Q8 U - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH% k0 h) L9 K0 C0 n3 J# z! K# ^) n) ]
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
( p$ }+ _# u- C" G9 F
复制代码
1 N! G1 H3 i2 k5 D
0 G, \" u) N& H M3 O用ida pro找到调用CreateFontA的源头函数如下。. [0 j: j8 G( t: m+ s0 N
从函数的参数可以看出,这应该就是字幕显示函数了。6 j' O3 s$ \% Y* |5 W
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。8 o- V3 t- \# P6 Z8 q: U
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
9 e* s9 ^( ]# a
8 t+ T& E* [+ z& k. t- bool __thiscall sub_10058A00(void *this, int a2, int a3, int a4, int nNumber, int a6, DWORD a7, int a8, int xRight, int yBottom, LPCSTR lpMultiByteStr)
2 @3 h% p4 b. ^ - {
. S5 M$ B7 [% i5 s. |% A3 b - void *v11; // edi- {5 \$ {3 Y2 T7 X9 S0 O
- int v12; // eax* }4 Y. y7 m) H& w |/ R9 G
- int v14; // ecx
* ?5 ]8 v1 |* ]" l9 I7 X - int v15; // eax1 R# D/ D# O/ B7 B! j8 e/ }: o
- char *v16; // eax f" M, m. f5 s6 X) H- K+ H. y9 B
- int v17; // eax- r1 B. Z. O7 t5 ?; x& j
- HDC v18; // ebp1 @3 o8 W0 Z p# l
- int v19; // eax* `/ v" F2 _# [" F6 @
- int v20; // eax
) E+ v6 M, c" N: x. N$ w- o# W( m - int v21; // esi
4 p8 B `# Z* D* s8 K& n - char *v22; // eax6 z3 X# {1 ^4 q
- int v23; // esi
1 h! ? {& ]- L9 [8 j - int v24; // ecx
6 w. v# h, A- j6 x9 Y2 ?6 u - HBRUSH v25; // eax
. n. m* G- u2 f* o* x9 x - signed int v26; // ebx# E1 v3 R. u% D3 X3 r6 z( J- e7 H) {
- WCHAR *v27; // eax4 H5 q5 r) G8 ^5 \ J
- int v28; // esi2 H: W0 Z0 _7 p G4 f
- int v29; // ecx
7 p+ _5 W: \3 R0 h: ~7 O - int v30; // eax, u' X; C% v/ f A. r
- int v31; // ST28_4
. H- ~$ J2 v( J* H1 y - bool v32; // sf( P' s+ j0 y7 Z$ S
- unsigned __int8 v33; // of
1 l6 ]; b3 ?' [ - unsigned __int8 *v34; // ebx
. D! {. |' |) L+ o% s! w - int v35; // ecx+ j' P/ U+ ` e- h! @6 C; I2 ?
- int v36; // esi
6 G0 D: [ I# O' G7 G5 u. ?" o - int v37; // edx
( s% u# [. y- T/ B - int v38; // eax
, N; }% Q9 x! Z - unsigned __int8 *v39; // ecx
, G1 h3 b, I( O" o$ j* I/ d - int v40; // [esp+40h] [ebp-2098h]. L$ j6 e# e9 F9 t
- signed int v41; // [esp+44h] [ebp-2094h]
; B3 q7 Z) x! `5 `: Z: F - WCHAR *v42; // [esp+48h] [ebp-2090h]
0 q/ f% K3 Y' H" }" G6 `1 h6 e - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
% U4 C) E# k2 d! y0 c! n - int v44; // [esp+50h] [ebp-2088h]
4 |; [7 M1 c: {1 c7 {. ]1 z - HGDIOBJ v45; // [esp+54h] [ebp-2084h]( U# p( g7 P' A' x/ q! N! d( w% ?
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]: T P* [5 }9 o4 {4 S. Z
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]
/ w# R! u2 S7 B6 n8 N% F - HFONT v48; // [esp+64h] [ebp-2074h]6 C: t8 f+ r* x) ^6 R
- float v49; // [esp+68h] [ebp-2070h]. ^0 `# v {) t" N; G `+ V; A
- float v50; // [esp+6Ch] [ebp-206Ch]
: i8 d4 F9 n, ~5 h+ `/ y - char v51; // [esp+70h] [ebp-2068h]
' M1 a: K- n2 U9 i - int v52; // [esp+74h] [ebp-2064h]# u1 T& Z2 |, j& J3 ?; Q( h
- int v53; // [esp+78h] [ebp-2060h]" ]1 w% ]) h( y$ x5 E# G* l
- int v54; // [esp+7Ch] [ebp-205Ch]
& k2 Z2 k5 ]4 _# P& A+ L3 B - int v55; // [esp+84h] [ebp-2054h]: H0 `( b. m4 H
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]% O7 A& Z7 s1 `' W. Q3 n$ f2 j
- struct tagRECT rc; // [esp+90h] [ebp-2048h]
0 U* p; r5 V; z+ B/ i2 B" R - int v58; // [esp+A0h] [ebp-2038h]
/ p2 ^3 e3 B5 D/ }1 x+ f - char v59; // [esp+A4h] [ebp-2034h]: K9 Y+ C: Y2 j! l" |& ]6 z$ @
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
1 j% k/ S0 x& y: Q& a - / w& n6 f8 X4 V" U" x! L/ F
- v11 = this;
, u0 Z5 u. H1 w4 w" x8 s1 o4 y+ s - v58 = 52;* U; {& F9 Y/ x" [5 J! A
- memset(&v59, 0, 0x30u);/ Q! H4 V; z, R) ~/ s& y8 w0 b
- if ( *lpMultiByteStr )
1 ]# E/ s# y/ o. l3 G& [ - {6 d5 |) |' L7 t6 ^* B
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
' n7 o7 E8 B1 v/ v( u+ f - *((_DWORD *)v11 + 4) = v12;; R; X. t i8 ^7 G) ^3 N& X
- if ( v12 <= 1 ), ?" D5 Y' P% d. H1 \
- return 0;: g) S' \$ A- z9 F' }9 V$ x: r
- *((_DWORD *)v11 + 4) = v12 - 1;& _& j4 A- w6 Z# }+ I1 r' b6 s
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
8 e( U) P; m- p7 U: P5 J* r - }' q7 K. g# t p. m5 o
- else
- m( i& k1 l! c - {0 Y" D2 s/ Y7 n. b2 X7 g& I
- *((_DWORD *)v11 + 4) = 352;: `' J( x$ j7 n% b
- v14 = *((_DWORD *)v11 + 4);
! m7 O; f! P) o% m7 W - v15 = 0;4 `4 V% f) \ P" I4 H$ V# T4 W- L
- do e" J& }! d3 l c; x1 G& F+ ^$ V [
- {
4 X* X( I- L) t I4 P0 R9 I - WideCharStr[v15] = v15 + 32;1 d. |8 i$ K+ V* m. h
- ++v15;5 v5 O. h3 V7 x8 x
- }% Q9 u! B% B0 x; T, g( Y- g; x; z( Y
- while ( v15 < v14 );" L: L+ V2 Q1 ?6 q- @# I: u$ s5 g6 B
- }: {4 e" _; g% @* }8 Y
- v16 = *(char **)v11;/ s) `0 D4 Y% N9 }/ c( \7 ~
- if ( !*(_DWORD *)v11 )& Z. f: d% I6 c7 [4 p$ S
- v16 = byte_100B2D6E;" E# F4 H# O0 {9 I$ O/ ~1 u, P1 f3 L- a
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);9 b; v. }! ]/ l( X+ k1 `! M0 @: D1 v* s
- *((_DWORD *)v11 + 6) = v17;
* P7 U3 O, z+ Q1 c2 ~2 S - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )8 {. |; P) p. y, |6 m# f
- return 0;
8 x. [' V) {7 |8 \9 x( U6 s$ S, x - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
! n# s( `, [+ p - v18 = CreateCompatibleDC(0);
: {6 C! z* I3 z% C8 H - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
9 S U) X; E T6 v; H: W; G( W% M - v47 = SelectObject(v18, v45);0 ^( q& p; o4 r' P/ ]
- XString::operator=(v11, a3);
: R% ^: a$ I4 c5 r$ D: @ - *((_DWORD *)v11 + 2) = nNumber;( t6 P- C' U2 H) @
- v19 = GetDeviceCaps(v18, 90);
3 y m- A, p# Z& P: {) u$ E: F c - v20 = MulDiv(nNumber, v19, 72);
. b. [9 v9 Q$ ^# i8 j0 ] - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);5 t" P. ]! F; n! i# g$ b( }' ~& E
- v46 = SelectObject(v18, v48);7 b' T. L: s& I/ p5 K+ n
- GetTextExtentPointA(v18, "A", 1, &v56);: e8 N$ n: e% l7 @1 U( g+ K
- v21 = *((_DWORD *)v11 + 4);" e' D5 D3 d1 i; m# m+ O
- *((_DWORD *)v11 + 3) = v56.cy;! O& s& K' j/ C# G3 y
- v22 = (char *)operator new(32 * v21);
0 ]6 x; A# E0 s& N - if ( v22 ). s, P/ J0 @7 @1 h) q+ f/ @4 i
- {
5 M5 P) R# r. \) D - v23 = v21 - 1;
3 y. X1 x, l y1 m( u - if ( v23 >= 0 )7 b( d+ L. J: E1 e& p+ B) K% W
- {) J+ f6 z0 p8 y
- v24 = (int)(v22 + 12);7 l) B% r, v- l7 x8 Q! J0 E5 M% O
- do1 y! ^+ u' a4 T/ I1 \
- {% a7 ^1 J+ u$ y. y0 I: |# q3 g$ b
- *(float *)(v24 - 4) = 0.0;' }( A) t) U! j2 i b% i- _
- v24 += 32;) G* o) V7 m4 ?! P1 z O& F2 H
- --v23;
% F5 X8 v- ] O9 ^" [ - *(float *)(v24 - 32) = 0.0;
+ g' R" ^! }; K, l - *(float *)(v24 - 44) = 0.0;# X1 _5 p" r& C8 m( a4 b
- *(float *)(v24 - 40) = 0.0;
2 r5 z; _/ @. l3 o - *(float *)(v24 - 36) = 0.0;
. d! Y# t+ p" t - *(float *)(v24 - 32) = 0.0;
; E2 b: i0 V9 {& h - }
9 i' x" C! z: \& d1 `$ N - while ( v23 >= 0 );5 L& |8 S& A( T7 n
- }" Q! Z$ t" C8 j9 r2 S% u
- }) J% S7 W% L+ [
- else% u1 D2 I( y' A& C$ w: N
- {6 `' q# ?: l |9 q. m( g
- v22 = 0;& ?" O1 R: A1 b% Q" K! N
- }
, F3 G) y! {" ` O& j6 M+ s+ U - *((_DWORD *)v11 + 5) = v22;
% V/ o& h- A2 H3 m# Z - SetRect(&rc, 0, 0, xRight, yBottom);
0 d* J: y: w" w* i" T, p - v25 = (HBRUSH)GetStockObject(4);
* n+ q4 {4 W( v - FillRect(v18, &rc, v25);
5 t( U4 Q& J9 j - SetBkColor(v18, 0);
4 F' y& }/ p5 a! a# N/ G - SetTextColor(v18, 0xFFFFFFu);2 H0 b3 h5 c0 ]% g
- SetBkMode(v18, 1);% a0 {! P' \ @
- v26 = 1;
9 r5 W! d1 d2 b+ J, W) t - v41 = 1;% X3 D5 d) f& K; F, P I; q! f
- v40 = 0;4 U! P! v5 c6 w3 j
- v43 = 0;
7 ?: S' ?$ I4 b' x ~- K( J& p* Y! N - if ( *((_DWORD *)v11 + 4) > 0 )9 j+ c8 W9 i9 [$ O4 P6 k' }3 W# r
- {
3 F' G0 _8 Y1 Z2 P - v27 = WideCharStr;% U; `, D! {; |7 i3 U
- v44 = 0;
. G, v' K3 W( N! h- l0 v - v42 = WideCharStr;% Y+ Q1 F: M% O Z& }& _
- v49 = (double)xRight;
' p( S# m! ?- V2 l' D- c0 ?2 X - v50 = (double)yBottom;! Z* E# @- \' f* M
- while ( 1 )) k, q7 O, J5 J! `2 h* |8 J
- {
& M V6 D+ ^; v7 ^, Q# v& V - v28 = v44 + *((_DWORD *)v11 + 5);
! F- t' T% b! ~- \! R/ p% w* Z - *(_WORD *)(v28 + 16) = *v27;
5 Q. P: l% } V5 G( Z8 H4 \0 M - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
; k: r9 z% u) a1 }3 i: m - if ( *v42 >= 0x20u )
& ^) Q# A; \$ Y- A* ^3 k) x1 |( A - {, ^7 R* J ?- Q9 }% M
- --*(_DWORD *)(v28 + 20);! ]$ \+ ~5 g! q1 C: Y. z
- *(_DWORD *)(v28 + 24) += 2;: j0 }! j3 g& q
- --*(_DWORD *)(v28 + 28);
8 _, ~/ A& }( T/ _. l2 ? - }7 A6 K. g, v0 g7 ~+ v
- else6 |0 ~9 i" o* }0 R
- {/ H- O! c! ]* {0 I8 n
- *(_DWORD *)(v28 + 20) = 0;
_- D5 U/ F3 D - *(_DWORD *)(v28 + 28) = 0;7 B5 P+ c7 I }& H, O
- }9 H* E# Q; w2 p- \6 m
- v29 = *(_DWORD *)(v28 + 24);
9 e( i* t2 g/ A: _ - v30 = v40;
) `5 D- _ Q$ E. F$ {; }; \ - if ( v29 + v26 + 1 >= (unsigned int)xRight )& Z8 C) ~. q# m, @# J k7 U: T
- {
, w! P5 j7 Y/ L7 j0 @ - v26 = 1;
! G! L# h$ i1 {+ M% |/ o- i. ]2 y - v30 = v40 + *((_DWORD *)v11 + 3) + 1;! V6 l- {* |/ y; X
- v41 = 1;
: {* k1 V! G$ H# z - v40 += *((_DWORD *)v11 + 3) + 1;
* f% k+ A- @! y2 d$ p - }
; T7 I9 }. t: |# h6 y, K" t$ ~3 S - *(float *)v28 = (double)v41 / v49;
3 W$ g2 G. Y4 R1 l& d, S! ], J - *(float *)(v28 + 4) = (double)v40 / v50;
6 Y9 O& F! T5 D( X$ S - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
9 P1 h. i; @, V - v31 = v26 - *(_DWORD *)(v28 + 20);* F! P3 t( C& U9 {2 a7 v4 u
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;5 `4 v7 I! C/ C, t- P
- TextOutW(v18, v31, v30, v42, 1);% ?3 i6 N8 V1 v6 n4 P+ O& [
- v44 += 32;- y9 S* W4 Z! v; n% P
- ++v42;
" @) w2 k4 Q- C _8 S5 D - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));# y. i+ C, u9 {9 V. C, s, x
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;! f6 g: Q- r4 L
- v26 += *(_DWORD *)(v28 + 24) + 1;7 v o ~& h p2 W0 y
- v41 = v26;
/ X$ v" Z3 l; r6 n - ++v43;
1 ]+ f2 f4 k0 q4 e+ G: p - if ( !(v32 ^ v33) )
, I: [8 U6 o" M8 K- Z! j3 } - break;1 j* R, e% N. e
- v27 = v42;
. h/ C" U8 Y; w8 G- f6 s# s% O - }: J2 [$ u* K& h3 y& s( E. ]
- }
! I" @! q/ |6 M+ ?5 g3 G7 V0 \ - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);( _, o+ k- e% W5 l5 b/ L2 n
- if ( v34 )+ {" Z, k' Y' w& \3 t6 F; o
- {% `1 s% I% ]- |' U1 h
- GetObjectA(v45, 24, &v51);
9 ?% Z% h: N0 n) q$ h, r2 n - v35 = v53;" ~+ H- Z+ S* {$ q; _& O
- v36 = v55 + v54 * (v53 - 1);+ n9 o; e+ G" d9 @: X( h* n6 u! \ P
- v40 = 0;; j6 {2 e! m6 ?- m; S( b0 _' h
- if ( v53 > 0 )
! v- P6 b0 F1 j0 q' h0 }# z7 t - {
* `, [. ]& g9 H2 O7 R7 p) v, H - v37 = v52;$ F3 K7 x5 L) }4 M) L) i6 Q: Q- _
- do# I: L, V* k/ W4 P
- {. r/ L0 Z8 I# z3 f3 R1 _# y4 {
- v38 = 0;9 A$ ~2 G, D. h/ w6 r8 j# t" J
- if ( v37 > 0 )
$ h4 h" T: }: b z# i - {
: p% D7 r/ S( q" D/ S2 J& G - v39 = (unsigned __int8 *)v36;$ k7 U! f5 ^7 ?8 }6 n p( w
- do G4 {" y5 j$ C' H: l) W
- {$ z6 u! L% w4 s1 _2 h6 N0 V, T# K! _
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
1 Y) f+ |# H _$ n0 @9 j - v37 = v52; p( W1 O+ @% i7 d; x) }8 K5 H
- ++v38;/ K/ k& O9 P+ Z/ L& l
- v39 += 3;; j5 V4 S- R1 u0 T. G
- }2 J/ S6 ^; h, Y
- while ( v38 < v52 );
7 u2 P8 \7 v. D6 ]) V! l - v35 = v53;
% E" L# |* N9 d+ y, d - }
A9 _0 n( K3 |6 |0 K - v36 -= v54;5 s( o, x% I& ^- S+ @
- v33 = __OFSUB__(v40 + 1, v35);) w/ }' G! X$ Z; T; g+ q9 P) h! A; U
- v32 = v40 + 1 - v35 < 0;4 t+ G7 Z+ J' k V
- v34 += 4 * v37;- t4 j8 o& c1 n( v- w2 v
- ++v40;
! |2 ?. [( I! H% ] - }
( y+ ?9 P/ D( ~+ o/ c! {3 r - while ( v32 ^ v33 );; I; a+ l1 _6 t8 g S
- }& ?/ s( ]! q! N$ m) U) q: ^- K
- }+ U3 D6 S# o! v& l% x6 N
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);" i5 Y/ \* e: z& {% a2 v* T9 [
- SelectObject(v18, v46);
G2 u0 Z9 Q1 F. t6 Q - VxDeleteFont(v48);* F2 b0 Q! { v
- SelectObject(v18, v47);
9 H; W# ]" ]6 x9 Q5 T) J" _! m - VxDeleteBitmap(v45);
+ k( U0 d- y$ a- `" f u! s - DeleteDC(v18);3 n3 U: @0 @5 v
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);# V' ?3 Z, _& p' A
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
0 P5 r9 j# a% g! K - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
* A/ u B- r% o+ Y- ?! I - return v40 + *((_DWORD *)v11 + 3) < yBottom;# r. R9 E) R2 t7 N7 Y
- }! j5 U: u& A! _! {% V1 |* `5 T
复制代码 & c& n3 c V3 [2 A
; ]0 g& p" j* `* z |