美文网首页Android&iOSAndroid开发那些事安卓
手把手教你搞懂Android反编译

手把手教你搞懂Android反编译

作者: nlpjoe | 来源:发表于2016-06-30 09:38 被阅读18235次

    手把手教你搞懂Android反编译

    转载时请必须注明出处:http://www.iosxxoo.com/2016/06/29/2016-06-29/

    前言

    反编译别人的程序不是什么值得炫耀的事,希望大家最好只是兴趣探索,而不是利益驱动。本文主要目的是绕开一个简单的激活程序。

    什么是反编译

    我们知道,Android的程序打包后会生成一个APK文件,这个文件可以直接安装到任何Android手机上,因此,反编译就是对这个APK进行反编译。Android的反编译分成两个部分:

    1. 一个是对代码反编译,也就是java文件的反编译。
    2. 一个是对资源反编译,也就是res文件的反编译。

    所需的工具

    反编译代码的工具:

    反编译资源的工具:

    热身准备

    首先我们需要一个APK,这里我自己写了一个,源码下载地址:http://download.csdn.net/detail/u012891055/9671973,打包成APK后下载到手机上。

    它的主要功能是模拟邮箱激活,如果我们输入了错误的数据则无法通过激活。所以我们的目的很简单,就是让这个判断逻辑失效。

    主要源码说明:

    第51行存储的正确的两个激活号码,通过:将账号密码隔开,如下

    private static final String[] DUMMY_CREDENTIALS = new String[]{
                "foo@163.com:20135115",
                "bar@163.com:20135115"
    };
    

    现在只有激活码正确才能通过激活。

    第331行是Execute函数,逻辑判断的部分。

        @Override
        protected void onPostExecute(final Boolean success) {
            mAuthTask = null;
            showProgress(false);
    
            if (success) {
                new AlertDialog.Builder(LoginActivity.this)
                        .setTitle("恭喜您")
                        .setMessage("成功激活!")
                        .show();
    //                finish();
            } else {
                mPasswordView.setError(getString(R.string.error_incorrect_password));
                mPasswordView.requestFocus();
            }
        }
    

    反编译代码

    dex2jar解压下来文件很多,在mac上我们需要用到dex2jar的是这三个东西(windows上对应用bat文件):

    • d2j_invoke.sh
    • d2j-dex2jar.sh
    • lib

    AndroidStudio打包好的APK文件的后缀,需改为.zip,然后解压。从解压的文件中找到classes.dex文件,并将其放入dex2jar同一目录下,如下:

    并在cmd中也进入到同样的目录,然后执行:

    sh d2j-dex2jar.sh classes.dex
    

    执行如下:

    然后我们会得到一个classes-dex2jar.jar文件,我们借助JD-GUI工具打开即可,打开如下:


    可以看到代码非常清晰,这样我们就可以看到整个APP的代码逻辑了。

    反编译资源

    apktool下载完成后有一个.sh文件和.jar文件,我们把APK放进来,如下:


    在cmd中进入apktool目录,执行命令:

    sh apktool.sh apktool d FooApp.apk
    

    d是decode的意思,表示我们要对FooApp解码,结果如下:

    然后你会惊喜的发现多了一个FooApp文件夹。


    主要目录说明:

    • AndroidManifest.xml:描述文件
    • res:资源文件
    • smail:反编译出来的所有代码,语法与java不同,类似汇编,是Android虚拟机所使用的寄存器语言

    修改App icon

    打开我们的描述文件,高清无码:



    可以看到我们的App icon名称为ic_launcher,我们找到所有mipmap开头的文件夹,替换成下图即可:

    ic_launche

    在最后重新打包后我们的App icon就会被修改了,不过在重新打包之前,我们还有最重要的一件事没有做,那就是修改激活码判断逻辑。

    修改逻辑

    我们通过源码或者JD-GUI查看反编译的代码可以看到激活码判断逻辑如下:

        @Override
        protected void onPostExecute(final Boolean success) {
            mAuthTask = null;
            showProgress(false);
    
            if (success) { 
            // 激活码正确
                new AlertDialog.Builder(LoginActivity.this)
                        .setTitle("恭喜您")
                        .setMessage("成功激活!")
                        .show();
    //                finish();
            } else {
                mPasswordView.setError(getString(R.string.error_incorrect_password));
                mPasswordView.requestFocus();
            }
        }
    

    所以我们只需要找到反编译后的if(success)的语句,并将其修改成if(!success)即可,如下:

    if (success)//修改成if(!success)
    {
    ...
    } else {
    ...
    }
    

    这样我们就成功的颠倒了以前的逻辑,我们输入一个错误的激活码,就会被判断成正确的。挺简单的,是吧。

    现在我们来动手修改:

    1. 打开smail里的LoginActivity$UserLoginTask.smali文件.

    2. 全局搜索if-eqz,通过AlertDialog关键字辅助定位,发现在第228行

    3. ok,就是这里了,然后将if-eqz修改成if-nez,他们对应Java的语法如下:

    Smail 语法 Java 语法
    if-eqz v0, if(v0 == 0)
    if-nez v0, if(v0 != 0)

    ok,大功告成,现在就可以重新打包了。关于smail语法,有兴趣的直接Google就行了。

    重新打包

    我们大概修改后两个地方,其实重新打包也十分简单,在cmd中执行以下命令即可:

    sh apktool.sh b FooAPP -o NewFooApp.apk
    

    其中b是build的意思,表示我们要将FooAPP文件夹打包成APK文件,-o用于指定新生成的APK文件名,这里新的文件叫作NewFooApp.apk。执行结果如下图所示:


    然后你会发现同级目录下生成了新的apk文件:


    但是要注意,这个apk现在还是不能安装的,因为我们没有对它进行签名,重新签名后它就是个名副其实的盗版软件了,大家一定要强烈谴责这种行为。

    重新签名

    重新签名也是很简单的,我直接用的一个已有签名文件,使用Android Studio或者Eclipse都可以非常简单地生成一个签名文件。

    在cmd中执行格式如下:

    jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore 签名文件名 -storepass 签名密码 待签名的APK文件名 签名的别名
    

    然后我们就可以用这个apk进行安装了,为了追求更快的运行速度,我们可以对其进行一次字节对齐,这里就不说了。

    使用盗版APK

    我们用NewFooApp.apk安装好盗版app后,发现图标变成了篮球,并且随便输入数据都能通过激活了:

    1

    怎么样?总的来说还是挺有意思的吧,不过别用歪了。

    参考链接:

    Android安全攻防战,反编译与混淆技术完全解析(上)- 郭霖

    Android安全技术解密与防范 - 周圣韬

    Done

    作者: @biggergao
    个人博客: Mr.码了戈壁

    2016年06月29日

    相关文章

      网友评论

      • yang2yang:你好,使用jd-gui打开invalid input fileloader......,是什么情况?经过测试,可以打开其他war,那么是不是使用dex2jar转化的jar包有问题?还是说这个jar经过了加固之类的处理,需要其他方式进行打开?
      • 十步杀一人_千里不留行:评论一群水军,你这演示完全是骗人的,你在写这篇文章的时候亲自干过开发没有。。你自己写个demo.apk也不混淆。自己再解出来。连加固也没有。你应该去应用市场下一个加固的去做例子,这种骗人把戏,随便搜索成千上万篇。真正逆向的门都没入。实在没内涵。。以后不要写这种弱智文来骗刚毕业的孩子们。。
        nlpjoe:@帅浩哥哥 这是我前年帮我女朋友做课程设计的时候写的一篇总结博客,只是介绍性文章,如果看了这个就精通了逆向 那这行也太不值钱了吧。你如果是大牛,可以写篇好的贴在评论区给别人看
      • uuid1234:最近才初次尝试APK反编译,楼主写的很详细,:+1:
      • FynnJason:大神在吗?命令行语句,在windows中是什么呢?把sh改成bat吗
      • 潇洒的夏夏:大神在不在
      • bb4fe0bc50e1:楼主,源码地址无效啊
        nlpjoe:@bb4fe0bc50e1 可以了
      • 王默默:就看看
      • 一缕殇流化隐半边冰霜:大神啊!!安卓和iOS通吃!!:+1::+1:
        nlpjoe:@一缕殇流化隐半边冰霜 冰霜大牛才一直是我心中的大神 :whale:
        一缕殇流化隐半边冰霜:@周俊佐 哈哈。。瓜神都和我说啦。。你挺厉害的。。膜拜一下:+1::+1:
        nlpjoe:@一缕殇流化隐半边冰霜 弱鸡并不会安卓 :smile:

      本文标题:手把手教你搞懂Android反编译

      本文链接:https://www.haomeiwen.com/subject/thgxjttx.html