本帖最后由 shane007 于 2023-8-26 17:10 编辑
: h/ f7 I) j+ |* ]
) A' b7 U# Y# v3 `+ ^% E0 K这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。* y$ ^1 \) k$ P( G- F; F8 Y( w' ]
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
/ ^& D+ `9 p: _8 K9 X+ R
( ]6 x ]6 }/ o# z& I x- # Type Name Pre-Call Value Post-Call Value
5 D' v8 E6 R; ]! @7 V - 1 int nHeight 0xfffffff0 0xfffffff0) c* { K( i& X+ J
- 2 int nWidth 0x00000000 0x00000000
o) {: o+ l: N; z - 3 int nEscapement 0x00000000 0x000000003 L v* {3 Y# U1 D3 z4 E' f# N. Q
- 4 int nOrientation 0x00000000 0x00000000
% f& k; f# ~' r: S' { - 5 int fnWeight FW_NORMAL FW_NORMAL
$ r5 q) Q) p# k8 E6 W - 6 DWORD fdwItalic 0x00000000 0x00000000
% E' A6 `+ O* w2 A - 7 DWORD fdwUnderline 0x00000000 0x00000000
& O) Q2 C' C% { w# J! p& P5 Q - 8 DWORD fdwStrikeOut 0x00000000 0x000000002 @( P: _2 m/ j
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET' e# K" L; b! q2 d7 S' G! ?4 q
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS, f/ @; B7 A5 ]9 _" P6 e7 k
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS& T6 T- ?- t; n. e
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
4 C+ V6 ~" v) b. C0 _ - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH! w) p) @6 Q$ N4 [5 m/ o7 F
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
% @* \1 {5 Q9 D3 k' {
复制代码
2 ?- @0 _' Z* `& s
+ c, s8 d' H) e; V用ida pro找到调用CreateFontA的源头函数如下。
# ~8 e0 J+ R- [" U) r' l2 K4 q5 y9 W从函数的参数可以看出,这应该就是字幕显示函数了。
2 T. ?8 [+ E+ `" J& Y) S- s# V关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。1 s4 R. i5 b5 e* u/ W
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
: Q$ v. W$ v5 o8 U- + z+ P2 U, I7 W" ~" f" F, x
- 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)
, {7 e. ?# z: \ - {
9 l) z8 w& n3 q& r6 G - void *v11; // edi4 X; v0 N. L) Z3 M
- int v12; // eax
5 l+ B4 y& R/ e - int v14; // ecx
: b( y+ ?" s" @5 p$ O$ w, n - int v15; // eax
! |9 ~/ \/ ^# E4 ?6 ~ j - char *v16; // eax8 `; U0 G- x' s; o/ k" z
- int v17; // eax
d ?. u4 X2 r0 x0 a8 R - HDC v18; // ebp
" f% p8 T! ^# g6 x- V - int v19; // eax
" F: k, H# h* Y% H3 P% V - int v20; // eax
- p1 A4 \# Z! C - int v21; // esi% J/ b; j) U% S+ v) |
- char *v22; // eax+ Z# B; s/ M5 b1 [
- int v23; // esi
7 u7 T7 M7 g1 ?1 P- B @ - int v24; // ecx
9 P0 h& F7 B2 } Y) M - HBRUSH v25; // eax
% P) h/ l3 _4 w4 a& o5 E - signed int v26; // ebx
4 m/ |" y& j, D. Z- D# @7 v$ V# j - WCHAR *v27; // eax
! R) f. i; V9 y9 E+ L+ \ - int v28; // esi
/ j) T' r4 o" X6 ?9 w6 m - int v29; // ecx0 e# _! u0 p6 d4 y* k/ F* ~2 u
- int v30; // eax
: `9 q0 U7 G, a- z* l4 J- s - int v31; // ST28_4, J8 `: `* `" @% J# C$ `9 P" U. h" R
- bool v32; // sf
; M! o m" B/ }9 X% j4 ?& r - unsigned __int8 v33; // of& t& m8 k( B* R! Y2 e7 ^$ J
- unsigned __int8 *v34; // ebx
! i S- }3 y8 J/ k - int v35; // ecx
& e3 o2 }# g' q& k - int v36; // esi$ B2 q8 G2 y* g0 S; k4 b+ q2 Q+ L
- int v37; // edx
/ @! e) n7 T l* M - int v38; // eax
5 S2 L' g, e9 W: |4 F X/ d( b3 m - unsigned __int8 *v39; // ecx9 F) D( {4 t4 |0 o
- int v40; // [esp+40h] [ebp-2098h]
7 P9 M6 p2 b4 y. y - signed int v41; // [esp+44h] [ebp-2094h]5 w/ l' J% M! Z5 j' ?& q
- WCHAR *v42; // [esp+48h] [ebp-2090h]8 r/ ?4 t" P, c
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]7 G+ z# V% L y5 D. E) j& s
- int v44; // [esp+50h] [ebp-2088h]
, J! \8 p, v8 A T - HGDIOBJ v45; // [esp+54h] [ebp-2084h]7 u2 V5 l: q+ e: y! Z9 ^9 J F
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]7 q! @7 J4 b1 ]: V: [, R4 r: T
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]
( V1 y9 n8 s: K, L0 [2 F! b. r7 n - HFONT v48; // [esp+64h] [ebp-2074h], k; l: P. U2 y; g0 B, F
- float v49; // [esp+68h] [ebp-2070h]
! X" J0 x" M& F+ y5 }( Y0 k - float v50; // [esp+6Ch] [ebp-206Ch]% z2 @+ }2 l8 X8 a+ z% ~
- char v51; // [esp+70h] [ebp-2068h]
: k) [: ^+ G9 z; a q/ b2 S - int v52; // [esp+74h] [ebp-2064h]& J: J' }7 N# g9 q( k
- int v53; // [esp+78h] [ebp-2060h]
4 M0 s) t" g7 H# Z) ]# @ - int v54; // [esp+7Ch] [ebp-205Ch]
( T0 x7 S; Q7 g! C$ k; S2 Y - int v55; // [esp+84h] [ebp-2054h]
( N$ B; R. f9 S: o7 y8 X7 D8 S - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
6 j' a0 E9 X% j: B( f - struct tagRECT rc; // [esp+90h] [ebp-2048h]5 v& H! b+ P1 T2 S2 c6 F- d
- int v58; // [esp+A0h] [ebp-2038h]
( n: t3 E5 h. M7 Y' T# z7 X - char v59; // [esp+A4h] [ebp-2034h]' t% o* K4 g: B) Z4 {+ n! ]* i8 [9 K
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
2 ?) C6 g, a, U7 Q0 p) L( s - 6 @: N' E& I4 T8 x' C0 Y. {, @! E$ B
- v11 = this;- w9 |; \! o9 F9 Z- ~
- v58 = 52;7 h4 a" J$ g( i& S
- memset(&v59, 0, 0x30u);
. U- t" {+ }/ b: x - if ( *lpMultiByteStr ) i6 l+ i7 a A5 W% x. f2 Y6 c! P; N. U
- {
* H P( Z# r4 l3 z1 j - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
6 {' Q4 i% l A. V4 d `5 F - *((_DWORD *)v11 + 4) = v12;* ~, [3 \, y) |) j& M
- if ( v12 <= 1 )
/ k# a" t2 M- V" C) O - return 0;
& t F* Y# Q+ [" X1 l - *((_DWORD *)v11 + 4) = v12 - 1;
& }+ R( F( M' B/ z5 n - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);3 x" g% `" a4 l! Q* r# ~
- }
3 T8 c1 u, W) e6 w; Q - else
* M1 z, X8 K' p: Q - {7 M% |% O- Y/ u$ i
- *((_DWORD *)v11 + 4) = 352;) d5 ~4 K" O/ p T2 N# j
- v14 = *((_DWORD *)v11 + 4);
. }3 R7 F+ o+ y6 t( V) A - v15 = 0;. H& H* r# ]% B5 u* K
- do
0 M/ b: g0 c! u7 @# w - {. l5 r# z# T0 b7 m! V/ }
- WideCharStr[v15] = v15 + 32;
5 ^8 Y- m+ n, W* d5 R; { - ++v15;& T8 K v$ K3 a7 |& a9 Y
- }
' m$ z3 V& l( B: C: g - while ( v15 < v14 );6 I- J* K3 |1 E4 S% h! q
- }
; v, d8 x$ e) z - v16 = *(char **)v11;9 g# D( D( g& e% P4 U. X7 B! D/ v
- if ( !*(_DWORD *)v11 )0 z! e* O' F* X# }- _# r5 }' Y
- v16 = byte_100B2D6E;; }* t' a# c* b- b2 i
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0); \' K0 ^8 @ t, W
- *((_DWORD *)v11 + 6) = v17;
- u" \6 _, G8 Q% P9 E0 z7 q - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )2 p0 U7 w5 @7 c
- return 0;
1 S, n7 S2 E3 h0 _ - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);/ ]0 ^- y2 @5 G( ~
- v18 = CreateCompatibleDC(0);
) N/ w$ s! v% g. r# q, n - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);0 u+ u* c1 u y3 x0 u7 L6 @
- v47 = SelectObject(v18, v45);
! U0 b1 h. t3 `- M2 Q5 R+ w2 T! U - XString::operator=(v11, a3);( p7 B1 w( o5 o0 L6 Z V; c, A
- *((_DWORD *)v11 + 2) = nNumber;* ~5 N8 q* R3 `7 ?# S/ n
- v19 = GetDeviceCaps(v18, 90);
4 L* p3 W2 F+ A - v20 = MulDiv(nNumber, v19, 72);
) B$ _( F& Q8 E0 {( D - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
. L) a! U& I& ^4 Y2 d - v46 = SelectObject(v18, v48);7 F E' }! E) i( U3 t. W% I, {$ Z
- GetTextExtentPointA(v18, "A", 1, &v56);
" g# A, h1 s ` - v21 = *((_DWORD *)v11 + 4);. m$ u% k7 D0 o6 H, t- w
- *((_DWORD *)v11 + 3) = v56.cy;( ~% [& w, W- l; t3 ~6 `
- v22 = (char *)operator new(32 * v21);
. [- U" o: _# Z. [6 N" N - if ( v22 )8 w2 Q( U9 Y/ H. G' Y# L" C
- {, W" Y& s6 j# n- s; }4 M/ t+ H
- v23 = v21 - 1;' U% n- H0 W% C6 m
- if ( v23 >= 0 )6 G/ E* d8 s u5 h
- {( J* {2 `* I7 I
- v24 = (int)(v22 + 12);
4 l+ J" x2 S6 p5 L7 [! O+ |& z - do" s1 G w+ a# @# O7 S
- {
& M2 ?: u4 Z. ?5 M: F$ T; V8 j) r - *(float *)(v24 - 4) = 0.0;
; l- K6 C( U- ~; O5 t' s$ o! r - v24 += 32;& B- {' A3 J! l( ]+ R
- --v23;" F5 z, c/ i2 p4 M
- *(float *)(v24 - 32) = 0.0;
: B' Q: k0 J7 U. b. t! O - *(float *)(v24 - 44) = 0.0;
1 ] Y- j! |: n/ H; V. }' F - *(float *)(v24 - 40) = 0.0;
/ M9 D# Q! U1 U; D" A8 [ v - *(float *)(v24 - 36) = 0.0;
* A: _ S9 w- s4 ] - *(float *)(v24 - 32) = 0.0;/ b- O7 z0 f; k5 c2 v: G' Z* I
- }0 n+ Q, m) [+ f0 j! ]9 R: |$ P
- while ( v23 >= 0 );1 e. }9 M/ O: x9 I( n5 |
- }
% Z- _7 G# G9 U$ `& p - }6 [) i/ ?+ U6 @) T! R
- else
2 i* m4 p/ C! c - {8 X: O5 P7 F. Z! i+ e, R0 R! L
- v22 = 0;3 X8 X- ~/ l5 ?4 m. p
- }0 e) ~, T) P9 e$ h: e( i
- *((_DWORD *)v11 + 5) = v22;% h% U& ?' m% V( J7 [6 f5 `3 l1 A
- SetRect(&rc, 0, 0, xRight, yBottom);& _ a" W# b: w# [
- v25 = (HBRUSH)GetStockObject(4);$ U# _* ^. P6 r0 a( b
- FillRect(v18, &rc, v25);9 v' ~8 c2 n& L1 i
- SetBkColor(v18, 0);& w: {- x' a& p, c G" b
- SetTextColor(v18, 0xFFFFFFu);
" T" I) E8 |# }5 g; P1 P" C - SetBkMode(v18, 1);
9 L9 ?& R2 w8 D - v26 = 1;1 H5 {, `" d2 {6 P% k/ j0 v! p
- v41 = 1;
6 P& }, J2 S( F6 A Z - v40 = 0;
! I# W. l( B& W/ ], l - v43 = 0;
6 {' d+ c0 H- L/ F/ _ - if ( *((_DWORD *)v11 + 4) > 0 )
n; T# Y1 z3 [ - {& F( i0 x% W' m6 U6 h: l
- v27 = WideCharStr;
0 j4 K/ |2 @' i& A - v44 = 0;+ T& t$ `" J. t8 m: e
- v42 = WideCharStr;
* r$ o5 b8 R% X/ u ~7 i4 Z - v49 = (double)xRight;
6 d: p( a+ f' r X4 N8 X7 [; I+ [ - v50 = (double)yBottom;& Q+ r3 I& A. B' |+ p
- while ( 1 )4 z2 ?5 W. A( g# H* y
- {, O0 \6 t# Z. W7 a" F" Q
- v28 = v44 + *((_DWORD *)v11 + 5);! m4 r& Z6 F `) ~
- *(_WORD *)(v28 + 16) = *v27;
- Z! ?4 ?2 \7 Z$ N. f9 ]1 p( P - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));1 X1 k! D0 E$ J1 n& k# a
- if ( *v42 >= 0x20u )
, f* v3 d) D6 Q N( ]8 C - {
" b0 p- L! S* u9 E - --*(_DWORD *)(v28 + 20);- D6 v9 L5 s& p `$ S. T: g
- *(_DWORD *)(v28 + 24) += 2;" `# T, h- p$ ?3 d; g
- --*(_DWORD *)(v28 + 28);! H* c# v6 Y2 G1 E0 v
- }# s! N% M& E7 ~9 `
- else. T' V9 d( b6 \7 ^+ y: L9 ?
- {
4 y0 _ C4 G( ~. i9 X. D - *(_DWORD *)(v28 + 20) = 0;% r2 h4 @8 k0 b1 z. z# C
- *(_DWORD *)(v28 + 28) = 0;. D0 }$ |" q! w$ j' _( a; _
- }
% b1 v' ?9 W' l: p - v29 = *(_DWORD *)(v28 + 24);
6 e& W% L# x6 _! g2 y+ X - v30 = v40;
! m$ D- w5 c- y - if ( v29 + v26 + 1 >= (unsigned int)xRight )7 d2 [! h6 S6 w. k$ x
- {
! c! O4 S' A4 `) `& z - v26 = 1;
6 k8 Y# |6 `6 b$ F( ? - v30 = v40 + *((_DWORD *)v11 + 3) + 1;
' a, Z9 V# C" \5 |5 J% K - v41 = 1;, c, I& Y* e3 @+ `4 W1 E
- v40 += *((_DWORD *)v11 + 3) + 1;
8 r/ h/ P& _( K7 \. ` E( b4 ^/ c" Q$ O - }
! ?" j2 j! ^& M* X( q - *(float *)v28 = (double)v41 / v49;
( B0 z/ P+ e+ y" |5 E - *(float *)(v28 + 4) = (double)v40 / v50;
' b8 Z) J$ F8 |; o, ?# e - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
" _& p' ^( @' z - v31 = v26 - *(_DWORD *)(v28 + 20);3 b* ^! m1 B$ J6 c- l
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
& A2 W% s9 i' U1 y- M H - TextOutW(v18, v31, v30, v42, 1);6 ~' I3 o- ]1 k: } M' x
- v44 += 32;0 b; T9 s3 x; e
- ++v42;
* H; G- c9 n/ ~8 v- V8 F1 B - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
) d9 K: H5 p- A- G2 W, k& v - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;0 s; q% Y: u* B% U; ?
- v26 += *(_DWORD *)(v28 + 24) + 1;. ?' ]$ o+ @* Z5 L* |) q4 k: c U5 B
- v41 = v26;
6 i( B; j [ S- B2 c7 A - ++v43;- {8 k. d% G/ W2 V( T
- if ( !(v32 ^ v33) )
& t. _8 \3 j. F% @# m' h - break;8 ]! B! N2 X; S) p. `& y4 A
- v27 = v42;
& ]! S5 H8 D' A& T - }
7 Z# s/ H- y5 L- _9 @ - }
! N' x5 c: e! m7 s2 F D - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
3 u9 T1 w% n4 X# k! C3 K - if ( v34 )+ F' S, p0 c8 b, |* ?. G6 C/ Z
- {
/ N' c& z' T2 s4 G! k - GetObjectA(v45, 24, &v51);
+ [( p9 \) Z$ g9 M. @ - v35 = v53;
$ _& F7 X) p4 \/ ?7 h# f8 R e L - v36 = v55 + v54 * (v53 - 1);1 r# n7 R5 }' d! d/ R/ U1 |7 ?+ b+ l
- v40 = 0;
( h8 b$ a5 k( H* j, u, U - if ( v53 > 0 )
v" Z9 m& a7 C) n/ n6 C - {
; E2 W( f) ?4 F. V/ N4 h - v37 = v52;' |. B) y; B3 C/ z
- do
! Y( r* d2 k; Y- B8 v - {. B! K0 o) w0 q4 d
- v38 = 0;
! U9 g2 t% v! m: F$ G5 m - if ( v37 > 0 ), \: l; x5 v/ }% k' x
- {% Q/ C# {5 W" W* B" M
- v39 = (unsigned __int8 *)v36;
L! g, F+ ^8 P - do
- a* M( P2 [/ N: Q/ _* V - {. q* I! G; n7 j N
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
; t! W- T; h9 l: v" o' D% e+ N- { - v37 = v52;- k5 n; R9 }( b! r6 f; M
- ++v38;3 F! L1 D# p4 E4 d7 [
- v39 += 3;
5 n+ v; a6 ]4 I0 Q6 ` n - }
; b- [) V7 y* S1 T. r$ w2 Q - while ( v38 < v52 );4 s5 r# G3 i6 j
- v35 = v53;6 ?; S. k Z* n ]$ Z1 h1 f$ t U, k
- }
: w: h" E# F3 F - v36 -= v54;) J4 n* j( j2 T5 F
- v33 = __OFSUB__(v40 + 1, v35);
* K" K* X! x) _5 w- D% c8 A6 I - v32 = v40 + 1 - v35 < 0;3 V v' X0 _! n4 T3 B6 _4 V
- v34 += 4 * v37;, X7 Z4 d( d0 g. F' D' w
- ++v40;' s6 D6 Z, _* G$ F: [
- }2 g2 Y$ A3 N8 H) S) f: y
- while ( v32 ^ v33 );! _6 \$ o& a {+ ]0 F* z
- }8 ?9 R# h' c" n! u8 O
- }
4 e! ^" W* i" |' h, A- z - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
. U1 t$ `4 I9 M3 ]' J5 u - SelectObject(v18, v46); p8 i/ e$ @+ ?( @& y
- VxDeleteFont(v48);- G" l) F3 V: G+ R7 S2 T7 u3 z
- SelectObject(v18, v47);
5 j% k! y2 `0 h$ K3 { - VxDeleteBitmap(v45);& y# h. U6 [1 g' h, `8 ]3 [7 y
- DeleteDC(v18);
, \" @: }3 I% R) U8 h - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);0 V8 Q9 y1 @, w+ f6 s0 p
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);! K4 N0 _; m% @8 k/ V
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);' w" Z4 y/ J# _3 |" |9 M. G
- return v40 + *((_DWORD *)v11 + 3) < yBottom;: u8 Q4 B3 [6 {6 {8 E
- }1 b: c. d! ~0 Y/ g% s
复制代码
7 {- n5 _' i6 n1 i3 R. I' s6 \ I6 Y% R+ z: S7 b
|