安卓逆向之常见结构的smali语句分析

admin 2024年4月24日07:55:32评论8 views字数 2610阅读8分42秒阅读模式
常见结构的

No.0

前言

smali代码是Dalvik虚拟机的寄存器语言. 我们在做安卓逆向的时候, 由于dex文件反汇编出来的都是smali代码, 所以能读懂smali语句和了解常见的语句结构是非常重要的, 下面介绍两种结构的smali代码.

No.1

常见语句结构

例如我们现在有一个软件, 这个软件里面有一个输入框, 可以输入数字, 然后有一个按钮用来判断用户输入的内容, 当数字大于0, 输出”他大于0”, 等于0的时候输出”他等于0”, 小于0的时候输出”他小于0”

public void onClick(View v) {
    String s = binding.numberInputBox.getEditText().getText().toString();
    String prompt = "";
    try {
       int a = Integer.parseInt(s);
       if (a > 0) {
           prompt = "他大于0";
       } else if (a == 0) {
           prompt = "他等于0";
       } else {
           prompt = "他小于0";
       }
    } catch (NumberFormatException e) {
       prompt = "这不是一个数字";
    } finally {
       binding.resultDisplayTextBox.setText(prompt);
    }
}

安卓逆向之常见结构的smali语句分析

我们编译生成apk, 使用android killer进行反编译, 在smali_classes4comexamplemyapplicationFirstFragment$1.smali 里可以找到我们的代码

安卓逆向之常见结构的smali语句分析

首先在这个文件中的第50行, 把numberInputBox储存到v0寄存器, 使用invoke-virtual调用numberInputBox的getEditText()获取到里面的输入框放到v0, 然后56行再调用获取到的输入框的getText()方法来获取里面的输入内容, 因为getText()返回的是EditText类型, 需要再调用toString()方法来把EditText转换为String类型, 最后放到v0寄存器.

No.2

if条件判断

在smali代码中, 条件判断使用的是if-cc命令, cc可以更换为任何条件 例如:

·       if-lez vx, 地址              如果vx(v表示一个寄存器)里的值小于等于0, 则跳转到地址

·       if-gez vx, 地址      如果vx大于等于0, 则跳转到地址

·       if-eqz vx, 地址      如果vx等于0, 则跳转到地址

·       if-nez vx, 地址      如果vx不等于0, 则跳转到地址

·       if-gt vx, vy, 地址   如果vx大于vy, 则跳转到地址

·       if-lt vx, vy, 地址    如果vx小于vy, 则跳转到地址

·       if-eq vx, vy, 地址   如果vx等于vy, 则跳转到地址

·       if-ne vx, vy, 地址   如果vx不等于vy, 则跳转到地址

安卓逆向之常见结构的smali语句分析

第66行中, v1被赋予一个空字符串, 然后调用Integer类的静态方法parseInt(), 来解析v0

, 把结果传递给v2寄存器. 然后下面使用if-cc对v2进行判断.

首先使用if-lez把v2和0作比较, 如果v2小于等于0, 就跳转到:cond_0, 也就是第88行, v2大于0的时候不跳转, 继续执行. 到88行这里后又有一个判断if-nez v2, :cond_1, 如果v2不等于0, 跳转到:cond_1, 相当于v2小于0的时候跳转到:cond1, 等于0的时候不跳转, 继续执行. 然后每一个条件分支都有一个goto :goto_0, 表示分支结束之后使用goto语句跳转到:goto_0来跳出条件判断, 继续执行后续代码.

那么我们可以总结一下条件判断的基本结构, 使用if-cc做出判断, 然后跳转到特定分支, 在每个分支的末尾需要一个goto语句来跳出条件判断.

No.3

循环

现在我们修改一下代码, 让其功能变成输入一个数字, 然后求他从1到他本身的和.

public void onClick(View v) {
    String s = binding.numberInputBox.getEditText().getText().toString();
    String prompt = "";
    try {
       int a = Integer.parseInt(s);
       int result = 0;
       for (int i = 1; i <=a; i++) {
           result += i;
       }
       prompt = String.valueOf(result);
    } catch (NumberFormatException e) {
       prompt = "这不是一个数字";
    } finally {
       binding.resultDisplayTextBox.setText(prompt);
    }
}

安卓逆向之常见结构的smali语句分析

我们使用android killer反编译这个软件, 在smali_classes4comexamplemyapplicationFirstFragment$1.smali找到我们的代码.

安卓逆向之常见结构的smali语句分析

前面的代码都一样, 我们从第71行开始看, 这里调用parseInt解析输入框里的内容为数字放到放到v2, 然后定义了v3用来存放计算结果, 定义v4也就是for循环里面的i. 这里使用了判断语句if-gt v4, v2, :cond_0, 如果v4大于v2就跳转到:cond_0, 也就是跳出循环, 否则继续执行. 接下来的add-int/2addr v3, v4表示把每次循环的数相加到存放结果的v3, 相当于v3 = v3 + v4, 然后使用add-int/lit8 v4, v4, 0x1 相当于每次循环给v4也就是i加上了1, 最后使用goto :goto_0跳回到85行, 进行下次循环, 直到v4大于v2才跳出循环.

那么循环结构我们也可以总结一下, 循环的本质就是判断和跳转, 使用if-cc做判断, 如果不满足条件就跳回原来的地方再次执行语句, 一直到条件满足跳出循环.

PS:APP学员投稿

No.4

原文始发于微信公众号(隐雾安全):安卓逆向之常见结构的smali语句分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月24日07:55:32
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓逆向之常见结构的smali语句分析https://cn-sec.com/archives/2081437.html

发表评论

匿名网友 填写信息