标 题: 【分享】3句代码,在星际争霸屏幕上写字(详细教程,有图)
3 b& a$ W+ q$ D" i* N6 q7 I$ I作 者: ztd
3 B) F; f0 s( p; Q时 间: 2009-01-06,20:31
$ v4 a! G1 [1 S: e( `链 接: http://bbs.pediy.com/showthread.php?t=80016
0 z$ B9 q; l! Z( c
# O( h+ m7 R/ c5 C+ S我们来看看在游戏里怎么写字!
% I& T( y. u. k( ~游戏版本:星际争霸1.16.0
+ K5 e6 A; I7 k; e0 X5 y/ ^ i# |9 f工具:OllyDBG8 d- {# f: k' Z6 }+ `- u
# t3 A# o7 \0 a" @! n7 C, s如下图:
/ c% Q" ~% Q( I' H" F1.jpg
- G: _3 U/ `5 i- k5 s2 [
2 o! n* |3 M1 [3 Y# F( a
( w( G+ T5 ~% J( y( W. U% |找CALL思路:游戏里写完字后,它应该会在内存里留下字符的痕迹,我们就从这个思路开始找写屏的函数。
* M& y0 Y( a% v; `+ A. [; H: R/ S
第一步:先让游戏自已写几个字!运行游戏,选择局网IPX,和电脑对手。开始游戏后选择设置网速(玩星际的不用说怎么设置了吧?),完了它会出现以下字符:* k( ]: ~0 k! K& L. b" Z
2.jpg
, I4 ~- B* R H n! ]6 {
4 Q# P1 }4 m, D* y, g! P6 p; T! b- o
第二步:在内存里找关键字,按下图所示,找到为止。4 H" A$ {3 j, q7 F6 r; M
1,按图所示,在OD里先从D 00400000开始,回车。, Z. t o' J1 a" `
2,按Ctrl+B输入关键字,再确认,如果没找到,再从1步骤开始(找不到再从D 00500000,D 00600000)。
9 K. B' X1 i$ O' G8 |% _. I3.jpg
- [- H% t5 H6 K4 p 1 P# a7 x+ L' ^" W: S
3 Q2 J0 o6 |) S& l2 | m5 t+ n第三步:找到后用你的大脑分析,怎么下断。
/ ]4 ?1 o2 T) K8 w, \9 Z可以看得出,这是个动态分配的字符串,但是也有规律,每间隔N行就是一串。/ z( s/ @. `5 V/ S+ D
4.jpg
- d, g2 J. B, H, X% }% l $ D4 Y- Y9 F# b t" E" A2 K
3 z2 J' V" N9 X0 C" a& b
第四步:找到规律后,我们试试在最后一次显示的字符串下面,选择一大片空白区下个"内存写入断点",看看能不能找到是哪个程序在写字符?下完断点后,在OD里按F9运行,再切换回游戏设置网速,让游戏自已再写一遍字。. g; Y' q- e/ c+ H$ Y) @% E+ h
5.jpg# `1 }, n: y7 Z4 i- i, C2 R* v
0 R# ?; A+ x! @$ U* W2 ~% E
' q0 J- i' Q9 X
第五步:运气真好,居然断到了。
& r+ S: }7 @! H% |7 r/ p" L1,如果断点正确(看下图1的注释),就按下图中所标的1,2,3步骤操作,之后,在OD按F9运行程序。
& P2 V! W! T/ ]4 Q说明:按这三个步骤操作很重要,它可以帮你带到写屏函数那里去。因为找到写字符的内存了,我们就可以找到显示字符的函数了,因为游戏要读这段字符内存来进行显示。
: n! Q% w! ~6 Y) J( l8 \1 a* c6.jpg
1 W' i* y1 j. k( D7 J
, e. s- f/ y# a4 w* F# E4 q
. h' o6 I2 u' y, u5 B- `第六步:离胜利不远了。
3 `2 D0 P! r& K% e+ T9 `它把你带到写屏函数附近了。如下图所示,为什么要在2那里下个断再走一步?因为这还不是写屏的主函数,因为它RETN 0C,就算你用远程进程Call这个地址,程序也会出错,不会正常返回,所以我们还要往回找,看这里哪里CALL进来的,按下图的说法操作。
# G `" c! ?) i( a! P+ ^7.jpg1 r p7 m. q6 @( q7 n. l/ e
J1 N; q& C6 _% @: r# R% _, i; ^% q$ E! n5 ~
第七步:搞定!& p7 y2 o& M l
8.jpg
2 K+ @) n# A9 p& o3 `; C8 g" L & }) x F2 L, V* M: O, f( l7 K( h8 G2 G
" d5 V1 Q8 h) A第八步:通过远程调用游戏的CALL,来实现游戏写屏:) a/ ^: V' t0 H( s0 a- T, u7 I+ T. ?
这一步骤就不详说了,VS2005,我用的是全局钩子。你们爱怎么就怎么的,反正关键代码是:' c3 J" x$ J+ p5 b0 D/ e0 r
if(X键按下)6 [+ \. @" ]+ c9 p5 q2 E, ? l# L% [
{. C: a' G9 v6 z0 k* l2 p9 H5 n2 m
DWORD addr = 0x0048CFB0;//这个地址就是我们刚才找到的写屏主函数的起点(星际1.16版本)。( d5 d% A2 z. v: `* _! U/ Y: g
char *buf = "Hello Word!";
& l5 y7 C* p( l) a+ A% A1 W( N__asm
) m- y" C+ e0 w- s; d0 n. h) d{; r1 r: N' F$ f4 W* Z
xor eax,eax;
, E, [+ y* K5 @, ~; { mov edi,buf;& M+ c4 M) J7 ?# ?' W; w5 J, M
call addr;
" O9 @+ I3 {2 u$ n}8 H0 V# y( g+ _6 s) l! v
}
/ u+ z- I! L0 w! |: X( @- B/ W. \" \: g2 b1 k/ @2 W6 I
星际每个版本都可能这个地址有变化,但是步骤都差不多。下面是1.08版本的:3 d7 M2 s9 a6 v# ?# q+ |
DWORD addr = 0x0046DE10;//(星际1.08版本的)/ k. ~7 a0 n3 r7 L# b& l u H; p+ d1 `) @
char *buf = "Hello Word!";2 T0 ~/ Z# o" t- \
__asm9 j i% Q: L' O; f3 L: D
{
, e. `# s! c/ _/ U6 | xor edx,edx;9 _2 X+ K: a# Z; L1 M+ v, b; ^
mov ecx,buf;6 N& ^2 b% A* `
call addr;
1 } H# P4 l! \5 H }
; E4 E1 X4 P- C' }; M4 w
^9 ?9 b7 c: b t3 \9 n3 C9 _----------------------------------------------------------------------------------------------------------------0 g) N, w* T& u. h
顺便再给出一段星际联网时可以地图全开的代码(1.08版本):
f! B* I: v% g+ E' |# m( y5 J
6 b# R$ r$ [! W+ ]9 ?//16进制字符串转数字并写入指定地址) \' q1 ?- I4 ^8 T
void write_ma(DWORD addr,char *ma)6 U! B4 y' T# K$ [. X: x
{, B# c5 p% P e/ W1 T" {3 e
__asm/ g9 c3 _- V: g. H5 o4 c
{& P7 P( |/ S, V, t) D [
PUSH EAX;; e$ }# {3 `* g7 A. `
PUSH EBX;' ` f5 y$ T2 P w8 {
PUSH ECX;1 P' |% o, G7 e. d N
PUSH EDX;
% Q# M) |) K r$ p- P- N$ j PUSH ESI;; u) M6 ?( P. V. n# }: ]
MOV DL,16;
; ^; V$ m8 E2 G MOV EBX,DWORD PTR DS:[ma];
/ K7 r- \+ w) p# B5 l1 Q5 A MOV ESI,addr;
5 B( Z3 o: C7 e CALL Write;
8 A# B6 `( h+ L7 i/ _, \3 v3 x POP ESI;; n4 {3 K+ n' l* t/ V2 ~
POP EDX;
% n& o1 _5 A5 b, o$ q# O POP ECX; @4 L$ I/ N8 j( [& b$ w0 w
POP EBX;0 U8 M1 [, e$ [0 y" u% o" D; {
POP EAX;8 t" }: i" G( ^2 e( q! a1 z) C& ]4 D
JMP OVER;5 e, _) C1 l& W m8 ^8 a3 s5 Z
Write:: a( d8 Y3 J6 N, O q
XOR EAX,EAX;
1 R: F: c+ K9 n5 M9 E XOR ECX,ECX;7 t( l& U& i) c# i& J; T
CALL GetAnsi;
' X9 K) ? p, N7 Z6 `' _ MUL DL;
+ [4 b6 s0 P7 W8 ^/ k9 E5 d/ K& o# L MOV CL,AL;
! }1 I6 m" y; {6 }* R! L INC EBX;! P8 U z# N, z, [% J- x% o
CALL GetAnsi;8 J; d5 j4 O& d4 ?
OR AL,CL;
6 g; |' m0 G; |7 E6 _2 K5 K MOV BYTE PTR DS:[ESI],AL;
+ l4 [; [7 F, Q0 R1 j INC EBX;
& o, X5 E- Z3 ~$ U INC ESI;
" ~; l4 t3 n8 O* f9 _ MOV AL,BYTE PTR DS:[EBX];
6 x8 t7 i! q6 ]: }) y8 K; p CMP AL,0;$ y) Z- g8 ~5 a% n# }; u
JNZ Write;8 w C2 J. @" O( {6 B' I
RET;
1 D; ]; q0 P! h5 \1 O$ k- \3 h GetAnsi:
/ U& V* j$ \3 z( L MOV AL,BYTE PTR DS:[EBX];
/ X% W( ^$ Q- n. {& m CMP AL,57;( \7 I- K' v( b% G
JA ZiMu; ^) {6 j6 M* N+ @# v% v8 U( o1 |
SUB AL,48;
. |- J6 a1 V* i* x6 ?9 B L1:
* ^- d- ?( q# g* Z. `4 d4 q RET;$ n8 G, @2 Z: M
ZiMu:, [2 ]% o; n$ h3 j! ~3 P, |' @7 g4 Y
SUB AL,55;
4 V6 Y, P% X$ @% X, L JMP L1;
) o I. C+ h6 P& P. P6 Q OVER:
8 Q1 p* J6 @' h; h) B& d }0 \: w5 D( A- Z* q% a& L1 e
}) J, R- ]. E; x) {' q* O
, G1 @3 l; _1 B' a3 c" t6 G, G& r//按F12地图全开
9 N! g7 ]% S& i==============================================
1 Y4 o" H' c S, R/ l if(VK_F12 == wParam && 1 == ((lParam>>30) & 1))
e( B4 u7 v Z {) _8 F' j+ J2 z5 E
//游戏屏幕上显示“Open Map”/ M' D' J! F' D$ c3 W" V/ g1 a* T$ V
DWORD addr = 0x0046DE10; R) _( v/ [, X; C9 \
char *buf = "Open Map";5 ?& @0 z! z5 N8 c; j, ^2 D, O
__asm! m( l$ {7 Y& Q8 E6 K* |
{
/ [3 d5 P6 b3 `/ U xor edx,edx;4 }9 T! Z8 Y( E+ n
mov ecx,buf;
, E* w Q6 t% }" p call addr;
0 F1 s- j6 }& Y3 } e) E6 i; Y }! @% w: B* @$ h+ A5 X" E" Y
//开地图的代码2 U6 l! S! z+ s0 O$ ~# F) O4 o
write_ma(0x00404BA8,"7500");
1 E2 z; h5 _5 Z9 N1 y* E8 m write_ma(0x00410C81,"BDFFFFFFFF");
9 C1 g8 }0 Z* W7 b: V: m' ^ write_ma(0x00414046,"7400");
7 X1 Z0 o2 B! V) p# j2 ~ write_ma(0x0046EA70,"909090909090");
2 G2 N; {. F! D5 x9 o- w write_ma(0x0046EA7D,"EB29");$ _' p" [+ _7 f
write_ma(0x0046EA98,"7500");
( i' h1 t7 |4 S3 a* v1 u write_ma(0x0046F7EE,"310578A16500850500A86500750AFF0D90A6650090909090");# `( Q/ ]$ E/ l. U1 h; Z
write_ma(0x0046F815,"7400");
& b6 j7 G. n! m8 Q write_ma(0x0046FA6B,"310578A16500850500A86500750AFF0D90A6650090909090");
. o( p7 h* |* t+ g; n write_ma(0x0046FA92,"7400");! h) I5 c' k; P9 D8 k5 f3 Z& l
write_ma(0x00470F2B,"7400");
% T, d1 N' S" Y: H: m- G write_ma(0x00470F43,"EB04");7 L& I6 N! E% }) Y S: I
write_ma(0x00470F4B,"EB09");
! p# b0 R. N8 s- @6 w/ B write_ma(0x00471067,"7400");
. }# E: | o! V6 J% B9 s write_ma(0x0047107F,"EB04");$ Y% z6 _2 ?1 h& w9 Y) _* S
write_ma(0x00471087,"EB09");% {2 a! ?2 R8 ^
write_ma(0x004C9541,"0F8400000000");! [1 G3 g5 p- L7 N
}5 d* |& v( m8 s8 {" T2 ?& r( q
} |