标 题: 【分享】3句代码,在星际争霸屏幕上写字(详细教程,有图)' b: G$ T1 e; h
作 者: ztd
# Q# n g+ f" v: x时 间: 2009-01-06,20:31
( M+ ^1 {$ ?, }* z链 接: http://bbs.pediy.com/showthread.php?t=80016
% Z; Q, P! n& K" C5 t" D: x @! R; K# c8 _
我们来看看在游戏里怎么写字!/ h2 ]* m' U; z# e8 r. T1 P) E* @# O
游戏版本:星际争霸1.16.02 {6 Z' [. I' m% l) r5 _8 h- i+ q
工具:OllyDBG
. |3 j% s; o" X" o' `4 F0 A1 E3 X/ @# e' O- S
如下图:. [$ ~& n& O0 G% T9 G5 k4 O y8 w/ ~ n
1.jpg; C* R* f/ U' @/ t0 S6 l* K1 I5 k( t
% |7 |, B$ x% e0 f# ?
9 R' D. F, |2 i) D
找CALL思路:游戏里写完字后,它应该会在内存里留下字符的痕迹,我们就从这个思路开始找写屏的函数。
" L; Y; S' c, ?- U5 H& ?/ C0 N0 ~2 i e+ G9 M% q
第一步:先让游戏自已写几个字!运行游戏,选择局网IPX,和电脑对手。开始游戏后选择设置网速(玩星际的不用说怎么设置了吧?),完了它会出现以下字符:" x7 u, ]5 t) {9 o" M
2.jpg
! v4 k4 @- D1 m* ~ w7 t
6 M6 z5 ~; C9 }( t4 b; `7 i. f- ?" u2 p/ [
第二步:在内存里找关键字,按下图所示,找到为止。
! M5 i7 L1 y8 o1,按图所示,在OD里先从D 00400000开始,回车。
$ W1 t/ B6 f' \. k' L6 q2,按Ctrl+B输入关键字,再确认,如果没找到,再从1步骤开始(找不到再从D 00500000,D 00600000)。" L& x- v: N2 a7 m l: `
3.jpg
9 j% E6 U: a) _3 F. T& F
5 [+ l4 L) s; ^( @/ w
) j7 S: S8 \+ J" Q! ?9 v$ r* U第三步:找到后用你的大脑分析,怎么下断。: ?) G# j4 N) |) ]% ?9 P3 _. z
可以看得出,这是个动态分配的字符串,但是也有规律,每间隔N行就是一串。
% \0 Q) }8 v O3 z, J4.jpg
, ~0 j8 T2 t# W& r0 `# r 3 u; u8 ?3 |4 k* k
2 S8 q$ H" D* T: _2 u
第四步:找到规律后,我们试试在最后一次显示的字符串下面,选择一大片空白区下个"内存写入断点",看看能不能找到是哪个程序在写字符?下完断点后,在OD里按F9运行,再切换回游戏设置网速,让游戏自已再写一遍字。
# d' b) K+ m% M* \8 x+ j5.jpg1 X1 z/ t% V( V5 I1 Y M6 Z( `9 ?
. p: S/ n8 U* X0 Z, J; d! q7 F
; ^* v4 O8 X ?1 U0 T6 ]+ C& s I5 p第五步:运气真好,居然断到了。$ b7 w8 C3 W( A; K* x# q$ a
1,如果断点正确(看下图1的注释),就按下图中所标的1,2,3步骤操作,之后,在OD按F9运行程序。* w' j& {5 z% J6 v
说明:按这三个步骤操作很重要,它可以帮你带到写屏函数那里去。因为找到写字符的内存了,我们就可以找到显示字符的函数了,因为游戏要读这段字符内存来进行显示。
& ^* `) P; U+ Y' b& r& s6.jpg
1 J5 x+ Q3 V- F7 m2 O8 M3 Q ]8 G* T# B: q2 `/ \
" i C% T3 z9 V. [4 g. Y; _! e& y/ C/ Q第六步:离胜利不远了。
, a$ @# B# o5 p它把你带到写屏函数附近了。如下图所示,为什么要在2那里下个断再走一步?因为这还不是写屏的主函数,因为它RETN 0C,就算你用远程进程Call这个地址,程序也会出错,不会正常返回,所以我们还要往回找,看这里哪里CALL进来的,按下图的说法操作。
' }0 r% e/ y' g7.jpg
* {4 f/ V! |# ~ 3 a6 w; ~0 H Y- W
1 Z( t+ I% t) A& {第七步:搞定!
4 U% @/ e' @8 E u+ E) X2 D8.jpg
" S' A; ]( X: m* j9 N; B" g8 {$ {5 m 2 e7 p3 n" _7 ? g/ Y
% s) |4 M5 E; ? I# ]第八步:通过远程调用游戏的CALL,来实现游戏写屏:
6 { `! q3 i1 s# X# N( g7 D. v# T" y这一步骤就不详说了,VS2005,我用的是全局钩子。你们爱怎么就怎么的,反正关键代码是:3 a2 Z F5 R2 P) Y3 U' E4 `( o( E
if(X键按下)$ Q. Y5 w% h |# F9 }4 j
{
6 B# ]% r! J. @+ ]- O/ uDWORD addr = 0x0048CFB0;//这个地址就是我们刚才找到的写屏主函数的起点(星际1.16版本)。4 W+ P% r9 ~( z7 j+ C# ~( G
char *buf = "Hello Word!";. P) U+ j7 o) t8 T2 v) m( R0 f
__asm* J0 Y5 _7 V' a5 C; B' c/ L7 b- y
{- X) _7 E2 \: W! D0 f
xor eax,eax;) N; ]; ^% ~5 V8 [
mov edi,buf;! g# B" @( n' s# _! e2 t v' ^
call addr;
, H$ P8 c0 L5 J: t}- U8 A. N$ q( m# b
}3 r, `. k1 G7 {! M
m K( }( |5 l: a* ~星际每个版本都可能这个地址有变化,但是步骤都差不多。下面是1.08版本的:9 _$ y- R0 V" b
DWORD addr = 0x0046DE10;//(星际1.08版本的)+ I8 I' \' V( G; B* ]& ?
char *buf = "Hello Word!";
2 ~' I+ w) j0 k! R6 U; q# J __asm: s0 h1 ^7 Y" l( N/ O, C
{
# S s( p5 g. R R xor edx,edx;' [! @: d9 K' r$ |
mov ecx,buf;
& r i. {2 a- G call addr;9 t& H2 W/ l1 ~ R/ i9 M
}
& K3 F3 y/ B( U* u- K0 u
+ O3 q( F+ v% @( U& l- f---------------------------------------------------------------------------------------------------------------- t- i; ^6 l* @% `9 ^: n
顺便再给出一段星际联网时可以地图全开的代码(1.08版本):& \& j/ h" y d+ V8 ~
0 ]& N A( x+ u( ~//16进制字符串转数字并写入指定地址. B: R' G7 j/ V, y7 Q4 _' i
void write_ma(DWORD addr,char *ma)
; I3 q5 r" L( s, P{
! k1 l9 w; T( A% L5 g6 X __asm5 D5 Z8 e o9 i0 e4 t
{% T, T( U7 @5 o# ^) _) D
PUSH EAX;
! H3 T7 k5 k( b( ]2 Y PUSH EBX;! K0 |' `' E; H" ?
PUSH ECX;
: p% ?6 R; y* [ PUSH EDX;: |+ F& }4 j* i& {7 z* i. M5 c
PUSH ESI;
# k5 @% ^3 H# y' ~& D2 g MOV DL,16; s6 K N3 Q) r# @) R: [
MOV EBX,DWORD PTR DS:[ma];
* Z6 Z5 z, |" w1 d MOV ESI,addr;
8 u$ G Q- G5 K8 i+ f1 k% _ CALL Write;
2 K1 U- v! {& O$ d3 E# q POP ESI;( C! A, I: [; j- |. h2 `3 ^3 p
POP EDX;
* C5 v( }: b8 m. {3 w) u" b* d POP ECX;
4 `4 d3 N6 g* h) N( _ POP EBX;
5 r1 h+ l$ J9 x+ |* q, Z3 k POP EAX;$ i. m4 i* }4 ]6 O* m
JMP OVER;
8 U4 Z0 m$ y, l8 z" B Write:
5 @/ u! x) \ ]# f+ }4 U XOR EAX,EAX;
/ e- f) R+ u9 p% | XOR ECX,ECX;1 w4 v& K; {9 @) E! B: o6 C" r( E
CALL GetAnsi;+ R' n) m c$ H: \/ w
MUL DL;1 H) ~" p( ]1 ^9 c, N2 n
MOV CL,AL;+ ?+ \, X$ W* y! W
INC EBX;9 g( |/ r, `2 m- M( x% Y
CALL GetAnsi;
# i' U) q# Y* B/ L) p OR AL,CL;
6 g* F. Z0 Z5 R4 }4 R" |9 L MOV BYTE PTR DS:[ESI],AL;* c# s- z2 a. M/ B# N' _( P+ [
INC EBX;& @! k. _' ]8 ?: M
INC ESI;
8 ^2 O. o2 f6 z MOV AL,BYTE PTR DS:[EBX];
$ l4 q2 P9 n! ^! r) v CMP AL,0;( M; @& G% n0 A% Z) D
JNZ Write;, Y/ P: C( n e0 [8 B% }
RET;
1 m# D: Y- W, w* ^3 p GetAnsi:- {# k3 c7 p! d3 [) L/ A* e6 w
MOV AL,BYTE PTR DS:[EBX];
0 C, ?: b' P0 B, p; h CMP AL,57;* b K; i8 `& q
JA ZiMu;- t% z) W/ s8 _! P7 J
SUB AL,48; [" L) {" q" C
L1:; m- N5 j' O1 L2 k: c# ~# j8 s
RET;5 q* b8 ?( B8 S' D5 c
ZiMu:9 g9 X F# u1 M- B& o( P3 M3 B
SUB AL,55;; ?" |+ S( f2 o1 T4 L
JMP L1;
9 [- n/ M4 F! ^. i1 m OVER:# k- r% B7 }* ?
}% H. V3 A9 ]! z7 N
}
! P" n; N& z: r1 f5 _4 ~4 B# G" X- y1 m7 W1 d: w
//按F12地图全开/ e3 D+ z, l L6 p5 \5 ~7 w
==============================================
% @- X& o7 p( e/ e; |: r if(VK_F12 == wParam && 1 == ((lParam>>30) & 1))
0 T. y2 L8 I/ g {, D3 d# [( D- j) O, h# R
//游戏屏幕上显示“Open Map”4 o; q6 d7 T# v( n
DWORD addr = 0x0046DE10;
7 i3 h8 E: }. C* _+ v' o* j char *buf = "Open Map";
. X" m6 E f2 ]8 J8 M: v% m& j u __asm4 F1 p6 }9 _0 n# x8 e. c2 q! @
{
7 B& f" E& d9 o' R xor edx,edx;
- ?3 D/ |4 a2 e5 X& L mov ecx,buf;9 \, H+ w8 e! j; o- H5 p8 D2 v
call addr;. b! f7 B1 N* r' A% g7 W
}( P9 W; X; r/ [
//开地图的代码
3 {3 J& m8 k. V write_ma(0x00404BA8,"7500");! v' ^/ Y; h7 j/ ~5 _2 ?
write_ma(0x00410C81,"BDFFFFFFFF");
+ E" a6 \# a& N2 a write_ma(0x00414046,"7400");
" ?- T$ `9 }6 L- ? write_ma(0x0046EA70,"909090909090");
3 s: T: w& \! {+ o" u, T write_ma(0x0046EA7D,"EB29");# k% ]3 M, \3 M# P6 o& c8 w
write_ma(0x0046EA98,"7500");
7 Q4 z4 c+ q4 {# O6 g: T write_ma(0x0046F7EE,"310578A16500850500A86500750AFF0D90A6650090909090");
& ~9 N. M4 k0 ^6 Z+ U write_ma(0x0046F815,"7400");% c+ r5 f3 M! K. w# q' ~/ [/ y# Y
write_ma(0x0046FA6B,"310578A16500850500A86500750AFF0D90A6650090909090");
+ Y0 F9 R9 U( U$ B% D; E) p write_ma(0x0046FA92,"7400");; `6 c* z- q1 \4 S9 `: q3 Y! B K, y
write_ma(0x00470F2B,"7400");: p2 U/ n: B. r/ e
write_ma(0x00470F43,"EB04");! @ o. Y2 J4 C4 Y7 P- ?+ \/ K7 t0 G
write_ma(0x00470F4B,"EB09");
2 \. H! U# j0 ~6 q) ], G& g; ~+ @+ [ write_ma(0x00471067,"7400");2 [+ I% R3 K$ i3 }4 h, R
write_ma(0x0047107F,"EB04");% [, j" M5 z9 {; Q, v& W
write_ma(0x00471087,"EB09");% W6 O( q* s0 Z j1 m% p
write_ma(0x004C9541,"0F8400000000");5 |7 O+ s; e8 A# u- v& C* _* i3 ^, Q
}
% Y) W i7 U1 q8 T( P: R} |