• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android安全攻防战,反编译与混淆技术完全解析(下)

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

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android安全攻防实战,皇家攻防战2,婚姻攻防战之爱要付出,毒舌攻防战,樱桃恋爱攻防战等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

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


在上一篇文章当中,我们学习了Android程序反编译方面的知识,包括反编译代码、反编译资源、以及重新打包等内容。通过这些内容我们也能看出来,其实我们的程序并没有那么的安全。可能资源被反编译影响还不是很大,重新打包又由于有签名的保护导致很难被盗版,但代码被反编译就有可能会泄漏核心技术了,因此一款安全性高的程序最起码要做到的一件事就是:对代码进行混淆。
混淆代码并不是让代码无法被反编译,而是将代码中的类、方法、变量等信息进行重命名,把它们改成一些毫无意义的名字。因为对于我们而言可能Cellphone类的call()方法意味着很多信息,而A类的b()方法则没有任何意义,但是对于计算机而言,它们都是平等的,计算机不会试图去理解Cellphone是什么意思,它只会按照设定好的逻辑来去执行这些代码。所以说混淆代码可以在不影响程序正常运行的前提下让破解者很头疼,从而大大提升了程序的安全性。
今天是我们Android安全攻防战系列的下篇,本篇文章的内容建立在上篇的基础之上,还没有阅读过的朋友可以先去参考 Android安全攻防战,反编译与混淆技术完全解析(上) 。


混淆

本篇文章中介绍的混淆技术都是基于Android Studio的,Eclipse的用法也基本类似,但是就不再为Eclipse专门做讲解了。
我们要建立一个Android Studio项目,并在项目中添加一些能够帮助我们理解混淆知识的代码。这里我准备好了一些,我们将它们添加到Android Studio当中。
首先新建一个MyFragment类,代码如下所示:

public class MyFragment extends Fragment {

    private String toastTip = "toast in MyFragment";

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_layout, container, false);
        methodWithGlobalVariable();
        methodWithLocalVariable();
        return view;
    }

    public void methodWithGlobalVariable() {
        Toast.makeText(getActivity(), toastTip, Toast.LENGTH_SHORT).show();
    }

    public void methodWithLocalVariable() {
        String logMessage = "log in MyFragment";
        logMessage = logMessage.toLowerCase();
        System.out.println(logMessage);
    }

}

可以看到,MyFragment是继承自Fragment的,并且MyFragment中有一个全局变量。onCreateView()方法是Fragment的生命周期函数,这个不用多说,在onCreateView()方法中又调用了methodWithGlobalVariable()和methodWithLocalVariable()方法,这两个方法的内部分别引用了一个全局变量和一个局部变量。
接下来新建一个Utils类,代码如下所示:

public class Utils {

    public void methodNormal() {
        String logMessage = "this is normal method";
        logMessage = logMessage.toLowerCase();
        System.out.println(logMessage);
    }

    public void methodUnused() {
        String logMessage = "this is unused method";
        logMessage = logMessage.toLowerCase();
        System.out.println(logMessage);
    }

}

这是一个非常普通的工具类,没有任何继承关系。Utils中有两个方法methodNormal()和methodUnused(),它们的内部逻辑都是一样的,唯一的据别是稍后methodNormal()方法会被调用,而methodUnused()方法不会被调用。
下面再新建一个NativeUtils类,代码如下所示:

public class NativeUtils {

    public static native void methodNative();

    public static void methodNotNative() {
        String logMessage = "this is not native method";
        logMessage = logMessage.toLowerCase();
        System.out.println(logMessage);
    }

}

这个类中同样有两个方法,一个是native方法,一个是非native方法。
最后,修改MainActivity中的代码,如下所示:

public class MainActivity extends AppCompatActivity {

    private String toastTip = "toast in MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction().add(R.id.fragment, new MyFragment()).commit();
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                methodWithGlobalVariable();
                methodWithLocalVariable();
                Utils utils = new Utils();
                utils.methodNormal();
                NativeUtils.methodNative();
                NativeUtils.methodNotNative();
                Connector.getDatabase();
            }
        });
    }

    public void methodWithGlobalVariable() {
        Toast.makeText(MainActivity.this, toastTip, Toast.LENGTH_SHORT).show();
    }

    public void methodWithLocalVariable() {
        String logMessage = "log in MainActivity";
        logMessage = logMessage.toLowerCase();
        System.out.println(logMessage);
    }

}

