首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DalvikVM如何处理切换和尝试smali代码

DalvikVM如何处理切换和尝试smali代码
EN

Stack Overflow用户
提问于 2012-12-31 19:30:25
回答 1查看 4.2K关注 0票数 8

我正在努力学习smali,我有几个问题,我在谷歌上找不到。

1)我创建了一个简单的测试用例来更好地解释我自己

代码语言:javascript
复制
const-string v1, "Start"
:try_start_0
const-string v1, "Try Block"
invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0

.catch语句:这两个参数是指从标签到标签并捕获它(两个标签之间的代码),还是意味着从:try_start_0开始执行try,直到它到达:try_end_0 (允许goto跳转执行两个标签之外的代码)?

try的标签是否始终采用try_start_%d格式,或者它们可以是任何标签?

2)另一种情况

代码语言:javascript
复制
packed-switch v0, :pswitch_data_0

const-string v1, "Default Case"

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V

:goto_0

const-string v1, "The End"

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V

return-void

:pswitch_0
const-string v1, "Case 1"

invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V

goto :goto_0

:pswitch_data_0
.packed-switch 0x1
:pswitch_0
.end packed-switch

switch语句:是否要求switch语句位于switch数据和switch调用之间?另外,标签的命名也是固定的,还是只是为了方便?

3)如果标签可以不同,baksmali会产生具有不同标签的smali代码吗?

4)在反编译dex时,哪些可选行并不总是显示出来?

我知道.parameter和.line是可选的,但是哪些是可能不存在的呢?

提前谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-01 01:57:19

1)

前两个标签(在您的示例中为try_start_0和try_end_0 )定义了try块涵盖的代码范围。如果覆盖的代码中发生异常,则执行会立即跳转到第三个标签(catchall_0)。标签的名称并不重要,它可以是任何有效的标识符。

还有.catch指令,除了它只处理特定类型的异常(类似于java的catch语句)之外,它也是一样的。

一个代码块可以被多个catch语句覆盖,最多一个catch all语句。.catch语句的位置并不重要,但是覆盖相同代码的catch语句的相对顺序是import。例如,如果您有

代码语言:javascript
复制
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :handler1
.catch Ljava/lang/RuntimeException; {:try_start_0 .. :try_end_0} :handler2

第二个catch语句永远不会被使用。如果在覆盖的代码中抛出RuntimeException,则将始终使用第一个catch,因为RuntimeException是一个例外。

但是,如果它们的顺序相反,它将按照您的预期工作- RuntimeException处理程序用于RuntimeExceptions,而异常处理程序用于任何其他类型的异常。

最后,与java不同的是,.catch语句中的代码范围不需要严格嵌套。例如,拥有这样的东西是完全合法的

代码语言:javascript
复制
:a
const-string v1, "Start"
:b
const-string v1, "Try Block"
:c
invoke-static {v1}, Lcom/example/test/Main;->print(Ljava/lang/String;)V
:d
.catch Ljava/lang/RuntimeException; {:a .. :c} :d
.catch Ljava/lang/Exception; {:b .. :d} :d

你也可以有一些非常奇怪的结构,像这样。

代码语言:javascript
复制
.method public static main([Ljava/lang/String;)V
    .registers 3

    :second_handler
    :first_try_start
        new-instance v0, Ljava/lang/RuntimeException;
        invoke-direct {v0}, Ljava/lang/RuntimeException;-><init>()V
        throw v0
    :first_try_end
    .catch Ljava/lang/Exception; {:first_try_start .. :first_try_end} :first_handler
    :first_handler
    :second_try_start
        new-instance v0, Ljava/lang/RuntimeException;
        invoke-direct {v0}, Ljava/lang/RuntimeException;-><init>()V
        throw v0
    :second_try_end
    .catch Ljava/lang/Exception; {:second_try_start .. :second_try_end} :second_handler
.end method

上面的两个例子都不会从编译的java代码中生成,但是字节码本身允许这样做。

2) switch语句可以在与switch语句或switch数据相关的任何位置。这里的标签名称也是任意的。

3) Baksmali可以通过两种方式之一生成标签。默认方式是使用标签的通用“类型”,并附加标签的字节码地址。如果您指定-s/--sequential labels选项,而不是使用字节码地址,它将为每个标签类型保留一个计数器,并在每次生成该类型的标签时递增该计数器。

4)通常是调试信息的一部分。.parameter、.line、.prologue、.epilogue、.source、.local、.restart本地、.end本地...我想这就够了。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14100992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档