本帖最后由 shane007 于 2023-8-27 10:49 编辑
& w% n' T: Y' q. i+ N& {6 y+ d* E @2 d$ T
这个游戏是opengl引擎的,对opengl的初始化主要是在vision71.dll里做的。经过grep文字检索之后,确定这个游戏没有调用 glGenLists和glCallList这2个函数来用于字幕显示。3 r1 Y, C, C% @6 S; o, A( _7 W9 X+ \
% h# r9 l Q4 M+ ?! h7 i
dxwnd窗口化之后,用cheatengine 检索内存字符串(注意,有的字符串在内存有2份,对后1份下断点才有用),( D/ {0 ~; `- ]' G% {7 A' I
随后下断点。在以下地方断下。/ h2 [' {* ]8 D( m7 e; \+ D
e( @$ y" U5 z# q) z8 [$ N/ ~- Operation Wintersonne.exe+CE883 - F3 A5 - repe movsd ( G& |: h/ w/ B6 l/ c* b! i9 h
- 004CE883
复制代码 7 c; N( M! C( I3 T" o% k) S. W8 ~
7 R8 ~- M# `/ Y* N用ida pro查看之后,发现是个底层方法。
3 F5 A% T0 q* _2 z9 g真的显示函数应该是调用它的上层方法。
4 [- v3 S7 L, s' d4 r |4 e- void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)5 D" ~% f! l' l8 p" g6 h2 z6 K
复制代码 7 B8 ]/ x% I, x! i6 I0 W
; g2 y3 ?, g) V% h7 O
这个方法看着蛮像的,也许就是它,待日后修改代码测试
. p* M8 ~! d9 z$ N, P
1 H: R- w/ _, B+ r$ R& U- & i% K! k! P1 _. \* r. L
- int __thiscall ATL::CSimpleStringT<char,0>::SetString(_DWORD *this, void *a2, size_t a3)9 k$ H" ?" Y H5 C+ G9 s) ~
- {! i, _. z. T/ b
- unsigned int v4; // edi
+ D3 z( w/ h$ |. C - char *v5; // esi5 N" Z& [, t7 p0 A! D9 z' {: V2 a" g
- void *v6; // eax8 I' ~: }" ]& ]- O+ s0 Q
1 G5 E; ]# L$ c. r/ }5 B- if ( !a3 )
; T0 u' r) @" f3 R0 n3 m - return ATL::CSimpleStringT<char,0>::Empty();
( p) ~8 L. [1 U# J - if ( !a2 )
' a( i4 l* B8 f - unknown_libname_180(-2147024809);
$ G A2 A$ A7 J) ~, G. E& I - v4 = *(_DWORD *)(*this - 12);
( T3 t; Y+ s# r" c8 J3 h - v5 = (char *)a2 - *this;, ?) G7 x8 f+ _' P
- v6 = (void *)ATL::CSimpleStringT<char,0>::PrepareWrite(a3);
. T8 F+ g+ x) X - if ( (unsigned int)v5 > v4 )
3 M7 V& g0 U* Z! { - memcpy_0(v6, a2, a3);
" K0 B8 N; L( ]& j0 j& A! z$ J - else
/ a, z) Q5 ^/ J. O6 ^+ J - memcpy(v6, &v5[(_DWORD)v6], a3);6 f) h7 ?' F y8 u* T6 m
- return ATL::CSimpleStringT<char,0>::SetLength(a3);
! v- z8 D4 R0 _' }3 P - }0 ?$ W5 ?+ f( z4 `$ J- I. b
复制代码
# r" C8 k! }3 n0 P8 v- P' _9 H" v- W' I2 m
5 ~7 x s/ Q: X, n9 k. U |