吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 20655|回复: 58
收起左侧

[Android 分享] 安卓游戏破解之分支跳转(修改分析)

[复制链接]
傲世V雄哥720 发表于 2014-11-18 12:42
本帖最后由 傲世V雄哥720 于 2014-11-20 16:27 编辑

【安卓smali破解之分支跳转(修改分析)】


终极冒险岛智能版。
存在箱底下很久了。



为什么会存在箱底很久无法破解。下面有原因的。

修改成功。下面是修改流程。
也就是今天要讲的;分支跳转修改方法。

首先;
测试游戏提示;
游戏卡死在  发送中
所以直接搜;发送中。
看到如下代码;↓这就是它的整个方法的验证系统。

(Pswitch)

[Asm] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
.method public logic_activate()V
    .locals 8
 
    const/4 v7, 0x2
 
    const/4 v6, 0x1
 
    const/high16 v5, 0x800
 
    const/4 v4, 0x0
 
    const/16 v3, 0x32
 
    sget v0, Lcom/FrameWork/Screen_Main;->activate:I
 
    goto/16 :goto_1    #【注释:这里就是添加的强制代码】
 
    packed-switch v0, :pswitch_data_0
 
    :cond_0
    :goto_0
    return-void
 
    :pswitch_0
    iget-boolean v0, p0, Lcom/FrameWork/Screen_Main;->b:Z
 
    if-nez v0, :cond_0
 
    iget v0, p0, Lcom/FrameWork/Screen_Main;->curPage:I
 
    packed-switch v0, :pswitch_data_1
 
    goto :goto_0
 
    :pswitch_1
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_1
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_WIDTH:I
 
    add-int/2addr v0, v1
 
    sub-int/2addr v0, v3
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_1
 
    invoke-static {v7}, Lcom/FrameWork/GameScreen;->changeSubScreen(I)V
 
    goto :goto_0
 
    :cond_1
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    iput v6, p0, Lcom/FrameWork/Screen_Main;->curPage:I
 
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, ""是否确认购买正版验证?"
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto :goto_0
 
    :pswitch_2
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_2
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_WIDTH:I
 
    add-int/2addr v0, v1
 
    sub-int/2addr v0, v3
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_2
 
    iput v4, p0, Lcom/FrameWork/Screen_Main;->curPage:I
 
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "购买正版验证,可获得游戏后续关卡,信息费5元(不含通信费),通过短信代收,是否确认购买?"
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto :goto_0
 
    :cond_2
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    invoke-virtual {p0}, Lcom/FrameWork/Screen_Main;->sendMessage()V
 
    iput-boolean v6, p0, Lcom/FrameWork/Screen_Main;->b:Z
 
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "发送中...."
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto/16 :goto_0
 
    :pswitch_3
    sput v4, Lcom/FrameWork/Screen_Main;->activate:I
 
    goto/16 :goto_0
 
    :pswitch_4
    invoke-static {v7}, Lcom/FrameWork/GameScreen;->changeSubScreen(I)V
 
    sput v4, Lcom/FrameWork/Screen_Main;->activate:I
 
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
 
    new-instance v1, Ljava/lang/StringBuilder;
 
    const-string v2, "ACTIVATE_CANCEL======"
 
    invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
 
    sget v2, Lcom/FrameWork/Screen_Main;->activate:I
 
    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
 
    move-result-object v1
 
    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
 
    move-result-object v1
 
    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
 
    const/4 v0, -0x1
 
    invoke-static {v4, v0}, Lcom/FrameWork/GameScreen;->setSaveGameInt(II)V
 
    const/16 v0, 0x8
 
    sget v1, Lcom/FrameWork/Screen_Main;->activate:I
 
    invoke-static {v0, v1}, Lcom/FrameWork/GameScreen;->setSaveGameInt(II)V
 
    invoke-static {v6}, Lcom/FrameWork/GameScreen;->saveSave(I)V
 
    goto/16 :goto_0
 
    :goto_1    【#注释:goto_1跳向了这里。成功】
    :pswitch_5
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "游戏激活成功! "
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_WIDTH:I
 
    add-int/2addr v0, v1
 
    sub-int/2addr v0, v3
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    sget v0, Lcom/FrameWork/Screen_Main;->curStageNumber:I
 
    add-int/lit8 v0, v0, 0x1
 
    invoke-direct {p0, v0}, Lcom/FrameWork/Screen_Main;->changeToSelectStage(I)V
 
    const/16 v0, 0x8
 
    sget v1, Lcom/FrameWork/Screen_Main;->activate:I
 
    invoke-static {v0, v1}, Lcom/FrameWork/GameScreen;->setSaveGameInt(II)V
 
    invoke-static {v6}, Lcom/FrameWork/GameScreen;->saveSave(I)V
 
    goto/16 :goto_0
 
    :pswitch_6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
 
    const-string v1, "ACTIVATE_ERROR"
 
    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
 
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
 
    new-instance v1, Ljava/lang/StringBuilder;
 
    const-string v2, "erroCode==="
 
    invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
 
    sget v2, Lcom/FrameWork/Screen_Main;->erroCode:I
 
    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
 
    move-result-object v1
 
    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
 
    move-result-object v1
 
    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
 
    sget v0, Lcom/FrameWork/Screen_Main;->erroCode:I
 
    packed-switch v0, :pswitch_data_2
 
    :goto_2
    invoke-static {v5}, Lcom/FrameWork/GameScreen;->isInputDown(I)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    sget v0, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_X:I
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_WIDTH:I
 
    add-int/2addr v0, v1
 
    sub-int/2addr v0, v3
 
    sget v1, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_OFFSET_Y:I
 
    sget v2, Lcom/FrameWork/Screen_Main;->LOGIC_SCREEN_HEIGHT:I
 
    add-int/2addr v1, v2
 
    sub-int/2addr v1, v3
 
    invoke-static {v0, v1, v3, v3}, Lcom/FrameWork/GameScreen;->touchLogic(IIII)Z
 
    move-result v0
 
    if-eqz v0, :cond_0
 
    invoke-static {v7}, Lcom/FrameWork/GameScreen;->changeSubScreen(I)V
 
    sput v4, Lcom/FrameWork/Screen_Main;->activate:I
 
    const/4 v0, -0x1
 
    invoke-static {v4, v0}, Lcom/FrameWork/GameScreen;->setSaveGameInt(II)V
 
    const/16 v0, 0x8
 
    sget v1, Lcom/FrameWork/Screen_Main;->activate:I
 
    invoke-static {v0, v1}, Lcom/FrameWork/GameScreen;->setSaveGameInt(II)V
 
    invoke-static {v6}, Lcom/FrameWork/GameScreen;->saveSave(I)V
 
    goto/16 :goto_0
 
    :pswitch_7
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "发送短信失败后未使用联网计费。"
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto :goto_2
 
    :pswitch_8
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "联网失败,请查看网络设置。"
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto :goto_2
 
    :pswitch_9
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;
 
    const-string v1, "Android手机未使用CMWAP计费"
 
    invoke-virtual {v0, v1}, LhlLib/HLTextBox;->setText(Ljava/lang/String;)V
 
    goto :goto_2
 
    nop
 
    :pswitch_data_0
    .packed-switch 0x0
        :pswitch_0
        :pswitch_3
        :pswitch_5
        :pswitch_4
        :pswitch_6
    .end packed-switch
 
    :pswitch_data_1
    .packed-switch 0x0
        :pswitch_1
        :pswitch_2
    .end packed-switch
 
    :pswitch_data_2
    .packed-switch 0x6
        :pswitch_7
        :pswitch_8
        :pswitch_9
    .end packed-switch
