`

android 反编译的一点思路

 
阅读更多
请大家先不否定我,不要先把事情打上不可能的标签. 只是一点思路和探索,就当是活跃思维了。

欢迎留言,不吝赐教.

android 反编译的教程帖子还是很多的,具体流程一般是 android->dex->dex.jar->java source,简单
点的 class 反编译效果还是不错的。一旦 sourcecode 太复杂,反编译效果就强差人意了。所以让我有了写自己反编译器的冲动.
这里, 反编译目标对象是运行在 dalvik 虚拟机的 class 文件. 它运行在 jvm 上的 class 文件基本结构是一样的, 但操作符的数目更少, 操作也更简单, 很多对寄存器的操作都简化了.
我使用 dex 解压 apk 文件 获得 class.dex 然后再转码为 .smali 文件, 这文件其实就是 dalvik bytecode 的文字表达方式, 相对于直接读写 byte位, 基于文字的文件更易读一些.

在我的设想里,反编译的结果应该是:
1 没有语法错误.
2 和 sourcecode 文件等效的代码。力争反编译得到的 sourcecode 再次编译后得到的 class 文件同 sourcecode 得到的 class 文件是一致的.
以下不在设计范围之内:
对于混淆代码, 反编译过程自身不负责替换被混淆的包名和变量名. 替换工作应该在完成反编译之后通过其他工具完成. 例如你如果获得了等效的源代码, 那么只要你使用市面上流行的混淆工具再次混淆源代码即可转码成一个更易读的源码版本.

具体实现上:
我认为反编译的重心是 method 的反编译. java 的基本组成部分是 class, 内部类, 接口, 匿名内部类, 方法, 静态初始化段落. 在编译时所有的类类型都会被处理成一个独立存在的 class 文件, 例如内部类就是 parentclass@innerclass 匿名内部类就是 parentclass@number. 不同的是内部类会含有一个 parent.this. 先完成 method 的反编译, 再考虑内部类的问题.

我用了一个月的时间来分析 android 编译得到的 dalvik bytecode 文件. 可供参考的资料实在不多,于是我就自己动手按照自己的思路写了一些基础的反编译代码。思路分两个部分:
1 理清程序的执行流程,识别出 while,嵌套while、if、else、dowhile等程序结构。
2 在执行结构的基础上反编译出 java code。

对于阶段 (1) 在每个while或者是goto的部分切分 bytecode 成更小的片段, 然后,把 bytecode 转化为执行流程“图”,然后通过分析节点的连通性来分析出各种语句结构(for,while,dowhile,if...)

如果源码结构不太复杂,第一阶段是可以顺利完成的,例如
    public void testContinue6() {
        int a = 0;
        int b = 0;
        int c = 0;

        out1: while (a < 100 && b < 100) {
            for (int i = 0; i < c; i += 2) {
                if (i / 5 == 2) {
                    System.out.println("innter0");
                    break out1;
                }
                if (i % 18 == 3) {
                    System.out.println("innter2");
                    continue out1;
                }
            }
        }
    }

我目前的代码已经能完整的识别出其中的 while、嵌套循环等结构。

如果执行顺序可以确定,那么阶段(2)翻译出 sourcecode 就十分简单。这基于下面的几个假设:
1 java bytecode 是基于寄存器的,bytecode中所可能使用到的寄存器的数目和参数都是可以确定的。
2 程序执行总是顺序的,即便是 while 循环也可以理解成先执行条件判断部分,然后执行while的代码部分。
3 在顺序执行的代码段中,执行过程中会根据程序结构而划分出更多变量的子作用域。
4 子作用域可以使用的变量数目>=父作用域的变量数目,在作用域结束时只有当前作用域中使用的变量结束作用(寄存器被释放). 也就是说如果 current.scope register count > parent.scope register count, 那么就能确定这个变量一定是定义在当前上下文的.

我还发现了一些解释的小技巧:
每个 bytecode 操作符其实都可以看做一个输入输出控制器,永远都是一个或者是多个输入,0 或 1 个输出。
那么语句的执行可以转化为一个"倒置的树结构"的寄存器依赖"图", 所有语句最后都会合并到一点,例如 return, 或者method invoke. 在子作用域中, 按照倒置树的起止范围可以细分更多子结构, 每个子结构都合并到一点. 追查寄存器的依赖关系就可以获得变量的依赖关系, 进而推断出变量的定义位置和作用域.
那倒置树的叶子节点是 "常量" 或者 来自 parent scope 或者可以推断他是一个当前作用域的变量, 那么可以停止树结构的建立了. 如果两个树结构有重叠的节点, 那么这个节点就应该被当作当前上下文的一个变量对象.

这里只是泛泛的说,但我相信通过上面的分析方法是可以确定各个变量的定义位置和作用域的。有了这些信息,只要把所有的 byte code 翻译成 java statement 即可获得可读的代码。再做一次代码语义的优化就可以获得获得可读性更强的代码了。

凡事总有例外,如果源码结构写的太复杂,就很难分析出来了,例如
    public void testContinue18() {
        int a = 0;
        int b = 90;
        int c = 0;

        do {
            System.out.println(a);
            if (test1()) {
                continue;
            }
            System.out.println("bb");
            if (test2()) {
                break;
            }
            System.out.println("cc");
        } while (test7() || test3() || test4());
    }

    public void testContinue20() {
        int count = 0;
        while (true) {
            System.out.println("00");
            count++;
            if (count / 32 + 5 == 113) {
                break;
            }
            System.out.println("aa");
        }
        System.out.println("bb");

        do {
            System.out.println("00");
            count++;
            if (count / 32 + 5 == 113) {
                break;
            }
            System.out.println("aa");
        } while (test2());
        System.out.println("bb");
    }

结构分析的时候就有很多等价的结构,不能确定使用哪种。并且之前在 if else 处断开 bytecode 的划分本身都太粗糙了。这里还没思路.

引用:
dalvik bytecode
http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html
分享到:
评论

相关推荐

    Android反编译工具包(最完整的Android反编译工具包)

    标题中的“Android反编译工具包(最完整的Android反编译工具包)”表明这是一个集合了多种工具的资源包,用于帮助开发者和安全研究人员进行APK的反编译工作。 首先,让我们来了解一下反编译的基本概念。反编译是将已...

    android反编译工具

    这通常涉及到使用各种Android反编译工具。这些工具可以帮助开发者、安全研究人员或者逆向工程师理解已编译的Android应用程序的工作原理。下面我们将详细探讨一些常用的Android反编译工具及其应用。 1. **Apktool**...

    Android 反编译-全部工具包

    在Android开发领域,有时我们需要对已有的APK文件进行反编译,以便了解其内部结构、查看源代码或进行二次开发。"Android反编译-全部工具包"提供了一个便捷的方式,将所有必要的反编译工具集合在一起,使得开发者无需...

    android反编译工具(dex2jar,apk2java)

    本文将详细介绍两款常用的Android反编译工具——dex2jar和apk2java,以及如何利用它们获取APK中的Java源代码和资源文件。 一、dex2jar dex2jar是一款将Dalvik字节码(.dex)转换为Java字节码(.jar)的工具。...

    Android反编译工具包

    本文将深入探讨Android反编译的相关知识,包括为什么要反编译,常用的工具,以及如何使用这些工具。 一、为什么进行Android反编译 1. 安全分析:开发者或安全研究人员可以通过反编译来检查应用是否存在潜在的安全...

    Android反编译软件 安卓反编译 Android APK反编译详解

    反编译就是将这些编译后的二进制文件还原成人类可读的源代码和资源文件,这有助于开发者学习其他应用的设计思路,查找安全漏洞,或者对现有应用进行修改。 **一、反编译的原因** 1. **学习与研究**:通过反编译,...

    Android 反编译可视化操作工具

    这就是Android反编译的作用。本文将详细介绍一款名为"Android反编译可视化操作工具"的实用软件,它使得这个过程变得更加直观和便捷。 这款工具的核心优势在于它的可视化界面,开发者无需再通过复杂的命令行操作来...

    Android反编译工具包(最新)

    Android反编译工具包合集,包含apktool,jd-gui-0.3.5.windows,dex2jar-0.0.9.15

    android 反编译smali工具

    在Android应用开发中,了解如何反编译APK文件对于调试、分析或学习第三方应用的实现原理至关重要。本文将深入探讨“android 反编译smali工具”,包括smali、smali-1.4.2.jar、baksmali-1.4.2.jar以及baksmali这四个...

    Android 反编译工具 APKDB

    本文将详细介绍“Android反编译工具APKDB”,以及如何利用它来提升我们的Android开发与调试能力。 APKDB全称为Android Package Database,是一款专为Android开发者设计的反编译工具。它能够帮助开发者快速对APK文件...

    android 反编译工具

    在Android应用开发中,有时我们需要对APK文件进行反编译以查看其源代码、资源文件或进行二次开发。这通常涉及到使用特定的反编译工具。本篇将详细介绍三个常用的Android反编译工具:Apktool、dex2jar以及JD-GUI。 1...

    android反编译套件

    android反编译套件,对与反编译android很好用.

    Android 反编译工具

    不同平台上的 Android 反编译工具 有 mac linux windows 所有平台的反编译工具 配套讲解博客 : http://blog.csdn.net/shulianghan/article/details/41697821

    android 反编译工具集

    在Android开发领域,有时我们需要对APK文件进行反编译以查看其源代码、资源文件或进行二次修改。"android 反编译工具集"是一个集合了常用的Android反编译工具,包括dex2jar和apktool,它们是Android开发者和逆向...

    Android反编译工具-jadx

    **Android反编译工具-jadx详解** 在移动应用开发领域,尤其是Android平台,开发者们有时需要对APK文件进行逆向工程,以了解其内部工作原理、安全分析或二次开发。这时,Android反编译工具就显得尤为重要。本文将...

    android反编译及阅读器gui

    本主题主要围绕“Android反编译及阅读器GUI”,我们将讨论如何利用相关工具进行反编译以及如何使用JD-GUI阅读器来查看反编译后的Java源代码。 首先,我们来了解一下Android反编译的基本概念。Android应用主要是由...

    Android反编译工具包 图形界面 apk 一键反编译

    本知识分享将围绕"Android反编译工具包 图形界面 apk 一键反编译"这一主题展开,介绍如何利用特定工具进行APK的反编译,以及这些工具的工作原理和注意事项。 标题中的"Android反编译工具包"是指一系列专门用于解析...

    Android反编译全套工具

    本资源"Android反编译全套工具"提供了一套常用的Android反编译工具,包括dex2jar、apktool和jd-gui,这些工具对于理解APK的工作原理、查找bug或者研究竞品功能非常有帮助。 1. **dex2jar**:这个工具主要用于将...

    Android菜鸟日记25-android反编译

    在Android开发过程中,有时我们需要对已有的APK文件进行反编译,以便了解其内部工作原理、学习他人代码或者进行二次开发。这篇“Android菜鸟日记25-android反编译”将带你走进Android反编译的世界,揭示APK背后的...

Global site tag (gtag.js) - Google Analytics