本帖最后由 shane007 于 2023-8-27 10:49 编辑
( ^# k. M& N& l1 p/ a) p1 o
6 s `' W+ ~( W) N" g( C这个游戏是opengl引擎的,对opengl的初始化主要是在vision71.dll里做的。经过grep文字检索之后,确定这个游戏没有调用 glGenLists和glCallList这2个函数来用于字幕显示。6 Z9 }" M, l& u' `6 T
8 f' j9 x- S) h1 `dxwnd窗口化之后,用cheatengine 检索内存字符串(注意,有的字符串在内存有2份,对后1份下断点才有用),
, N* _; i( ^/ u随后下断点。在以下地方断下。
/ Z4 j& x6 g$ {! ^' L' H- O+ H2 I4 J
- Operation Wintersonne.exe+CE883 - F3 A5 - repe movsd
2 r( `7 q% o8 O5 i/ G - 004CE883
复制代码
9 I" x7 Y* m$ m r
! w; D+ ~# X+ j3 |用ida pro查看之后,发现是个底层方法。3 G- ^3 M9 k9 P$ E) [: i6 E% C, h7 d# b
真的显示函数应该是调用它的上层方法。
- K' a" U: S1 A. n5 o- void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)
: B- _; n" v2 G3 u
复制代码
- v; N1 d1 o# Q/ b$ `; e, E( A- y6 s7 G& k9 j6 ]
这个方法看着蛮像的,也许就是它,待日后修改代码测试5 O! O: ~0 W, j; [
/ L2 z; c+ e% N9 }
' Q7 D* Q# W. ~" o- int __thiscall ATL::CSimpleStringT<char,0>::SetString(_DWORD *this, void *a2, size_t a3)2 D# a; o8 m( B# f
- {
5 `& u3 m% I( G, _' c - unsigned int v4; // edi. ]9 U7 m/ z3 ? A# U$ o6 {
- char *v5; // esi4 r/ }: q, v: ^' l5 j, W; Z
- void *v6; // eax4 c* m0 \( N& t& V+ S6 e/ U
/ v U+ h l) O4 a/ P" g' p, D- if ( !a3 )8 K5 \( H4 L/ x, Y' L, N) x- D0 g; y
- return ATL::CSimpleStringT<char,0>::Empty();
' O* L: I, y+ }5 G! c: S4 v+ V9 N6 V - if ( !a2 )
4 `. b) ?/ s1 N* l/ G, f5 x: j - unknown_libname_180(-2147024809);
% K8 H; V1 J# e7 ], H% d" M6 P - v4 = *(_DWORD *)(*this - 12);
: }. q9 x* q* v$ M- Y7 X( ^$ q - v5 = (char *)a2 - *this;
- k: j$ G& {( X1 H% d& V& K - v6 = (void *)ATL::CSimpleStringT<char,0>::PrepareWrite(a3);: O' Y# O4 D3 O% ~/ l9 R; f5 L
- if ( (unsigned int)v5 > v4 ) v I9 B9 Z4 p B3 r$ B1 `
- memcpy_0(v6, a2, a3);
0 |2 s1 t9 C: L - else, m3 W4 z p+ u, _! _2 ^3 _
- memcpy(v6, &v5[(_DWORD)v6], a3);
2 V; V% j0 U& z; [/ ~0 x( O Q - return ATL::CSimpleStringT<char,0>::SetLength(a3);' N' Z; d) s- q& _% u
- }
3 e0 b. N3 ~0 r E* l9 D
复制代码
. ~2 c" ^" t# }9 U% L/ y7 F/ Q
+ z- W, J# |2 B) d& w- e9 K' f% j1 ]; c( V6 n- c) F, o* `. n
|