站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2ME 专题手机游戏修改(5)Switch之tableswitch

手机游戏修改(5)Switch之tableswitch

摘要: 手机游戏修改(5)Switch之tableswitch
<tr><td>
http:///tech/article2123.html
[转载于纸墨聊斋]
原文:http://blog.xdnice.com/user1/151/index.shtml
作者:紫陌

在上一篇中我们讲到if(i==-6)的修改方法,一般情况下,程序处理按键的命令会采用两种选择方式,一种是if,另一种就是case,也就是switch开关。

我们来看下面的一段代码:

switch(getGameAction(i1))
[] {
case 3: // '\003'
case 4: // '\004'
case 7: // '\007'
default:
break;

case 8: // '\b'
if(M == 0)
{
i();
break;
}
[] if(M == 1)
k();
break;

case 1: // '\001'
k = ((k - 1) + 8) % 8;
i = a(F, k);
break;

case 6: // '\006'
k = (k + 1) % 8;
i = a(F, k);
break;

case 2: // '\002'
[] F = ((F - 1) + 10) % 10;
i = a(F, k);
break;
[]
case 5: // '\005'
F = (F + 1) % 10;
i = a(F, k);
break;
}

这段代码也是比较简单的,如果你能够看明白,那么恭喜您。如果你看不太明白也没有关系,下面我们来大致分析一下这段代码。

il在这里也是keycode值,第一句中getgameaction(i1)就是说取得i1这个按键所对应的gameaction值,也就是我们前面讲过的游戏动作值。前面说过,游戏动作值只有9个,就是1、2、5、6、8、9、10、11、12。我们看上面的代码,里面出现了case 3、case 4、case 7、case 1、case 2、case 5、case 6、case 8等选择句,我们知道1、2、5、6、8分别对应着上、左、右、下、确定(出拳)的操作,所以这段代码处理的是游戏操作的响应问题。而3、4、7不属于gameaction,所以一开始就有,case 3、case 4、case 5、break的语句。当然了,一般情况下,我们是不需要修改这些按键的,但为了举例,我们还是试着来修改一下吧。

我们按照前面的方法,在IDA的IDA VIEW窗口中我们找到如下的对应代码:

met026_113: ; CODE XREF: keyPressed+81j
aload_0 ; var026_0
iload_1 ; var026_1
invokevirtual getGameAction(I)I
tableswitch 1 to 8 default met026_324
[] {
met026_193
met026_260
met026_324
met026_324
met026_295
met026_228
met026_324
[] met026_164
}


下面我们来分析一下以上代码的意思:

第一行与最后几行的“met026_XXX”是卷标,就是“label”。

第四行出现了GetGameAction,这个东西就是我们源程序中switch(getgameaction(i1))中的那个,你看,源代码与中间代码是不是相互对应的呢?凡是源代码里面出现的变量名,数字,以及函数等都会在中间代码中显示出来。

[]下面一句,对我们来说,是最重要的,也是最有用的。我们来看:

tableswitch 1 to 8 default met026_324
[]
这里的“tableswitch”就是我们在源代码中看到的switch开关,你看,很方便吧,源代码和中间代码是对应的呀。如果我们要寻找switch,我们只需要在IDA里面查找就可以了,很快就可以找到switch的。至于这里为什么会有tableswitch,而不直接用switch, 这是因为在中间代码里还有一种switch 叫做lookupswitch,这个我们后面会提到。

那我们接着来分析这句话:tableswitch, 我们知道table是有表格的意思,实际上我们可以把它翻译成开关表,或者选择表,或者别的什么,只要便于我们理解就行。tableswitch 说明后面跟着一个开关表,1 to 8 说明这个开关表是由1到8这8个数字控制转向的,而后面的default met026_324,我们上面说了,met026_324是一个卷标,它的意思是说:默认情况下,会执行met026_324这一行的指令。

[]我们接着看,大括号里面的东西,看明白了吧,是八个label,它们分别对应着1-8这两个数,也就是说,如果gameaction的值是1的话,就执行第一个label所指向的那一行的指令,如果gameaction的值是2的话,就执行第二个label所指向的那一行的指令。以至类推。

理解了这段代码的含义,我们也许就想了,如果我想把1和2执行的命令对换一下的话,那么我们将这两个label的位置互换一下不就可以了吗?确实是这样。我们接下来要做的就是互换label,但我们还不能在中间代码里来更换,我们需要切换到2进制窗口来查看它所对应的字节码(二进制),然后更在二进制编辑工具里面对字节码进行修改。