.end method




图上的代码是修改后的。

代码头的分支判断跳转;
    packed-switch v0, :pswitch_data_0

这一个分支判断。当游戏弹出购买→选择下一步的时候,它就会来到这里。

来到这里后,然后跳转到底部如下代码。

[Asm] 纯文本查看 复制代码
1
2
3
4
5
6
7
8
:pswitch_data_0
 .packed-switch 0x0
     :pswitch_0
     :pswitch_3     (CANCEL)
     :pswitch_5  (成功激活)
     :pswitch_4  (失败)
     :pswitch_6    (联网错误)
 .end packed-switch




然后pswitch_data_0,判断;购买成功失败。返回结果如果是成功。
成功会来到 pswitch_5  .

因为它的失败混淆了。没有;失败字样。
所以。我们在判断的前面
加上一个代码。

强制跳向成功。
成功的源头是;pswitch_5

所以在上面的代码;修改;

    goto/16 :goto_1

    packed-switch v0, :pswitch_data_0


goto/16 :goto_1
跳向了;pswitch_5  (成功)
所以。购买→确定→直接成功。


总结一下吧。

分支判断的游戏(验证系统。)
修改方法;
在它判断的地方。前面加上goto进行强制跳转。跳向成功。

另外要注意;
goto的使用。
假如成功的源头是;switch_99298
因为它后面是5位数。goto/4不够用。所以用goto/16
也就是说改的时候。如果goto对应分支位数不足。那么就会出错。

