标 题: 【分享】3句代码,在星际争霸屏幕上写字(详细教程,有图)
5 `- \, h, z% `5 x作 者: ztd5 c7 h5 S$ I j& i
时 间: 2009-01-06,20:31
9 ]# a4 ~) ]+ v链 接: http://bbs.pediy.com/showthread.php?t=80016
* U! j5 W# M' p/ @0 X
( ~3 D* I( J+ J T# E我们来看看在游戏里怎么写字! j9 ^9 h- J! G9 H$ j% }6 Q) ]* d
游戏版本:星际争霸1.16.0
, b* V K- }8 z2 E# I! R工具:OllyDBG
0 J6 r) o2 l' g! K `% M8 J' @1 z2 n! n; [$ I6 B- S
如下图:2 I/ v# y+ m" s" [$ s
1.jpg
5 M9 c" G, E8 Z4 K$ }& q
4 t5 K$ { |7 \% w" O+ h- e& @
) W/ D( y; g% z e- b找CALL思路:游戏里写完字后,它应该会在内存里留下字符的痕迹,我们就从这个思路开始找写屏的函数。/ P& j! ?+ V8 ?6 q" o* n& Y+ B
- ]: |* b) [4 u4 ^1 j3 \" v
第一步:先让游戏自已写几个字!运行游戏,选择局网IPX,和电脑对手。开始游戏后选择设置网速(玩星际的不用说怎么设置了吧?),完了它会出现以下字符:/ b; i! M" F% @) N: Y% r* I/ c
2.jpg
8 s+ U- t+ B: e8 n; x
1 o* x$ x7 I5 F( z
, L0 e; [0 t: t9 f0 ^9 F* f! [1 R第二步:在内存里找关键字,按下图所示,找到为止。
8 K% ~0 V. _% Q# _1,按图所示,在OD里先从D 00400000开始,回车。- Q, A! ` w3 D3 ~6 {
2,按Ctrl+B输入关键字,再确认,如果没找到,再从1步骤开始(找不到再从D 00500000,D 00600000)。+ F9 {7 y" b& U' s$ V( ]# {0 g0 j1 O+ Z
3.jpg
; F* e( Z ~" n4 W . \/ D) S6 q' Y7 G
4 w! |! Q" q' ?% V6 u$ X8 d
第三步:找到后用你的大脑分析,怎么下断。
+ l: d- O! c+ ^0 b' v( L6 b可以看得出,这是个动态分配的字符串,但是也有规律,每间隔N行就是一串。
9 |1 E8 Q0 _- @, J0 w. @# p A4.jpg
4 x/ P h& B; k 8 d5 b/ r( H0 N5 J1 g3 q
/ R( D- [! P% C" l
第四步:找到规律后,我们试试在最后一次显示的字符串下面,选择一大片空白区下个"内存写入断点",看看能不能找到是哪个程序在写字符?下完断点后,在OD里按F9运行,再切换回游戏设置网速,让游戏自已再写一遍字。+ m) x3 {% V# @' v
5.jpg
" H" l( C' p9 q+ r : l/ _# _4 W/ U. ]4 f
$ O" j3 F' s9 ^3 e* k7 g! c
第五步:运气真好,居然断到了。
5 B" F* ~% X* I. z1,如果断点正确(看下图1的注释),就按下图中所标的1,2,3步骤操作,之后,在OD按F9运行程序。# c( I r `/ k4 F: u4 L7 M5 f
说明:按这三个步骤操作很重要,它可以帮你带到写屏函数那里去。因为找到写字符的内存了,我们就可以找到显示字符的函数了,因为游戏要读这段字符内存来进行显示。
% I4 [7 j& V" F ]+ b& _6.jpg3 `4 u9 k+ ^( s% O* V
9 z$ _) |6 o5 m( a; V& K* u( p/ ]5 y* T& u3 M# \( d
第六步:离胜利不远了。. u9 S6 B4 N. d$ \, |+ S
它把你带到写屏函数附近了。如下图所示,为什么要在2那里下个断再走一步?因为这还不是写屏的主函数,因为它RETN 0C,就算你用远程进程Call这个地址,程序也会出错,不会正常返回,所以我们还要往回找,看这里哪里CALL进来的,按下图的说法操作。
' l5 Y/ J7 H; v, T- _7.jpg
( _" g5 F. h( u) {/ a8 ^ F 7 L$ B/ S6 ]6 j. M# Y& j# p
+ U3 ]$ h4 R$ J8 _
第七步:搞定!3 I# l) l' X7 A; x b
8.jpg
( s; X1 Z& W& T2 y " L! C. t1 M# V
; u6 z% z) S. v5 T* B% z w$ z
第八步:通过远程调用游戏的CALL,来实现游戏写屏:/ r9 x8 ~0 u( a( Y% I+ X
这一步骤就不详说了,VS2005,我用的是全局钩子。你们爱怎么就怎么的,反正关键代码是:8 e! D, o& n3 l# ?) v8 k
if(X键按下)& P1 m' k% r) U& Y
{
' O4 q. L+ N+ T2 n5 Z7 ?1 \DWORD addr = 0x0048CFB0;//这个地址就是我们刚才找到的写屏主函数的起点(星际1.16版本)。
2 a3 i% }2 [6 t, u# H" f4 kchar *buf = "Hello Word!";
2 k1 p8 C6 ]" w__asm
7 _( j- K" g! H) F) O{
% g) i0 q+ Q( n/ }0 i J xor eax,eax;
; F$ {& q& t$ r5 A+ F) q mov edi,buf;: \# n1 S! \" N; h
call addr;* ^( T0 s1 G4 b/ Z
}
- r3 {+ J7 n/ i; s}% i# }8 ]4 r% r" i0 d
* F( e& y, v4 L) ~
星际每个版本都可能这个地址有变化,但是步骤都差不多。下面是1.08版本的:# A4 X2 R) K+ _) F! s4 J
DWORD addr = 0x0046DE10;//(星际1.08版本的)
0 D- f1 G: o. H) q* n char *buf = "Hello Word!";, [7 O$ i$ }+ {5 G% R
__asm! [! q( F; ? J8 V3 @
{& R0 q) |( m3 A5 i/ k' L2 U
xor edx,edx;3 S4 V9 W/ m* r" ~- k& U! n* [
mov ecx,buf;5 w2 i; _1 P) o3 w: j4 j( j* l( e
call addr;+ _3 h8 o2 ]. ?8 Q& g; F+ |
}) E' B+ z% ?2 P) K0 B. u$ x
3 L9 W8 i0 y3 u5 k
----------------------------------------------------------------------------------------------------------------" }5 _ D8 E! u1 s# \
顺便再给出一段星际联网时可以地图全开的代码(1.08版本):
5 ` [2 a( X7 I; `" e! B# O' T% _5 I) n: A, Z. c
//16进制字符串转数字并写入指定地址6 Z/ H$ m9 W7 M: ~0 l" L; W
void write_ma(DWORD addr,char *ma). t( O. `. W' S" j8 P5 d9 Z
{
6 @4 N# ]# s" K: Q5 M __asm
2 _2 Q5 N! X5 a+ f& n4 D+ I% y+ W {3 W5 M: K4 d. n9 q- S* S% h
PUSH EAX;
/ `! m2 J1 N# u* T/ O) D PUSH EBX;
. c) y$ N, c* n& Z n PUSH ECX;
! t* a, t3 v1 }6 [0 R- l& V PUSH EDX;
1 @7 I) |; L3 R2 h PUSH ESI;
7 z4 p! c) i _! z$ Z. l2 e$ Q MOV DL,16;2 T# S. M' p+ c/ c9 X. \! g [& h
MOV EBX,DWORD PTR DS:[ma];- |# c4 b* h" h1 N, _8 v
MOV ESI,addr;
6 L' t1 Y# _+ [ CALL Write;
{ y( [% r) K; E$ I( E POP ESI;$ [' J/ ?: S' p
POP EDX;- P& c: Z8 [ e1 ], ?- y1 }
POP ECX;
: h) R/ E( b! H, A k% S/ W8 J POP EBX;
6 G( P* V& W) P7 k, F POP EAX;
! g$ A$ M0 }7 ^: M: \ JMP OVER;% q ?. Z& |3 ] D2 H
Write:
6 }+ w# K* |5 N1 }- o% t2 r; N, N XOR EAX,EAX;
5 S" n% d. F: Y2 v$ j6 w XOR ECX,ECX;
* g; s; O# ]* V3 T9 E CALL GetAnsi;
! ^2 a# K2 B! ]; a3 d& e MUL DL;
$ n% g; B! ~9 _, f- } MOV CL,AL;
8 K+ D3 ]2 V# d, a3 B INC EBX;
# z# C s5 B1 W+ _ CALL GetAnsi;
@# R, U! x7 P$ O* _# M OR AL,CL;1 l) b; ]1 F, v, u2 Z) b c! `
MOV BYTE PTR DS:[ESI],AL;, ]5 r* g1 U0 }$ k- ~
INC EBX;
, a+ h$ Z3 i0 T% o0 ]3 g INC ESI;
4 e& Q& [0 G2 d5 ? MOV AL,BYTE PTR DS:[EBX];
, ~5 M. t% L& D# i CMP AL,0;
6 K( ^3 X" n7 b, \1 Q; i! N JNZ Write;
# g* M! Y: f( y7 g. F RET;& W3 u! t6 n: R2 e& L/ b. o
GetAnsi:9 E( u/ J* J" O; W8 ^
MOV AL,BYTE PTR DS:[EBX];
" I5 Q. q( R4 R$ d/ j6 V) r4 a CMP AL,57;
) J) t2 j4 u/ { JA ZiMu;
- j* q, k/ n/ O. I% g SUB AL,48;
# o# r3 o2 ]$ `0 i L1:7 P* R4 `: u" h0 h5 G9 t U0 g
RET;
- y6 Z- J+ G2 l2 n ZiMu:) d! F, r8 l- \" w8 {0 D3 U
SUB AL,55;- R$ _$ K) g6 L* J; m5 w
JMP L1;
+ e1 q1 Z" g/ s& g, }% h9 [! y OVER:
: Q. N7 U% O5 e/ x' c( { } I+ p7 }# l7 e" l/ H
}
# {8 u [6 Q# I( Q& q: r
" A0 e/ V# |" h/ T' v1 i! Y//按F12地图全开
! u: q: j7 H: H& R==============================================
6 L- n: n9 U: ~( t1 s: Y( z9 k if(VK_F12 == wParam && 1 == ((lParam>>30) & 1))2 Z: @! L& J0 ?1 m
{
4 e7 i6 o ^- d//游戏屏幕上显示“Open Map”% A4 C( R- \9 P5 W H
DWORD addr = 0x0046DE10;3 E+ a# F; ~3 h1 W9 d+ A5 e
char *buf = "Open Map";( S4 ]; Z7 p' a" t
__asm9 L9 R( a/ g2 f# _& W, D4 a) W
{ a" P. S5 H% W' I5 x/ @
xor edx,edx;- n( i1 W3 T6 H1 n6 X$ Z
mov ecx,buf;
% l' a6 |; k3 [0 e+ Y( n call addr;# e9 S7 t. a$ @( x
}
( H! U% m( K# @: B//开地图的代码2 A, n3 I6 t( v* E9 M, {
write_ma(0x00404BA8,"7500");6 @. O- Y/ f$ q4 q! ]
write_ma(0x00410C81,"BDFFFFFFFF");& J ~- b9 U/ t) l- n) P
write_ma(0x00414046,"7400");4 u V {( g% e; A: y
write_ma(0x0046EA70,"909090909090");
+ a' q- t9 G2 z6 |5 V m write_ma(0x0046EA7D,"EB29");
( J2 {9 h- e* B. S write_ma(0x0046EA98,"7500");1 j0 {* Y! ?! ^% y* D" m
write_ma(0x0046F7EE,"310578A16500850500A86500750AFF0D90A6650090909090");
7 E( U& b% G, f1 | write_ma(0x0046F815,"7400");/ U2 H1 z" x: d+ u
write_ma(0x0046FA6B,"310578A16500850500A86500750AFF0D90A6650090909090");2 [6 W! ^1 J4 t) w
write_ma(0x0046FA92,"7400");
- ?1 i0 M: I* t! I F write_ma(0x00470F2B,"7400");5 h! |% s5 Z/ j0 b! C* m- i+ ]
write_ma(0x00470F43,"EB04");% }/ Z' o( Z( k2 F! T
write_ma(0x00470F4B,"EB09");' M+ s5 ]* S( N% [$ }% q
write_ma(0x00471067,"7400");
; R i3 P9 g$ f8 x; F5 X write_ma(0x0047107F,"EB04");
$ u2 w6 _0 G7 \3 J$ D- J7 G write_ma(0x00471087,"EB09");
$ e) c* R) `. I8 ]# o( I8 M write_ma(0x004C9541,"0F8400000000");
! w) l n8 |( A( W }
* }) J T- V3 ?9 F' l. n0 k7 J} |