我们在这里选中tableswitch,切换到HEX-view 窗口,我们看到如下的一段二进制码已经被选中了:

AA 00-00 00 00 CE 00 00 00 01

00 00 00 08 00 00 00 4B-00 00 00 8E 00 00 00 CE
[]
00 00 00 CE 00 00 00 B1-00 00 00 6E 00 00 00 CE
[]
00 00 00 2E

在字节码文件里,或者二进制文件里,每一行一般有16个字节,我们这里选择的这一部分,就是对应于上面的那个tableswitch的。我们来解释一下这个东西:

AA 是tableswitch的意思,这里的AA就等于中间代码里的tableswitch,前面我们提到10等于中间代码里的bipush,是一个道理。在字节码文件里,所有的指令全都是以十六进制数的形式表现出来的。在tableswitch里面,每4个字节为一条指令,我们可以看到在AA00后面有一个“-”,这个我们可以看成是一种分割符,它告诉我们,它后面的4个字节是一起的。至于AA,它一般后面会跟00、00 00、或者 00 00 00,这个是不确定的,视具体的情况而定。

AA 00 - 后面的4个字节为00 00 00 CE,它出现在AA的后面,实际是一个卷标,或者说是label,有人也叫偏移量。它的意思是说,默认情况下,就跳到这个00 00 00 CE对应的那个地方执行相应的指令。

接着,后面00 00 00 01 00 00 00 08,这8个字节,实际就是指1 和8 ,也就是说,它告诉我们我们可以选择的数为1到8,这8个数字。

接下来的部分,实际上仍然是label。它们分别以4个字节为单位,分别对应着1到8的所指向的label。

以上就是AA(tableswitch)这个开关在字节码里面的结构。我们弄清了它的结构以后,就可以通过修改字节码来达到我们修改游戏的目的了。

为了加深印象,我们再来总结一下AA的结构。
[]
最前面是AA加上1到3个00,说明这是一个tabelswitch,也就是我们说的开关表。

紧跟在AA后面的是默认要执行的指令的卷标,或者叫偏移量。

然后的8个字节说明了开关表的两端,比如从1到8,就会分别用这两个数字的十六进制来表示出来 :00000001 00000008

最后呢,就是对应于这些开关数字的卷标,比如开关里面有8个数字,后面就会跟上8个卷标,如果有10个数字,就会跟上10个卷标。我们在修改的时候一定要注意保证他们之间的对应关系。如果我们前面定义了9个数字,而后面只跟了8个卷标。那么,程序肯定是无法运行的,因为这个开关表是有问题的。
[]
好了,现在我们来修改一下吧。比如我们要把1和2执行的命令对换,我们就只需要把1和2对应的卷标对换一下就开始了。

AA 00-00 00 00 CE 00 00 00 01

00 00 00 08 00 00 00 4B-00 00 00 8E 00 00 00 CE
[]
00 00 00 CE 00 00 00 B1-00 00 00 6E 00 00 00 CE

00 00 00 2E

1对应的的卷标是红色的00 00 00 4B,2对应的是蓝色的00 00 00 8E,现在我们把它们对换一下吧。
[]
AA 00-00 00 00 CE 00 00 00 01

[]00 00 00 08 00 00 00 8E-00 00 00 4B 00 00 00 CE

[]00 00 00 CE 00 00 00 B1-00 00 00 6E 00 00 00 CE
[]
00 00 00 2E

这样,我们就把1和2对应的卷标更换好了,那么我们前面讲过gameaction中1和2分别代表什么呢?1 是代表向上,2 是代表向左,那就是说,当我们按向上键的时候,游戏里的操作正好是向左,而当我们按左键的时候,游戏里的操作正好是向上。是不是这样呢?大家回去自己实践一下吧。

[]可能有的人会问这样的问题,如果我想按9的时候扫行1的指令,那怎么办呢?这个开关表里面没有出现9呀,我们怎么更换卷标呢?我们将在下一篇里接着介绍switch开关的另一种形式:lookupswitch,敬请期待。

好了,今天就讲到这里了,等我回到学校以后,再接着来叨唠吧,祝我一路顺风吧。
http:///tech/article2123.html
</td></tr></table></td> </tr> <tr> <td background="/pic/split.gif" height=1></td> </tr> <tr> <td class="tdMargin1">
↑返回目录
前一篇: 手机游戏修改(6)switch之lookupswitch
后一篇: 手机游戏修改(4)按键的修改实践