


修改gmsv制造出我们想要的脚本语句【第二篇】
这次给的图是我自己拼的,把整个函数都拼接起来了,比较方便一点,呵呵妖城在线论坛- C* _7 H: o2 n$ |" O) P1 d* ?1 z
我们上次说到 set_level 这个函数,现在来一句一句分析这个函数的功能,看看gmsv是怎么执行这个脚本改变游戏里面人物的等级的。! l! w# v ^! e- `* M. p# L
: L( c5 ~2 T) z2 J5 ^1 I9 a妖城在线论坛注1:
6 L% z7 J1 q1 f0 v: }上次我说每个子程序的开头都是这样,是为了使用堆栈考虑。下面解释详细些。
2 ~' R& k b+ U: O1 R6 m魔力私服,最新魔力宝贝私服技术交流准确的说是在linux下的gcc编译器在编译gmsv的源程序的时候,—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート7 S+ {: c, D& x* _
(我们现在手上的gmsv不是源程序,而是由源程序编译产生的可执行程序,这个都知道吧 = =!)
& k; t/ x# h* F- m' S& `8 s魔力私服,最新魔力宝贝私服技术交流由编译器的机制导致的,就是说子程序存在注1代码这件事是gcc干的,bbs.mocwww.com0 Y3 c+ d o0 `4 C6 @! g8 X, U# J
(你反编译其他的任何程序,子程序几乎都以这样的语句开头)
6 J( J' A/ B% R& B妖城在线论坛并不是程序编写人想这样。这个跟我们理解程序没什么太大关系(那还说= =!)
1 m$ `" @, i' x9 jbbs.mocwww.com但是我们要知道在每个子程序里面堆栈指针的作用,因为我们的机器没有太多的寄存器给我们用,有很多数据我们必须先放在内存里,
9 V0 O+ T6 K# p }' v. a—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート必要的时候才拿到寄存器里面进行操作或运算。指针esp和ebp就是指向某个内存地址。妖城在线论坛% o4 a. r* p/ Q9 ?
顺便说一下,80x86机器的堆栈是递减的:就是说堆栈的底部是高地址,而堆栈顶部是低地址。(把堆栈想象成一个先进后出的装羽毛球的筒)魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表* ~: L5 g& K3 J
(80x86机器:就是使用IBM80x86指令系统CPU的机器,我们的PC机,只要用的是Intel的CPU都是基于IBM的80x86指令系统)
- h* t. ?5 U: w7 S3 B( ^+ t. h8 xbbs.mocwww.com想了解更详细关于 堆栈 寄存器 的资料请参见我发的那个汇编教程。—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート$ \6 t) a! [ R0 p8 C4 x' W
还有esp前面的e是扩展的意思,是80386以后从16位扩展到了32位的寄存器。
# U3 L3 \! m! E. G1 H6 a/ m魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表在我发的汇编电子书里面寄存器一般是ax,bx,cx,dx,sp,bp等等。—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート% ~+ l" f" \' ^3 U. U4 r
8 _$ ]" S$ x$ g# W3 N6 O3 M, |注2:* L* C8 {& @7 c$ J/ {3 B/ @* R
check_num这个函数不一句一句理解了,这个函数很短,有兴趣自己看下,我说下作用:
! A& o, A0 T) J3 H! _魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表检查一个命令后面是否带的是否是参数(带正负号或者不带正负号的数)。
8 U) v. w8 v4 P—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート这里是数一般是整数。这个函数在这里主要是检测命令所带的参数是否合法。魔力私服,最新魔力宝贝私服技术交流6 J% v# x% n3 f# ]6 M' s
" T/ g! i8 P! ^bbs.mocwww.com注3:bbs.mocwww.com' I0 [$ k' u4 u0 q! p
xor esi,esi 等价于 mov esi,0 就是把esi赋值为0,这个后面有用到。魔力私服,最新魔力宝贝私服技术交流/ }# ]& U- {/ W; y5 h) y
add esp,10h 是把堆栈指针向堆栈底方向移动2个字节。
! d8 b/ X* W. d9 r8 l" s—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート关键:test eax,eax 是把eax跟自己做 按位与(and) 逻辑运算结果不影响eax的值,只影响标志位(跟and不一样的地方)。
9 `4 q+ i6 J+ Qeax如果为0,那么标志位(不知道标志位是啥参见汇编教程)ZF=1,如果是负数,那么标志位SF=1。* ~2 e5 {0 D( r9 S1 M1 k
jz short loc_8121514 如果eax == 0(即ZF==1)则跳转到(short表明是短跳转)loc_8121514处(即绿色线),否则往下执行(红色线)。
( I: \+ L) l) A/ R妖城在线论坛loc_8121514 处很明显,是错误的提示。即 注9 所在的框。魔力私服,最新魔力宝贝私服技术交流/ y# e, {( ]: r& g* W9 @
这里补充一下check_num的返回值:返回的是命令后所带的参数类型,在al里,al是eax(ax)寄存器的低8位。
. L% k ^; Y; u1 q0 \7 {6 O—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート这里的 类型 是如下含义:如果是“+”或者“-”号,则返回他们的ASCII码(见注4),如果是数字,则返回对应的数。
1 C$ q) X* t3 I魔力私服,最新魔力宝贝私服技术交流“如果是数字,则返回对应的数”解释:—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート' G" P: ?$ R. w
比如 setlevel 1,因为gmsv读取到的其实是"1”的ASCII码,即49,那么得减去48(这个操作是在后面的get_num2函数里实现的),妖城在线论坛7 t3 s! u7 \; @1 C2 c3 v
再放到al寄存器里面,才是适合CPU处理的数字“1”。bbs.mocwww.com1 {% _4 A+ l; ?* `
* \5 a# T, }5 w: U: V G妖城在线论坛注4:—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート* l, D, ~% }* j4 W6 H) W
这里两个 cmp,参与比较的是check_num的返回值eax,43是“+”的ASCII码,45是“-”的ASCII码。
1 I9 F4 X6 U! Y4 t魔力私服,最新魔力宝贝私服技术交流首先,第一个 cmp,如果是“+”号,那么跳转到loc_812150C,否则往下执行,即第二个cmp。魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表( z3 a$ C2 `/ H2 c V/ Y
第二个 cmp,如果是“-”号,那么跳转到loc_812150C,否则(既不是“+”也不是“-”),那么往下执行。bbs.mocwww.com7 v; p L+ A3 T- i2 V6 @( |
注意这里的往下执行是红线,即loc_81214B4。
! o$ e/ H+ p) F) y: j3 G0 X5 ~妖城在线论坛
* _: F& l+ M6 P3 O% }: g魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表注5:
+ ]9 i7 `( s9 E, [) V5 K; f/ T1 f0 Jbbs.mocwww.commov esi,1 就是把 1 赋值给 esi。对了!看注3里面,不是esi赋值为0了吗?妖城在线论坛2 E! \7 Y9 r/ y9 y5 a( i9 h7 d0 R
esi在接下来的作用是:当作条件判断跳转,这里后面还会说。
: m0 J# M8 L* N: r- n. i魔力私服,最新魔力宝贝私服技术交流这里,check_num这个函数的影响体现了,就是说:如果脚本参数是不带正负号的数字,那么esi的值是0,如果是带符号的,那么esi的值是1。
. X, E# N% _) \# R# [3 ?魔力私服,最新魔力宝贝私服技术交流看注5的另一部分:test esi,esi 不说了吧?和注3里test一样的。好了,记住这里根据esi不同而又不同的处理(体现在注7)。魔力私服,最新魔力宝贝私服技术交流: [! r. a. W1 ?/ q
魔力私服,最新魔力宝贝私服技术交流4 E% z' N" v2 L0 I
注6:
8 |( {; p U* r) l4 Y妖城在线论坛get_num2这个函数具体也不分析,这里给出这个函数的作用:
- z) C1 [0 _' K* c0 G取得数字适合在寄存器里运算的值。就这么简单。魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表6 k9 Z1 [0 A) m
如果是正数,那么返回在eax里面就是正数;魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表, a4 U% S6 _% Y8 T! H( v, }( T- [
如果是负数(我们写的负数CPU是不认识的,必须这个函数处理之后让CPU认识),那么返回在eax里面就是正数。魔力私服,最新魔力宝贝私服技术交流+ A( y; ?0 y' ]; A W# u* n7 \
* ?3 u7 z+ l) Q; \—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート注7:
! E6 ^6 Y/ e% E% Y& ^—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート我觉得这是函数最重要和最核心的一部分。理解了这里,很多事情就好解决了。bbs.mocwww.com3 Q8 ~) u/ h Y: _4 g' B1 F) |# c- w
先来看这里出现的"2Ch”。转换为10进制是44,我们再翻看数据库的character表,看到等级是在第9栏。
- G( Q- Q& C/ c3 I妖城在线论坛那么这个44是怎么得出的呢?答案是:character表的 (9 + 2) * 4 == 44 == 2Ch。反正记住这个公式就行了。bbs.mocwww.com7 Y0 u/ R' I7 `) @( F1 _
再比如当前人物经验值在character表的42栏,加2为44,再乘以4等于176,转换为16进制是B0。—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート8 A% k. p/ W/ R: |( R! \
因为我们的目的就是加经验,所以这个数后面我们还会说到。
3 E3 `/ e( g- i& e$ A: l9 G) s0 @—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート[ebx+2Ch] 意思是取得ebx+2Ch这个地址处的内存数据。这个内存放的就是人物的当前等级。以后我就说当前等级了。
; F ]4 v1 D6 T2 G+ K* P+ e# L魔力私服,最新魔力宝贝私服技术交流继续正题:—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート2 f# e3 ]4 B6 I
我们看到整个注7是由esi为0或者为1进行跳转的两个分支。bbs.mocwww.com9 p- H6 D+ `2 ~' G* v6 ^; d
我们分析左边的分支(esi=1):
8 l5 G4 y. o8 _- z% [. B k6 Hbbs.mocwww.comadd eax,[ebx+2Ch] 把当前等级加到(get_num2的返回的)eax里面。# L% W5 Y5 t* U, h6 M* T
test eax,eax 将eax跟自己相与。bbs.mocwww.com9 R! P5 V8 B G% h
mov [ebx+2Ch],eax 把eax的值写到当前等级。魔力私服,最新魔力宝贝私服技术交流# Y# v: [- ~% c2 l( x& v
jle short loc_81214FB 如果eax小于等于0则跳转到 注10。
& g; {. V0 }0 |: N右边的分支(esi=0):
- y. D$ k8 ~3 l9 O; Gmov [ebx+2Ch],eax 把eax的值写到当前等级。
3 \6 `* l5 h# q7 z V" ]7 b9 G妖城在线论坛功能:如果参数是一个带符号的数字,把当前等级进行对应的加减(因为eax里面可以是个负数,add负数就是减了嘛)魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表 U0 B9 t2 \: z: y1 @% |1 _) T
如果参数是一个不带符号的数字,直接将当前等级修改成为这个数字。
# n. w7 y# i/ G {1 u1 y
+ N, t0 `, {/ o8 m2 e9 z) ubbs.mocwww.com注8:这个函数没仔细看,但是从名字看是上传(?)人物数据的子程序。必须执行这个子程序人物的当前等级在执行脚本命令后才会变化。7 F, S# g8 S; i- k% }: n7 o
注9:这里是命令格式错误后的处理。不具体说了。魔力私服,最新魔力宝贝私服技术交流) ~% m" ~' V2 D# U7 q& p
+ t6 H, p; S7 ]6 L9 t( a
注10:—魔力私服,魔力宝贝私服技术,DELPHI编程,魔力寶貝, 魔力宝贝, 크로스게이트,クロスゲート: a0 f; v. `( @; O' K
如果等级 变化之后 小于等于0 则跳转到这里。
! g+ b& h$ d0 C7 D魔力私服,最新魔力宝贝私服技术交流mov dword ptr [ebx+2ch],1 将等级强制改成1级。
+ L% n; W( p& N# |, c魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表也就是说实现了等级下限范围的控制,最小等级为1。妖城在线论坛$ T! f/ B0 J% s0 t0 t
#################################################################################
" B9 U+ R) S0 T8 K5 Ybbs.mocwww.com大概就这么多,说了比较多的废话,但是我感觉在理解这个子程序方面还是有点帮助的,呵呵。
. G+ H- n1 o5 ?- I1 I' g2 {, t1 Ebbs.mocwww.com这里说明一下,如果你将注7里面的(其他地方的别改)2C都改成B0,那么你在脚本里面使用setlevel命令的话应该就是:魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表( h7 j% G( M \* r+ \
加或者减或者直接设定经验值为多少。
! o& a/ ^& z4 f$ x9 U但是我们发现这个脚本有2个不好的地方:
5 ^) F9 f. t4 s; h# N3 Y6 d魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表1.等级变化了之后不会有提示,我们想要经验修改之后有提示;魔力私服,最新魔力私服,魔力宝贝私服,魔力宝贝私服技术,魔力宝贝私服,私服架设技术,妖城,FLASH,电影,黑客,网络,网吧,破解,入侵,注册表- F( r, K0 s( T; \
2.只能控制下限或者上限(注7中的jle改成jg就是上限控制了),我们想同时控制上下限。
/ F9 m2 [0 I1 K, d魔力私服,最新魔力宝贝私服技术交流我们下一篇再说另一个函数,更接近于我们理想中加经验的脚本语句的函数。$ y% r g- r0 w4 A4 ~1 F
9 J! q% H+ K% l" X- x3 Zbbs.mocwww.com妖头,我不要精华了……我要威望,嘿嘿……
( Q9 H7 K& R$ J8 ~bbs.mocwww.combbs.mocwww.com* r$ H. P1 i0 O% }* g
[ 本帖最后由 feifei1937 于 2009-8-5 12:30 编辑 ]
附件
-
set_level.jpg
(226.57 KB)
-
2009-8-5 12:26