转至手游
坛里关于手机短信游戏破解的文章有很多,而且很有水平,令人高山仰止!实不想班门弄斧,恐招千夫所指!但HALO2的推出给破解工作带来了许多便利,有必要向新手们介绍下,本人水平有限,文中不足之处请多多包涵!郑重声明:文中所引用的例子谨作为学习交流,并无它意!
用HALO2打开底下城与勇士.jar,点击"类编辑器",在"编辑"选项中选"全文查",在搜索栏中填入"MessageConnection",搜索方式选"By total class",开始搜索!(图1)
坛里关于手机短信游戏破解的文章有很多,而且很有水平,令人高山仰止!实不想班门弄斧,恐招千夫所指!但HALO2的推出给破解工作带来了许多便利,有必要向新手们介绍下,本人水平有限,文中不足之处请多多包涵!郑重声明:文中所引用的例子谨作为学习交流,并无它意!
用HALO2打开底下城与勇士.jar,点击"类编辑器",在"编辑"选项中选"全文查",在搜索栏中填入"MessageConnection",搜索方式选"By total class",开始搜索!(图1)
搜索结果如下:(图2)
其中"类名 j "是指该方法在JAR包根目录下的j.class.
"方法名 f "就是指该方法名为"f" .
"签名"是对该方法的描述,是区别于同一个class文件里同名方法唯一表述.我们反编译j.class,到这个"f"方法,它的起首行"private void f(int i1)"表明它的使用权限为"私有的"(private),而public指公共的,friendly 指友好的,protected指受保护的!具体的说明请参考专业的教材.void是指该方法的返回类型,也就是别的方法调用该方法所得到的东西,void意味着“什么也不返回",但也可返回一些变量值或其它结果.具体的要结合程序分析.比如"boolean"就表示它返回的就是布尔值,即真(true)和假(false).具体的说明也请参考专业的教材.括号里的(int i1)是该方法的自变量列表.自变量列表规定了我们在调用这个方法时传递给它的东西.对于本方法int i1是指:给
其中"类名 j "是指该方法在JAR包根目录下的j.class.
"方法名 f "就是指该方法名为"f" .
"签名"是对该方法的描述,是区别于同一个class文件里同名方法唯一表述.我们反编译j.class,到这个"f"方法,它的起首行"private void f(int i1)"表明它的使用权限为"私有的"(private),而public指公共的,friendly 指友好的,protected指受保护的!具体的说明请参考专业的教材.void是指该方法的返回类型,也就是别的方法调用该方法所得到的东西,void意味着“什么也不返回",但也可返回一些变量值或其它结果.具体的要结合程序分析.比如"boolean"就表示它返回的就是布尔值,即真(true)和假(false).具体的说明也请参考专业的教材.括号里的(int i1)是该方法的自变量列表.自变量列表规定了我们在调用这个方法时传递给它的东西.对于本方法int i1是指:给
该方法传递一个整型变量(int),变量名是i1.
让我们双击这个搜索结果来到j.class下的private void f(int i1)方法.点击这个"f"方法(不是它的下层目录"[0]code"!!! )上面所说的东西如图3.
让我们双击这个搜索结果来到j.class下的private void f(int i1)方法.点击这个"f"方法(不是它的下层目录"[0]code"!!! )上面所说的东西如图3.
以下是反编译后程序:
private void f(int i1)
{
b = i1;
a = false;
MessageConnection messageconnection = null;
Object obj = null;
if(l == 0)
{
h = "sms://" + d[0];
i = "JG " + e + " " + f + "#" + g;
l = 1;
} else
if(l == 1)
{
private void f(int i1)
{
b = i1;
a = false;
MessageConnection messageconnection = null;
Object obj = null;
if(l == 0)
{
h = "sms://" + d[0];
i = "JG " + e + " " + f + "#" + g;
l = 1;
} else
if(l == 1)
{
h = "sms://" + d[1];
i = "62 " + e + " " + f + "#" + g;
l = 0;
}
try
{
TextMessage textmessage;
(textmessage = (TextMessage)(messageconnection = (MessageConnection)Connector.open(h)).newMessage("text")).setPayloadText(i);
messageconnection.send(textmessage);
}
catch(Exception _ex)
{
b = 0;
}
i = "62 " + e + " " + f + "#" + g;
l = 0;
}
try
{
TextMessage textmessage;
(textmessage = (TextMessage)(messageconnection = (MessageConnection)Connector.open(h)).newMessage("text")).setPayloadText(i);
messageconnection.send(textmessage);
}
catch(Exception _ex)
{
b = 0;
}
try
{
messageconnection.close();
}
catch(Exception _ex) { }
a = true;
}
其中:try
{
TextMessage textmessage;
(textmessage = (TextMessage)(messageconnection = (MessageConnection)Connector.open(h)).newMessage("text")).setPayloadText(i);
messageconnection.send(textmessage);
}
catch(Exception _ex)
{
messageconnection.close();
}
catch(Exception _ex) { }
a = true;
}
其中:try
{
TextMessage textmessage;
(textmessage = (TextMessage)(messageconnection = (MessageConnection)Connector.open(h)).newMessage("text")).setPayloadText(i);
messageconnection.send(textmessage);
}
catch(Exception _ex)
{
b = 0;
}是检查是否进行了动作,如果没发送就抛出异常并将变量b赋值为0(b = 0).
而下一段:
try
{
messageconnection.close();
}
catch(Exception _ex) { }
a = true
是检查是否完毕,如果没完毕就抛出异常,如果完毕了就将变量a赋值为 true( a = true).就是说只有a = true才可以享受到后的服务!该方法的任务就是返回a和b两个变量,其他的都是多余的,都可以删除!
b = 0;
}是检查是否进行了动作,如果没发送就抛出异常并将变量b赋值为0(b = 0).
而下一段:
try
{
messageconnection.close();
}
catch(Exception _ex) { }
a = true
是检查是否完毕,如果没完毕就抛出异常,如果完毕了就将变量a赋值为 true( a = true).就是说只有a = true才可以享受到后的服务!该方法的任务就是返回a和b两个变量,其他的都是多余的,都可以删除!
用HALO2的代码编辑修改后,该方法变成了:
aload_0
iload_1
putfield j/b I
aload_0
iconst_1
putfield j/a Z
return
反编译后程序:
private void f(int i1)
{
b = i1;
a = true;
}
我们在模拟器上试验下,发现还是没破解成功!而且屏幕显示"正在购买....请稍等片刻......",和
aload_0
iload_1
putfield j/b I
aload_0
iconst_1
putfield j/a Z
return
反编译后程序:
private void f(int i1)
{
b = i1;
a = true;
}
我们在模拟器上试验下,发现还是没破解成功!而且屏幕显示"正在购买....请稍等片刻......",和
原来的一样!即是说游戏另有陷阱,所以这就是用HALO自动破解失败的原因!
好的那我们换个角度来思考!请看以下这段文字:public static String c[] = {
"购买成功,您的游戏币已增加5000!<br>", "购买成功,欢迎进入体验!<br>", "购买成功,杀伤力已经加倍!<br>", "购买成功,升级后能获得加倍的技能点!<br>", "购买成功,接下来打怪获得的经验值比之前增加一倍!<br>", "购买成功,接下来的强化装备属性100%成功!<br>", "隐藏职业已开启,请返回选择职业!<br>"
这就是成功后所显示的信息!我就想到调用这段文字的方法,看看判断短信发送成功的条件是怎样的.这个方法是静态(static)类型的,在HALO2里就是<clinit>这段:
anewarray java/lang/String
dup
iconst_0
ldc "购买成功,您的游戏币已增加5000!<br>"
aastore
dup
iconst_1
好的那我们换个角度来思考!请看以下这段文字:public static String c[] = {
"购买成功,您的游戏币已增加5000!<br>", "购买成功,欢迎进入体验!<br>", "购买成功,杀伤力已经加倍!<br>", "购买成功,升级后能获得加倍的技能点!<br>", "购买成功,接下来打怪获得的经验值比之前增加一倍!<br>", "购买成功,接下来的强化装备属性100%成功!<br>", "隐藏职业已开启,请返回选择职业!<br>"
这就是成功后所显示的信息!我就想到调用这段文字的方法,看看判断短信发送成功的条件是怎样的.这个方法是静态(static)类型的,在HALO2里就是<clinit>这段:
anewarray java/lang/String
dup
iconst_0
ldc "购买成功,您的游戏币已增加5000!<br>"
aastore
dup
iconst_1
ldc "购买成功,欢迎进入体验!<br>"
aastore
dup
iconst_2
ldc "购买成功,杀伤力已经加倍!<br>"
aastore
dup
iconst_3
ldc "购买成功,升级后能获得加倍的技能点!<br>"
aastore
dup
iconst_4
ldc "购买成功,接下来打怪获得的经验值比之前增加一倍!<br>"
aastore
dup
aastore
dup
iconst_2
ldc "购买成功,杀伤力已经加倍!<br>"
aastore
dup
iconst_3
ldc "购买成功,升级后能获得加倍的技能点!<br>"
aastore
dup
iconst_4
ldc "购买成功,接下来打怪获得的经验值比之前增加一倍!<br>"
aastore
dup
iconst_5
ldc "购买成功,接下来的强化装备属性100%成功!<br>"
aastore
dup
bipush 6
ldc "隐藏职业已开启,请返回选择职业!<br>"
aastore
putstatic j/c [Ljava/lang/String;
最后这句:"putstatic j/c [Ljava/lang/String"的"putstatic"我把它理解为把数据放入寄存器(堆栈?),(我没专门学过任何高级语言,只是小时候玩学习机时,接触了些FBASIC语言.不知这样解释对否?请高手不要见笑!)那getstatic就应该是把数据从寄存器里取出,而j/c [Ljava/lang/String就是存放以上数据的地址的标签.我们在HALO2里的类编辑器搜索j/c [Ljava/lang/String;会有两个结果,其中一个就是上面那段,不用理会.还有个d方法在j.class,即是这段:
private void d()
{
ldc "购买成功,接下来的强化装备属性100%成功!<br>"
aastore
dup
bipush 6
ldc "隐藏职业已开启,请返回选择职业!<br>"
aastore
putstatic j/c [Ljava/lang/String;
最后这句:"putstatic j/c [Ljava/lang/String"的"putstatic"我把它理解为把数据放入寄存器(堆栈?),(我没专门学过任何高级语言,只是小时候玩学习机时,接触了些FBASIC语言.不知这样解释对否?请高手不要见笑!)那getstatic就应该是把数据从寄存器里取出,而j/c [Ljava/lang/String就是存放以上数据的地址的标签.我们在HALO2里的类编辑器搜索j/c [Ljava/lang/String;会有两个结果,其中一个就是上面那段,不用理会.还有个d方法在j.class,即是这段:
private void d()
{
switch(d)
{
case 2: // '\002'
default:
break;
case 0: // '\0'
String s = "";
switch(e)
{
case 2: // '\002'
s = s + "购买后伤害倍数为:" + 2 * a.cF + "倍";
break;
case 4: // '\004'
{
case 2: // '\002'
default:
break;
case 0: // '\0'
String s = "";
switch(e)
{
case 2: // '\002'
s = s + "购买后伤害倍数为:" + 2 * a.cF + "倍";
break;
case 4: // '\004'
s = s + "购买后经验值倍数为:" + 2 * a.cE + "倍";
break;
case 3: // '\003'
s = s + "购买后技能点倍数为:" + 2 * a.cG + "倍";
break;
}
a.a(c[e] + s, b[1], b[2], b[3], b[4]);
a(-2, 4);
d = 1;
return;
其中"a.a(c[e] + s, b[1], b[2], b[3], b[4]);"调用了j/c [Ljava/lang/String;具体代码为
getstatic j/c [Ljava/lang/String;意思是取出这段文字!
这个private void d()方法又被谁调用的?我们再往上,而private void d()的标签是"j/d()V". "j"表示该方法位于JAR包根目录下的j.class."/d"表示它的方法名."()"表示调用该方法时没有东
break;
case 3: // '\003'
s = s + "购买后技能点倍数为:" + 2 * a.cG + "倍";
break;
}
a.a(c[e] + s, b[1], b[2], b[3], b[4]);
a(-2, 4);
d = 1;
return;
其中"a.a(c[e] + s, b[1], b[2], b[3], b[4]);"调用了j/c [Ljava/lang/String;具体代码为
getstatic j/c [Ljava/lang/String;意思是取出这段文字!
这个private void d()方法又被谁调用的?我们再往上,而private void d()的标签是"j/d()V". "j"表示该方法位于JAR包根目录下的j.class."/d"表示它的方法名."()"表示调用该方法时没有东
西传递给它,所以括号里是空的."V"表示该方法返回类型是void,V就是void的缩写.或者点击图3标签前面进入常量池,用"ctrl+c"复制标签(需自己添加路径和方法名),再用"ctrl+v"粘贴到搜索栏里!经过搜索发现public final void a(Graphics g1)调用了private void d()方法.如下:
public final void a(Graphics g1)
{
f++;
j++;
k++;
g1.setFont(k.a);
switch(c)
{
case 0: // '\0'
b();
b(g1);
break;
public final void a(Graphics g1)
{
f++;
j++;
k++;
g1.setFont(k.a);
switch(c)
{
case 0: // '\0'
b();
b(g1);
break;
case 2: // '\002'
c();
c(g1);
break;
case 10: // '\n'
d();
d(g1);
break;
case 11: // '\013'
e();
e(g1);
break;
}
i = 0;
}
分析后得知:只有变量c = 10时,程序才能执行private void d()方法,即:
case 10: // '\n'
d();
d(g1);
break;
就是说只有c = 10,程序才会认为短信发送成功!变量c的标签是 j/c I,后面的"I"表示该变量的数据类型.现在我们回到那个的方法private void f(int i1),看看变量c是如何变化的!经过搜索发现方法private void f(int i1)被public final void a()调用,而public final void a()又被r.class的public final void run()调用了,run()方法是Thread(线程)类下的,可以使用thread的start方法来调用它.那我们搜索谁调用run()方法时在搜索栏里输入"invokevirtual java/lang/Thread/start()V"经过搜索发现有4个结果,分析后只有j.class下的private void e(int i1)方法调用了r.class的public final void run().那我们看下private void e(int i1)方法:
i = 0;
}
分析后得知:只有变量c = 10时,程序才能执行private void d()方法,即:
case 10: // '\n'
d();
d(g1);
break;
就是说只有c = 10,程序才会认为短信发送成功!变量c的标签是 j/c I,后面的"I"表示该变量的数据类型.现在我们回到那个的方法private void f(int i1),看看变量c是如何变化的!经过搜索发现方法private void f(int i1)被public final void a()调用,而public final void a()又被r.class的public final void run()调用了,run()方法是Thread(线程)类下的,可以使用thread的start方法来调用它.那我们搜索谁调用run()方法时在搜索栏里输入"invokevirtual java/lang/Thread/start()V"经过搜索发现有4个结果,分析后只有j.class下的private void e(int i1)方法调用了r.class的public final void run().那我们看下private void e(int i1)方法:
private void e(int i1)
{
if(i1 == 0)
{
c(2);
Thread thread;
(thread = new r(this)).start();
f = 0;
return;
}
它在(thread = new r(this)).start()前先调用了c方法(c(2);),并且给c方法传递了一个整数"2",而c方法的标签是 j/c(I)V ,就是如下的方法:
private void c(int i1)
{
c = i1;
{
if(i1 == 0)
{
c(2);
Thread thread;
(thread = new r(this)).start();
f = 0;
return;
}
它在(thread = new r(this)).start()前先调用了c方法(c(2);),并且给c方法传递了一个整数"2",而c方法的标签是 j/c(I)V ,就是如下的方法:
private void c(int i1)
{
c = i1;
d = 0;
j = -1;
k = -1;
}
里面的变量c就是我们上面提到的,"c = i1;"就是变量c的值等于给c方法传递的那个整数"2".我们只要把private void e(int i1)方法里的c(2)改为c(10)就完成破解了!可能有人问private void e(int i1)方法和public final void a(Graphics g1)方法没关联啊!你只要继续搜索private void e(int i1)的调用者就发现public final void a(Graphics g1)最终调用了private void e(int i1),我就不一一介绍了!我对这个游戏有些疑问,按我的理解这个游戏哪怕是正常的也无法成功开启服务的啊!难到还有其他机关?想请教下BB,飞鹰,KIM这些高手们,这也是我用这个游戏作例子的目的!因本人水平有限,文中不足之处也请赐教!
本来还想用雪鲤鱼的几个短信+联网收费游戏做例子,介绍下破解简单联网收费游戏的一些心得,但本文的篇幅已超出预计了,唯有等有空再发上来了,说实话,写教材太难了,打字都打得手痛了!我写这篇文章只是希望朋友们能了解下HALO2的搜索功能.对于破解的思路和方法,各人有各人的方法,目前论坛里发的破解版使用的方法就比我的好.呵呵,当时我破解是为了移植到
j = -1;
k = -1;
}
里面的变量c就是我们上面提到的,"c = i1;"就是变量c的值等于给c方法传递的那个整数"2".我们只要把private void e(int i1)方法里的c(2)改为c(10)就完成破解了!可能有人问private void e(int i1)方法和public final void a(Graphics g1)方法没关联啊!你只要继续搜索private void e(int i1)的调用者就发现public final void a(Graphics g1)最终调用了private void e(int i1),我就不一一介绍了!我对这个游戏有些疑问,按我的理解这个游戏哪怕是正常的也无法成功开启服务的啊!难到还有其他机关?想请教下BB,飞鹰,KIM这些高手们,这也是我用这个游戏作例子的目的!因本人水平有限,文中不足之处也请赐教!
本来还想用雪鲤鱼的几个短信+联网收费游戏做例子,介绍下破解简单联网收费游戏的一些心得,但本文的篇幅已超出预计了,唯有等有空再发上来了,说实话,写教材太难了,打字都打得手痛了!我写这篇文章只是希望朋友们能了解下HALO2的搜索功能.对于破解的思路和方法,各人有各人的方法,目前论坛里发的破解版使用的方法就比我的好.呵呵,当时我破解是为了移植到
我的MOTO 小C上的,但这游戏的内存要求太高了,我的小C没法运行.dnf安全模式解除bug我就没留意到这个破解版,走了些弯路!
发布评论