本帖最后由 shane007 于 2023-8-27 10:49 编辑 9 E% I1 O$ I0 p! H7 ?3 |8 j" }0 _
9 R/ ]% z, ], @/ N! V/ c3 [ d! R这个游戏是opengl引擎的,对opengl的初始化主要是在vision71.dll里做的。经过grep文字检索之后,确定这个游戏没有调用 glGenLists和glCallList这2个函数来用于字幕显示。
[( T/ L; k0 l# g* V
% {- K8 F9 b, W; D& ?dxwnd窗口化之后,用cheatengine 检索内存字符串(注意,有的字符串在内存有2份,对后1份下断点才有用),
; W5 f4 P2 ~* G' K( ^) P2 |随后下断点。在以下地方断下。
" [; [1 d7 U1 r7 x0 O; o" |0 U0 _
. P0 R* [2 {6 k8 O, V: V- Operation Wintersonne.exe+CE883 - F3 A5 - repe movsd
: b' A* Z4 A! D6 U* H6 l4 i - 004CE883
复制代码
* g' @; V; f* j) Q. t) P/ `4 D+ ^5 H1 n
用ida pro查看之后,发现是个底层方法。% F) q* h+ V& Z, B8 h7 `* Z
真的显示函数应该是调用它的上层方法。- M. m. h- E P$ s* c
- void *__cdecl memcpy_0(void *a1, const void *a2, size_t a3)' {9 }- n; |+ Y
复制代码 : l, V1 n# O3 R& w
# i( B1 M4 m+ @; i& P+ c( |这个方法看着蛮像的,也许就是它,待日后修改代码测试
# o4 [5 y- H7 _- A. S' Q" O% ]3 H; ~% k
) D+ k! S8 o) l: Q- int __thiscall ATL::CSimpleStringT<char,0>::SetString(_DWORD *this, void *a2, size_t a3)
) [& m7 B4 V0 _ - {
, b: _* ^' U2 l) Q3 C7 E - unsigned int v4; // edi
+ ?* ~* G( m- b3 p# D) x6 X& J" D - char *v5; // esi
" b7 S4 ?" v7 k# E7 @7 t) H - void *v6; // eax" E" n9 v9 \; B- H6 b
- & |# g9 E9 }- Z* L" J- a$ S2 I
- if ( !a3 )1 T" ~! s; s6 d8 N5 v J' h
- return ATL::CSimpleStringT<char,0>::Empty();3 H9 C# h7 c' w6 T! j3 I
- if ( !a2 )7 B* [+ i1 Y9 M K Z
- unknown_libname_180(-2147024809);/ [) z/ X- G4 i* O$ `0 E
- v4 = *(_DWORD *)(*this - 12);( w' v8 z0 E7 c
- v5 = (char *)a2 - *this;
6 k( L) T3 \5 Q# J6 d, h - v6 = (void *)ATL::CSimpleStringT<char,0>::PrepareWrite(a3);
8 W" @+ ^9 r! O& b: s& A& ?# V - if ( (unsigned int)v5 > v4 )( i0 L' @& N; f8 j/ I }. C
- memcpy_0(v6, a2, a3);! U8 l8 H- `" n: ]( a6 f& e
- else0 z- _5 ?2 i* V" U# N
- memcpy(v6, &v5[(_DWORD)v6], a3);
* W: R4 V! |& ] J5 q - return ATL::CSimpleStringT<char,0>::SetLength(a3);
5 a" P; D; C: s' s- [* { - }( ?$ n( K9 A# J( R
复制代码
4 U! H% h- }0 t" |3 N3 X, E4 s0 S4 ~
f% h( V8 g! Y3 I1 i; B h% Y' P" ~1 Z+ F; j' k8 M- p5 o
|