问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android逆向工程入门:四个实验案例详解

创作时间:
2025-01-21 16:53:23
作者:
@小白创作中心

Android逆向工程入门:四个实验案例详解

Android逆向工程是Android开发和安全研究中的重要技术,通过反编译和分析apk文件,可以深入了解应用程序的内部实现,对于软件安全审计、功能分析和二次开发具有重要意义。本文将通过四个具体的实验案例,详细介绍Android逆向分析的基本方法和技巧。

Android 逆向分析实验

本实验将通过四个具体的案例,介绍Android逆向分析的基本方法和技巧。实验环境为Windows系统,使用的主要工具包括dex2jar、jd-gui和AndroidKiller。

Task 1:Case Study 1

task1.apk安装至安卓设备,发现需要对某个输入进行校验。

随机尝试输入并进行校验,发现提示flag错误,可见需要输入正确的flag才能通过校验。

下载dex2jar和jd-gui并为对应文件添加可执行权限。使用dex2jar将task1.apk转换为JAR文件格式。

d2j-dex2jar.sh ./task1.apk

可以看到以Java代码形式展示的task1.apk

分析可得当flag的位数与s相同(31),且每一位i均满足flag[i] ^ 0x17 == s[i](^:如果相应位值相同,则结果为0,否则为1)。按照提示写Python代码暴力破解。

Task 2:Case Study 2

使用dex2jar和jd-gui读取task2.apk中的Java代码。首先检查MainActivity.class,发现其中的onClick函数检查了一个名为a的类中的一个名为a的函数的返回值,而函数a的参数为用户的输入。

public class MainActivity extends c {
    protected void onCreate(Bundle paramBundle) {
        super.onCreate(paramBundle);
        setContentView(2130968603);
        EditText editText = (EditText)findViewById(2131427422);
        findViewById(2131427423).setOnClickListener(new
View.OnClickListener(this, editText, (Context)this) {
            public void onClick(View param1View) {
                if (a.a(this.a.getText().toString())) {
                    Toast.makeText(this.b, "You get it~",1).show();
                    return;
                    }
                Toast.makeText(this.b, "Sorry its wrong",1).show();
            }
        });
    }
}

检查a.class,其中的函数a如下所示:

public static boolean a(String paramString) {
    if (paramString.length() == b.length) {
    int[] arrayOfInt = new int[a.length];
    arrayOfInt[0] = 0;
    byte[] arrayOfByte = paramString.getBytes();
    int k = arrayOfByte.length;
    int i = 0;
    int j = 1;
    while (i < k) {
        arrayOfInt[j] = arrayOfByte[i];
        j++;
        i++;
    }
    i = 0;
    while (i < c.length) {
        if (a[i] == b[i] * arrayOfInt[i] * arrayOfInt[i] + c[i] *
    arrayOfInt[i] + d[i] && a[i + 1] == b[i] * arrayOfInt[i + 1] * 	arrayOfInt[i+ 1] + c[i] *arrayOfInt[i + 1] + d[i]) {
    i++;
        continue;
        }
        return false;
    }
    return true;
    }
    return false;
}

分析该函数。该函数中将用户输入按字节存入一个字节数组arrayOfByte,然后将arrayOfByte逐元素转存到int数组arrayOfInt中(从arrayOfInt的第二位开始,arrayOfInt的第一位为0)。arrayOfInt的长度为数组a的长度,因此可知用户输入的长度比数组a的长度少一个字节,为34个字节。最后逐元素验证数组arrayOfInt的元素是否满足16行中的数量关系,若均满足则返回true

编写Python代码破解。

Task 3:Case Study 3

使用file命令查看task3.txt的文件类型,发现为Zip压缩文件。

使用Unzip命令解压缩后按上两个Task的方法查看Java代码。查看onClickTest函数发现函数对比了用户输入与i函数的返回值。

public void onClickTest(View paramView) {
    if (this.n.getText().toString().equals(i())) {
        this.o.setText(2131099685);
        return;
    }
    this.o.setText(2131099683);
}

i函数放在在线Java IDE中运行,并将返回值转换为String类型输出,得到flag。

Task 4:Case Study 4

同样使用dex2jar和jd-gui查看task4.apk的源代码,可以发现onCreate函数中设置了某个按钮为不可点击状态,猜测这个按钮就是查看flag的按钮。

使用AndroidKiller对task4.apk进行反编译。

查看onCreate函数的smali代码,可以找到Java代码中设置按钮状态的对应代码。其中v5寄存器在前方代码中被置为0,猜测该寄存器传递的就是参数false。将一个新寄存器v4的值置为1并替代传参语句中的v5,使传递的参数修改为true

使用AndroidKiller将修改后的文件重新编译。将生成的task4_killer.apk在安卓中运行,此时直接点击"爬到了,看Flag"按钮即可看到界面上显示出flag。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号