【goto分为;goto    goto/4     goto/16   goto/32】
【goto在代码里的应用:无条件跳转(向)

分支跳转(pswitch)我研究了下。它不能和条件判断跳转(if-eqz)一样。删掉失败跳转。跳向成功。
分支只能强制goto跳转。
分支如果删掉的话。当代码来到这里的时候会卡死。无响应。




这个冒险岛改掉了。先上截图。然后发附件。

游戏个人感觉还不错。这次就把破解版的附件发上来吧。

游戏截图;
3.png

2.png

5.png


7.png

9.png



11.png




12.png



说明;点击内购→直接如图中的;激活成功。点击返回。即可。
如果卡住。多点几次返回。

附件不是主要。我讲的主要是;分支判断如何去修改。破解。
如果各位有什么问题可以到本贴提问。

下载说明;
这有2个版的冒险岛。1版和2版。都放在压缩包里了。解压即可。

下载地址:


链接: http://pan.baidu.com/s/1hquy8kO

密码: ggkl








免费评分

参与人数 3热心值 +3 收起 理由
qwe1154323937 + 1 谢谢@Thanks!
chaojiak47 + 1 我很赞同!
巅烽2 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

qwe1154323937 发表于 2014-11-24 21:38
傲世V雄哥720 发表于 2014-11-23 06:56
smali就不做教程了。

学习完ARM汇编就制作教程。

   用APKIDE找关键字看的代码太复杂了  , 有的改了不行  有的改了还进不去游戏 =、=   现在很难找到教程什么的   愿大大 出个教程什么的  谢谢!!
 楼主| 傲世V雄哥720 发表于 2014-11-18 19:16
本帖最后由 傲世V雄哥720 于 2014-11-18 19:17 编辑
mgsjh 发表于 2014-11-18 18:40
是直加
    goto/16 :goto_1    #【注释:这里就是添加的强制代码】

是吧。
smali代码是写一行空一行。

goto/16 :goto_1
这个是成功的源头是1
所以是goto_1

如果成功是
pswitch_5
那么goto就是
goto/16 :pswitch_5
lixingcong 发表于 2014-11-18 12:46
淡然出尘 发表于 2014-11-18 12:51
假如成功的源头是;switch_99298
因为它后面是5位数。goto/4不够用。所以用goto/16


赞一个

免费评分

参与人数 1热心值 +1 收起 理由
Dlan + 1 膜拜

查看全部评分

Avenshy 发表于 2014-11-18 13:09
安卓破解初始阶段。。至今不会用IDA调戏so文件。。
Taurus初心 发表于 2014-11-18 13:27 来自手机
好厉害,长知识了
851518232 发表于 2014-11-18 13:33
APK代码很难懂的样子
Kesuen 发表于 2014-11-18 14:09
学习了,刚刚学习很多需要慢慢研究。。
JK52PJ 发表于 2014-11-18 14:16
多谢楼主分享。
hzgg676102014 发表于 2014-11-18 14:34 来自手机
为什么看起来那么复杂
guanggao 发表于 2014-11-18 14:38
谢楼主分享
谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-8 22:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表