本帖最后由 shane007 于 2023-8-26 17:10 编辑 1 l6 U L6 C: [0 j8 x
|, x- B* k! R这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
) B: u2 B$ v6 \: ~3 y7 u用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
) y0 [4 [8 B+ c+ e! x6 u/ _+ s) t+ W# f
- # Type Name Pre-Call Value Post-Call Value
& l9 m$ V- F* c+ M" E& m0 ? - 1 int nHeight 0xfffffff0 0xfffffff0
3 b" l2 ?. i7 m+ B8 P$ W1 g - 2 int nWidth 0x00000000 0x00000000" y( Q+ k# ?! y, `3 D6 R7 ?% e8 ^/ H
- 3 int nEscapement 0x00000000 0x00000000
. R) I7 Y8 o+ v: ~( b - 4 int nOrientation 0x00000000 0x00000000$ a* n6 o7 o% Z$ C
- 5 int fnWeight FW_NORMAL FW_NORMAL( o8 Z1 S7 {- H% J* n
- 6 DWORD fdwItalic 0x00000000 0x000000001 b* t$ y* L5 V& Z* ]+ T
- 7 DWORD fdwUnderline 0x00000000 0x00000000/ t5 G+ G- E2 W4 C2 F! Y
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
' S9 N8 h/ {; P4 ~& m! ^ - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET- S" ?5 O" |7 T
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS. Y+ m# G8 r; N. V% _3 ?
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
6 S7 n" i/ O( K* M8 e' u& F6 z - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
3 F& s7 l' `4 a9 D - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
$ d# x* t5 v4 [$ |! [+ U- v" d - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"- W/ {+ p( j2 r0 D' N2 z7 A3 @
复制代码 : A/ ]2 m8 B( ~5 Q
3 v+ [5 }7 S0 _6 |# P7 z% [
用ida pro找到调用CreateFontA的源头函数如下。! M% {1 ] c, o: v. s3 ?( j v" n
从函数的参数可以看出,这应该就是字幕显示函数了。1 X# \* Y: A3 u: Q5 G! j$ l
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。6 k! g; T; y0 N
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。- C, P3 U+ ~$ Z: s2 v" v F8 y
- : w. A- U/ a3 T( H
- 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)
( @4 o. V9 h" I0 i - {
$ h8 c: \; }7 n( l' l) Q - void *v11; // edi6 {; Y# n0 T; s9 i
- int v12; // eax
" D7 D' w$ ^' P5 y7 r3 C - int v14; // ecx) _7 m& w/ c8 w1 f
- int v15; // eax8 H T' T% z; q, n$ E) b4 m& G
- char *v16; // eax/ Y8 S+ @9 t4 O% Q0 i
- int v17; // eax
% P5 }. O: a' [; p3 t - HDC v18; // ebp
/ |6 i9 z' K! i) V, a8 k! Y - int v19; // eax& F( R) U' A3 L3 x9 ]+ a
- int v20; // eax
: G9 ]0 f1 b$ ^: @ - int v21; // esi
# ^; \0 s$ i6 l6 C5 h9 }# ] - char *v22; // eax
, [' d: R! z& Y9 O Y# c - int v23; // esi
- f" [5 C7 b0 _ - int v24; // ecx+ b% d+ p/ b' D
- HBRUSH v25; // eax5 h! p' _5 ]. R* v$ B' @- D$ q
- signed int v26; // ebx
9 A a% y W- l& n - WCHAR *v27; // eax# d {' O$ g! q5 e5 h" K, ?3 v
- int v28; // esi
, B) }- }1 ?% P6 C& ?5 y - int v29; // ecx
* t. u3 E% y7 h3 t - int v30; // eax
' p, s, Q$ {1 w0 a/ `8 L - int v31; // ST28_4
: u; l# Z. w1 g# }7 E& ^ - bool v32; // sf
$ o) p1 \1 ?$ ^9 R8 O - unsigned __int8 v33; // of! t- A" B# [( u# K e
- unsigned __int8 *v34; // ebx
* S, s) _3 T+ i0 d _. }7 U2 ? - int v35; // ecx
1 V. `/ ?3 ]/ N1 Y) Z0 H4 u' f - int v36; // esi
: E0 B- D+ `6 h" `; K) f - int v37; // edx
$ M- u( k! A' I - int v38; // eax
0 I/ h. {7 {7 i" ?) f/ ^ - unsigned __int8 *v39; // ecx. g2 S: H" Y* S
- int v40; // [esp+40h] [ebp-2098h]1 R O) L; ~! `) N+ R) P
- signed int v41; // [esp+44h] [ebp-2094h]+ l7 P3 `/ F' R" y" B
- WCHAR *v42; // [esp+48h] [ebp-2090h]* Y0 M, A. `! c, ?) t! `3 a
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
2 s9 n" F- Q, r# B - int v44; // [esp+50h] [ebp-2088h]
" Q' {% U! L& X3 h - HGDIOBJ v45; // [esp+54h] [ebp-2084h]1 \4 x: a! I4 L+ f2 R
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
: O0 q2 |3 d+ |* [# _ - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
1 F' p8 i7 n( {$ b H& O' R5 _4 C - HFONT v48; // [esp+64h] [ebp-2074h]
0 w g5 @& J. w7 O8 v - float v49; // [esp+68h] [ebp-2070h]2 I5 [$ g1 S% j& Z! J3 y: g$ i
- float v50; // [esp+6Ch] [ebp-206Ch]' p9 k1 p) u$ Y1 u4 E
- char v51; // [esp+70h] [ebp-2068h]! D. m o" |+ x" o
- int v52; // [esp+74h] [ebp-2064h]& A7 ]2 L; W4 q/ `" r T
- int v53; // [esp+78h] [ebp-2060h]
/ e+ ~* V1 q5 ~; o! l' h - int v54; // [esp+7Ch] [ebp-205Ch]
, y3 P6 h% a. l) z: b' S( p - int v55; // [esp+84h] [ebp-2054h]
0 r) M: Y% H/ [3 U: X - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
' E; p. x$ _) e$ _- X$ ~7 ^$ t; v - struct tagRECT rc; // [esp+90h] [ebp-2048h]1 B& o! G( j- s) H' }% q
- int v58; // [esp+A0h] [ebp-2038h]1 n2 A* h. L4 E1 u" p
- char v59; // [esp+A4h] [ebp-2034h]! D' Z4 A4 \( `3 D% L" t. h/ A" D
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]5 E3 J0 j( O0 G' X$ L
- ! ]. Y/ d3 o& a' I
- v11 = this;
) h* {/ I3 ]3 D& s5 p$ [' U - v58 = 52;* s0 w0 F0 x( u* e ~+ O
- memset(&v59, 0, 0x30u);7 B$ X" ~5 t4 Z6 I% E/ Z
- if ( *lpMultiByteStr )8 y A# L9 A- u* ]0 O f; D
- {
$ n. e5 C% | A9 p: n5 { - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
( M# |8 J3 G: K" }- k( L - *((_DWORD *)v11 + 4) = v12;
6 u* N, {) v$ ? - if ( v12 <= 1 )
) q2 |9 ~$ I6 j) Y$ y a1 b - return 0;
$ o! ?- l5 F: H/ t5 c# A - *((_DWORD *)v11 + 4) = v12 - 1;; @9 v% o) x9 o) ~7 N
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);9 h' e0 x; [2 p# Y. w3 c4 A
- }
9 w& x% }4 l& ?9 C2 E8 D - else8 r% F; X% E. o" a( t u
- {
0 T; I4 L3 \" r) @+ F, s - *((_DWORD *)v11 + 4) = 352;: d( p- ?9 O' [
- v14 = *((_DWORD *)v11 + 4);1 ^& M) a. y1 L% E$ t0 F( W
- v15 = 0;# v. B* m- g8 h9 {' I2 F- P2 h
- do# x' }! F- m4 b. u1 i6 o9 X: F
- {3 ?# z. c' n; N$ Q
- WideCharStr[v15] = v15 + 32;
3 \1 C7 z+ W& J2 m - ++v15;
: q; T; a/ p* g/ q+ n! h# ~ - }- a2 X* k: l' c. a/ K
- while ( v15 < v14 );
+ p* e* B0 G& {3 j9 Q - }
( D5 c t" E8 ?# j2 U( Y - v16 = *(char **)v11;$ S: A) z$ ^/ k1 z& h1 ]! t
- if ( !*(_DWORD *)v11 )5 y8 \% V! n' i1 L5 o
- v16 = byte_100B2D6E;! }2 l/ j: T K8 S
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);* c( R, e, R* W4 l
- *((_DWORD *)v11 + 6) = v17;
; n& I+ O' w4 n- r' s - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )+ R/ y3 @# c$ X* N3 _& ~# S
- return 0;' W$ c0 j$ ^1 e2 }% `7 D4 l# O
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
9 O2 H, o! c: v$ e! f3 K) T, t - v18 = CreateCompatibleDC(0);7 ]# ^ L9 G9 C
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);; O! ~- Q: P: Z4 \9 Z4 ^
- v47 = SelectObject(v18, v45);
1 u9 P' ]% M% x/ l - XString::operator=(v11, a3);
% A: r& j! ^7 C2 e T) |( h - *((_DWORD *)v11 + 2) = nNumber;
- L0 E" i% t! {( O& |/ ^) [3 @7 Z - v19 = GetDeviceCaps(v18, 90);$ [) b) k& C/ U& R" ]) X$ d
- v20 = MulDiv(nNumber, v19, 72);: D8 v& i3 ^$ Q- K9 K! }2 g
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
& T1 B9 r) d, i @3 g - v46 = SelectObject(v18, v48);" _( N, k% ^# T5 `: E, H
- GetTextExtentPointA(v18, "A", 1, &v56);
9 B# A6 O! E) h6 R - v21 = *((_DWORD *)v11 + 4);; l; |* H; f' H0 U r
- *((_DWORD *)v11 + 3) = v56.cy;
! u$ s7 b: J/ h ]& E - v22 = (char *)operator new(32 * v21);. M7 J; D O& v5 N, x
- if ( v22 )
. l# d; O7 A5 C( T+ r - {: ]6 O8 _$ h' C! |# B' l# l" L/ p
- v23 = v21 - 1;* {7 b8 }. B, Q6 q* c
- if ( v23 >= 0 )
* V4 g8 {3 Z: M( I* ~+ y! b- H3 E0 ?$ p - {
: m( P* v8 a+ }2 P - v24 = (int)(v22 + 12);
! \( _9 t s: q- p9 Z. o( I( ^ - do# v. @" ^( t, B* F+ s9 m( Y
- {
, J0 Q5 W/ _) v* V. i" m4 z) S. _ - *(float *)(v24 - 4) = 0.0;$ d* \7 z! j* h- q3 `+ W' l0 Q9 G
- v24 += 32;, C& V3 L' j& l; T
- --v23;
4 n( N8 n" u1 T) I+ |+ Y- y - *(float *)(v24 - 32) = 0.0;. ]: U! ~& o, m: `
- *(float *)(v24 - 44) = 0.0;2 e' E2 H6 }9 t
- *(float *)(v24 - 40) = 0.0;
% o9 @+ {$ h2 k! h1 B. c8 w - *(float *)(v24 - 36) = 0.0;
, F, j1 q( q- n, d, m& ? - *(float *)(v24 - 32) = 0.0;0 n4 c; [# Q* t
- }0 j9 d. w! s& I/ |$ r
- while ( v23 >= 0 );4 c4 G3 {$ h6 R+ k* s
- }4 L! {. V+ C1 E* K( c k& D
- }
: }5 {3 V! k6 K. h - else
- X5 b( N) m$ T" w* \5 c O - {4 L- M# r5 O c& U1 x
- v22 = 0;
$ V9 }' T9 j7 b" w1 D) R. ~" [5 I - }! h- B5 ]: q( g: j% m
- *((_DWORD *)v11 + 5) = v22;
" C2 ?* b0 I5 \+ ~& l - SetRect(&rc, 0, 0, xRight, yBottom);
5 B, K0 Q i' v+ R; s6 |& j% I - v25 = (HBRUSH)GetStockObject(4);0 r; T7 i0 N0 P" x; j) [
- FillRect(v18, &rc, v25);
' z2 S6 q1 K* O/ Q" U2 w' ] [ - SetBkColor(v18, 0);
2 j$ {3 Q! H" I u% i+ a1 I - SetTextColor(v18, 0xFFFFFFu);
+ x3 P0 x8 c' w/ y8 ]' {1 ~ - SetBkMode(v18, 1);
" a/ H2 X o# s! B4 I - v26 = 1;
[1 a$ y$ \* n+ Z2 u6 G - v41 = 1;& g7 M3 A) w5 g9 p5 T3 Y- [
- v40 = 0;
2 [ K5 ]0 T! ^, I6 _. C! p5 x9 H" H - v43 = 0;
( W2 P4 T9 p8 l5 k - if ( *((_DWORD *)v11 + 4) > 0 )
( g. C7 ?3 p, m! N: k+ J - {2 {, S; |/ H2 G4 q4 A
- v27 = WideCharStr;
* C! U0 f. ~8 V0 f; J2 u - v44 = 0;; C+ _* c* s$ y0 o! [8 g
- v42 = WideCharStr;
+ u! B$ G& k6 q! [5 s: k - v49 = (double)xRight;% J/ p" I1 Z/ B* g* g" P
- v50 = (double)yBottom;
$ ~9 h L2 ?3 Q9 @8 L& U* Y - while ( 1 )- S/ ~2 d& v3 h6 B- p
- {
) i" ]- p% K6 @$ r+ ?7 i. K - v28 = v44 + *((_DWORD *)v11 + 5);
8 z. v- @9 H! T: G! u& L) w - *(_WORD *)(v28 + 16) = *v27;
6 ^0 R6 x% K2 v+ |/ z, ]( m - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));' S7 I+ k% c- {9 x
- if ( *v42 >= 0x20u )
8 w, q: c, B f - {
7 L+ `6 `$ Q' u: ?8 G9 @8 m - --*(_DWORD *)(v28 + 20);
: z6 w" r, I# [- q - *(_DWORD *)(v28 + 24) += 2;
4 m$ w; z% M* u0 t. N - --*(_DWORD *)(v28 + 28);, q4 U% r/ Y3 l
- }
2 g5 ^ N* V' A8 P - else
' ? a5 [! ~2 x# W2 l$ ^ - {9 B, H: I& d5 J8 k
- *(_DWORD *)(v28 + 20) = 0;
5 |; _2 j4 E4 ]+ Y1 o - *(_DWORD *)(v28 + 28) = 0;% Q9 b) I( s4 t- M- e+ q
- }
7 R- X* @( u2 `/ j - v29 = *(_DWORD *)(v28 + 24);
* \: I( l( Y8 X: H- q9 N& f - v30 = v40; o( p1 B/ n5 a
- if ( v29 + v26 + 1 >= (unsigned int)xRight )
8 H) `9 T4 ]9 w+ b5 y L - {
# d$ A( T" B) _1 ] - v26 = 1;
* L8 v) J! v% a& V3 w9 L) Z3 O1 M - v30 = v40 + *((_DWORD *)v11 + 3) + 1;7 R# a4 ^- N3 g0 L# v
- v41 = 1;- T0 |1 D4 @- v* V: ?. d
- v40 += *((_DWORD *)v11 + 3) + 1;0 r* p6 {2 N' q" ^- f
- }5 O8 k; ?- k! y: H3 A, z
- *(float *)v28 = (double)v41 / v49;+ {0 r9 p$ z/ ]+ `
- *(float *)(v28 + 4) = (double)v40 / v50;
* Q: F5 S& t) Z- b$ ~ - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;7 Z) g( b1 z. P% c& G
- v31 = v26 - *(_DWORD *)(v28 + 20);. w7 ]% c/ ?, r: O/ K
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
/ u6 ?7 \' b3 N# q4 J1 o - TextOutW(v18, v31, v30, v42, 1);1 S+ J$ K) y, W' Y) @$ I4 Z
- v44 += 32;# k; M& G- S x# Q9 F0 k
- ++v42;8 s- H- w( z; L2 E5 p* }' Y
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
/ E9 h% `3 y2 a: X* c5 B2 M7 j* n - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
5 N0 Y! U; O$ w7 l/ D - v26 += *(_DWORD *)(v28 + 24) + 1;2 I. [) l( E; M! S: G
- v41 = v26;: e+ `. y! ?* R" v9 n, K" W& C
- ++v43;
+ F( h1 [7 w# n: @# D# P; P - if ( !(v32 ^ v33) )1 w! u% ~) s3 G) X9 ?
- break;
6 Z3 W) |2 ?7 c$ l7 C! C4 N) h' k: C/ f - v27 = v42;
- S' X- p/ E4 D& _( M - }
( r5 z4 o+ w+ K c* ?/ X - }* h* m1 m- m$ u- v& m) T; D, T0 I
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);" I7 l8 x% Q% r( b9 q0 N
- if ( v34 )
, x% u) V! i6 @ - {; }; p8 H. q, M0 P0 o
- GetObjectA(v45, 24, &v51);
( ?4 _6 i5 X e! ]% m# [1 x, L8 o7 Y. b - v35 = v53;
( v+ e6 d7 Y3 T4 W# F - v36 = v55 + v54 * (v53 - 1);
( t2 @, A9 g# _ O H - v40 = 0;
* i% F. `" X1 d! F - if ( v53 > 0 )
, i! v7 w) C3 x$ E& U" N. H - {
t, Q- R& n3 L: S* m, g6 Q0 C - v37 = v52;8 ^2 Q' q& `' i: Y, D) D
- do$ ~8 a) \. }, h/ y
- {
$ a9 B- ~6 _$ L3 b - v38 = 0;4 S* J5 y8 _7 o2 b9 O
- if ( v37 > 0 )
+ ]7 `9 g6 y- {9 S h. q% h - {
$ ?# U3 ^2 F) A; `4 f - v39 = (unsigned __int8 *)v36;3 A0 d0 i9 r/ f, Z
- do. ~& Q4 d8 i l; @8 f& T: d7 q. n% z
- {
2 _3 c6 i8 _. N/ n - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;; ^3 J3 F& b l& m7 N8 X" I
- v37 = v52;1 \) T) y( `! ?
- ++v38;
, u* I9 E- f% z9 r6 Q - v39 += 3;
, o8 b% L& k7 R+ t3 r+ J) a, i - }
3 a) E0 [: O: y. o! ~- N1 G5 }( j - while ( v38 < v52 );! M7 i2 c n* X$ F/ w1 g. g9 n
- v35 = v53;
' D% Z- }/ r# r I" o - }
5 [- r. j* Q2 K" `* F/ r5 C2 F' D - v36 -= v54;6 m: z- F n3 R/ e
- v33 = __OFSUB__(v40 + 1, v35);8 J+ Q0 Y' F$ h( s1 Z- ?+ U
- v32 = v40 + 1 - v35 < 0;# E/ x' e. A& V
- v34 += 4 * v37;
m0 l5 P3 F* X2 P/ Q: x, Q - ++v40;# c8 x8 f2 G4 Z* L9 I! D) h
- }
- O7 {6 _" a3 z- l; }$ z" F - while ( v32 ^ v33 );
5 m/ P- r, x1 j - }
+ Q* A% x1 Q) | F$ L8 U/ `2 | - }2 {6 k# a0 Z7 y4 F" o& e
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
8 K) j/ B) w% W) }" }" \ i - SelectObject(v18, v46);- D7 x5 o* f! Q" N, e, [
- VxDeleteFont(v48);; |: C% ]# X" U: c2 E q7 ]
- SelectObject(v18, v47);: p4 N1 e6 I: r+ N
- VxDeleteBitmap(v45);' |/ T: Z/ U1 S# h |! q6 K
- DeleteDC(v18);0 V7 y1 Z" }& `
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);8 ]9 _& S* P+ K% e' Z v
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);4 }# `) G0 ~2 z0 v1 Y+ R2 S4 Z2 ]
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);) e$ |9 K3 w, T* ~
- return v40 + *((_DWORD *)v11 + 3) < yBottom;! v' g$ S; x$ f8 H% r# P# v
- }
7 q5 A2 k+ V7 h
复制代码
# s; u1 G( Z4 A1 U# z0 N) U# P! f; G" \
|