737672679 发表于 2014-11-18 13:05:45

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

本帖最后由 水波摇曳 于 2014-11-18 13:34 编辑

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


终极冒险岛智能版。
存在箱底下很久了。所以。刚刚停电,(手机端)就开始修改。



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

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

首先;
测试游戏提示;
游戏卡死在发送中...
所以直接搜;发送中。
看到如下代码;↓
.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, "\u662f\u5426\u786e\u8ba4\u8d2d\u4e70\u6b63\u7248\u9a8c\u8bc1\uff1f"

    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, "\u8d2d\u4e70\u6b63\u7248\u9a8c\u8bc1\uff0c\u53ef\u83b7\u5f97\u6e38\u620f\u540e\u7eed\u5173\u5361\uff0c\u4fe1\u606f\u8d395\u5143\uff08\u4e0d\u542b\u901a\u4fe1\u8d39\uff09\uff0c\u901a\u8fc7\u77ed\u4fe1\u4ee3\u6536\uff0c\u662f\u5426\u786e\u8ba4\u8d2d\u4e70\uff1f"

    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, "\u53d1\u9001\u4e2d..."

    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
    :pswitch_5
    iget-object v0, p0, Lcom/FrameWork/Screen_Main;->activateBox:LhlLib/HLTextBox;

    const-string v1, "\u6e38\u620f\u6fc0\u6d3b\u6210\u529f\uff01 720Tsk688\u4fee\u6539\u5206\u4eab "

    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, "\u53d1\u9001\u77ed\u4fe1\u5931\u8d25\u540e\u672a\u4f7f\u7528\u8054\u7f51\u8ba1\u8d39\u3002"

    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, "\u8054\u7f51\u5931\u8d25\uff0c\u8bf7\u67e5\u770b\u7f51\u7edc\u8bbe\u7f6e\u3002"

    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\u4f7f\u7528CMWAP\u9519\u8bef\u3002"

    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




然后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对应分支位数不足。那么就会出错。


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




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

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

游戏截图;











说明;点击内购→直接如图中的;激活成功。点击返回。即可。
如果卡住。多点几次返回。SEND.SMS权限已去掉。

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

刚刚的代码太长。、乱码了。。
不过不影响分析。



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

下载地址:


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

密码: ggkl










默小坑 发表于 2014-11-22 19:38:31

支持

myoldid 发表于 2014-12-15 16:49:54

意思就是不做比较直接跳向pswitch_5么?

737672679 发表于 2014-12-16 14:17:14

myoldid 发表于 2014-12-15 16:49
意思就是不做比较直接跳向pswitch_5么?

方法。你懂不?

一个方法。如果不展示出来。你懂吗?

人们认为的。,不可能的就不会去尝试。

这个词就叫做:实践

lk5261 发表于 2014-12-16 16:58:36

这个还好破解:)
页: [1]
查看完整版本: [Android] 安卓游戏破解之分支跳转(修改分析)