可以看到,MainActivity和MyFragment类似,也是定义了methodWithGlobalVariable()和methodWithLocalVariable()这两个方法,然后MainActivity对MyFragment进行了添加,并在Button的点击事件里面调用了自身的、Utils的、以及NativeUtils中的方法。注意调用native方法需要有相应的so库实现,不然的话就会报UnsatisefiedLinkError,不过这里其实我也并没有真正的so库实现,只是演示一下让大家看看混淆结果。点击事件的最后一行调用的是LitePal中的方法,因为我们还要测试一下引用第三方Jar包的场景,到LitePal项目的主页去下载最新的Jar包,然后放到libs目录下即可。
完整的build.gradle内容如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.example.guolin.androidtest"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.2.0'
}

好的,到这里准备工作就已经基本完成了,接下来我们就开始对代码进行混淆吧。

混淆APK

在Android Studio当中混淆APK实在是太简单了,借助SDK中自带的Proguard工具,只需要修改build.gradle中的一行配置即可。可以看到,现在build.gradle中minifyEnabled的值是false,这里我们只需要把值改成true,打出来的APK包就会是混淆过的了。如下所示:

release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

其中minifyEnabled用于设置是否启用混淆,proguardFiles用于选定混淆配置文件。注意这里是在release闭包内进行配置的,因此只有打出正式版的APK才会进行混淆,Debug版的APK是不会混淆的。当然这也是非常合理的,因为Debug版的APK文件我们只会用来内部测试,不用担心被人破解。
那么现在我们来打一个正式版的APK文件,在Android Studio导航栏中点击Build->Generate Signed APK,然后选择签名文件并输入密码,如果没有签名文件就创建一个,最终点击Finish完成打包,生成的APK文件会自动存放在app目录下。除此之外也可以在build.gradle文件当中添加签名文件配置,然后通过gradlew assembleRelease来打出一个正式版的APK文件,这种方式APK文件会自动存放在app/build/outputs/apk目录下。
那么现在已经得到了APK文件,接下来就用上篇文章中学到的反编译知识来对这个文件进行反编译吧,结果如下图所示:

\

很明显可以看出,我们的代码混淆功能已经生效了。
下面我们尝试来阅读一下这个混淆过后的代码,最顶层的包名结构主要分为三部分,第一个a.a已经被混淆的面目全非了,但是可以猜测出这个包下是LitePal的所有代码。第二个android.support可以猜测出是我们引用的android support库的代码,
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

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

相关文章

  • 2017-05-26手机游戏渠道SDK接入工具项目分享(二)万事开头难,手机游戏sdk
  • 2017-05-26activity的横屏和竖屏设置,activity
  • 2017-05-227.1.3 Android HTTP请求方式:HttpURLConnection
  • 2017-05-26配置adb环境变量,adb环境变量
  • 2017-05-26安卓第一天笔记,安卓第一天
  • 2017-05-26andriod 带看括弧的计算器,andriod括弧计算器
  • 2017-05-222.3.7 ProgressBar(进度条)
  • 2017-05-26Accessibility辅助功能--一念天堂,一念地狱,一念天堂一念地狱
  • 2017-05-26Android中自定义视图View之---进阶篇(Canvas的使用)
  • 2017-05-26使用flume+kafka+storm构建实时日志分析系统

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android通知栏沉浸式/透明化完整解决方案,root不完整解决方法
    • 硅谷商城4--显示购物车商品,硅谷商城4--购物车
    • Handler消息传递机制(一)
    • BaseAdapter日常的封装,baseadapter封装
    • android handler传递消息机制,androidhandler
    • Android特效专辑(八)——实现心型起泡飞舞的特效,让你的APP瞬间暖心
    • Android百度地图API集成三《搜索》,android《搜索》
    • 常用代码块,代码
    • 回顾自定义view三个构造函数,回顾view构造函数
    • 编译器开发系列--Ocelot语言7.中间代码,编译器--ocelot

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有