本帖最后由 shane007 于 2023-8-27 10:49 编辑
% {7 n& R& ?( E' @: T, e
5 R3 u8 V) U6 e' `8 ^) P4 p, _这个游戏是opengl引擎的,对opengl的初始化主要是在vision71.dll里做的。经过grep文字检索之后,确定这个游戏没有调用 glGenLists和glCallList这2个函数来用于字幕显示。
% M1 e' U& P* A9 K1 m0 u' {/ h; w* H5 G
8 W8 e1 a: `. D' l, }+ cdxwnd窗口化之后,用cheatengine 检索内存字符串(注意,有的字符串在内存有2份,对后1份下断点才有用),
" E# |" J" P' g! @8 B7 `' u, ?9 h随后下断点。在以下地方断下。
4 V3 K) }: ?& K' ?* Z1 ]. o4 k) ~* Z7 J% @+ i$ t1 v
- Operation Wintersonne.exe+CE883 - F3 A5 - repe movsd
- S5 X, I: \- m4 Z! I - 004CE883
复制代码
4 c' H8 f' w# I, a3 [7 C- P- k+ E5 D9 Q6 l, v6 }: \' x6 Q
用ida pro查看之后,发现是个底层方法。
: I) \6 j, H8 S! ~真的显示函数应该是调用它的上层方法。
6 P" W0 D0 `3 f5 w- void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)5 G8 _# L8 W U
复制代码 ; ~! M( |3 z( x$ `) K
1 H- [0 F7 Z" U; \1 L4 k. z/ m这个方法看着蛮像的,也许就是它,待日后修改代码测试1 y; f3 @' l& Q
' H/ S8 `7 V/ w7 }- h) [
* O* ^1 i9 V0 G2 E- int __thiscall ATL::CSimpleStringT<char,0>::SetString(_DWORD *this, void *a2, size_t a3); e$ h" S$ D9 ^% `
- {
: Z1 ~8 Z2 \3 P5 Y5 } - unsigned int v4; // edi
% K' k' z* R# L5 K1 B9 W. W - char *v5; // esi
8 X0 L) Z( l+ P - void *v6; // eax* Y% [1 ?8 c) A7 W4 Z3 K
% s' h9 j' `$ p" T5 [/ o2 I! P- if ( !a3 )6 o1 o5 A1 i$ n" \
- return ATL::CSimpleStringT<char,0>::Empty();
) P- i8 s" Q. @8 D/ t - if ( !a2 )% W- K) V+ }0 B3 F+ |
- unknown_libname_180(-2147024809);1 c" n% ^7 m" i& f o& G
- v4 = *(_DWORD *)(*this - 12);
* Z6 D7 h( `. U3 c8 n7 [ - v5 = (char *)a2 - *this;
- I- E8 U: g: F& I - v6 = (void *)ATL::CSimpleStringT<char,0>::PrepareWrite(a3);* R2 f3 k9 r. R; |. \" C: V' G8 t3 `! y
- if ( (unsigned int)v5 > v4 )
0 ?& J3 j+ F# k) R: ?3 E* G7 K - memcpy_0(v6, a2, a3);8 y3 j! m. u! s2 D: X
- else
. m1 U Z. ?' X" b6 | - memcpy(v6, &v5[(_DWORD)v6], a3);2 }5 ^9 o: J% L5 H$ Z
- return ATL::CSimpleStringT<char,0>::SetLength(a3);
9 a p, y6 K: \# E: G. d, t - }
0 Z" b. w3 ?3 U8 ^# a( U
复制代码 7 \8 ` T0 r: x4 X" ]5 P& U
8 y1 d3 Q" @7 ?* ~: l
; W' F. x" a! N" S |