本帖最后由 shane007 于 2023-8-27 10:49 编辑
" o( O! S: N; ?' i; ?
% f! _' x# r+ C! f, f这个游戏是opengl引擎的,对opengl的初始化主要是在vision71.dll里做的。经过grep文字检索之后,确定这个游戏没有调用 glGenLists和glCallList这2个函数来用于字幕显示。: ^/ c4 a) h. V( H; q v
; s4 h. t" \+ s; M4 C. K# Hdxwnd窗口化之后,用cheatengine 检索内存字符串(注意,有的字符串在内存有2份,对后1份下断点才有用),8 g) P1 u$ l. ]( |
随后下断点。在以下地方断下。
/ D7 b1 E" m K( G# ?# w. W5 L' w
7 ?* \, o1 v+ |5 Q& X4 Q- Operation Wintersonne.exe+CE883 - F3 A5 - repe movsd ! R: W' m4 ?! O+ ?. I+ @, u
- 004CE883
复制代码 7 Z) u3 Q$ d4 A" X
8 \. a2 m; s) M' h, j3 H用ida pro查看之后,发现是个底层方法。
' M5 V/ n" ^' t& c4 X0 V, _真的显示函数应该是调用它的上层方法。
8 @9 \' a a2 O4 ~- void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)
% V1 ~/ b7 N, R) f* p
复制代码 7 \' s( f$ {& ]$ _
( y# _7 t' x: i1 g" D这个方法看着蛮像的,也许就是它,待日后修改代码测试
7 A4 b d% A( L! N' G
6 n$ R( I8 F7 I
1 e& j5 I/ I, s: d9 K- int __thiscall ATL::CSimpleStringT<char,0>::SetString(_DWORD *this, void *a2, size_t a3)
, H8 I8 K) e3 D7 C) R$ c - {
: t$ V n3 \0 l0 V2 V3 Q! S+ U - unsigned int v4; // edi
1 M8 \& F' O2 \# d$ | - char *v5; // esi9 j* M- W3 j$ `0 f
- void *v6; // eax
3 U9 ^% J! m- H+ j; h5 I& W - , H: q, N" \% K6 _. V
- if ( !a3 )+ I% t1 C' G* D( [0 v- r5 g
- return ATL::CSimpleStringT<char,0>::Empty();! g: i6 `7 s/ e, x; x4 A) M
- if ( !a2 )) f' H X+ \! E
- unknown_libname_180(-2147024809);) h" h+ P6 I n C5 U
- v4 = *(_DWORD *)(*this - 12);1 Y# T6 z7 e# @; V6 u G- b% a0 Q& q7 ^ v
- v5 = (char *)a2 - *this;& E( \$ d) W' B1 M7 g
- v6 = (void *)ATL::CSimpleStringT<char,0>::PrepareWrite(a3);. M. R9 h; B& N. [6 n8 G& f
- if ( (unsigned int)v5 > v4 )0 ~$ `8 W/ O8 b- r4 s! ^
- memcpy_0(v6, a2, a3);3 j& n" H$ l' _1 V! W3 W
- else1 L7 s& z8 N2 x7 M2 j& ]( u
- memcpy(v6, &v5[(_DWORD)v6], a3); ?8 q( I7 h) ]9 O5 k
- return ATL::CSimpleStringT<char,0>::SetLength(a3);
; o2 J3 d8 d/ d) \7 v - }
7 ~$ i( `% T& O. k2 |
复制代码 8 H& o+ Y3 n4 e) w
4 k! ]4 G+ E& H9 P1 w, q4 d
5 j5 H& E3 h7 ^- e2 ? |