代码混淆的实现原理与方法

来源:互联网 发布:tensorflow gpu 显卡 编辑:程序博客网 时间:2024/05/16 23:51
由于java和.net这类高层抽象语言,具有 天生的易反汇编 特性,其编译后的程序包包含了大量的源代码变量、函数名、数据结构等信息
根据其编译后的程序包,可以非常容易的得到 近乎源代码质量 的反汇编代码。如果不加混淆,相当于直接将源代码拱手送人,内容严密的app权限审核可以说是形同虚设。如果大家想避免源代码泄漏后重新修改策划而额外增加的工作量,建议都加上混淆。


android平台的混淆原理是用“ 不能直接猜出含义 的通用变量名和函数名a b c等”替换编译后程序包中“ 具有明显语义信息 的变量名和函数名”
这样,通过逆向工程得到的只是 难以理解 的代码。
从混淆的原理可以得出以下两点信息:
1.重命名变量名可能会导致程序异常。因为程序是需要跟平台交互的,平台只会以固定类名来调用我们的app,这就涉及到需要屏蔽不能重命名的函数及类 proguard.cfg文件就是起这个作用的,混淆后哪个地方出错,就将相关的类和函数加入到混淆屏蔽列表里面去
2.由于混淆只改变字符串,并不能改变程序逻辑,耐心的hacker还是能够理解程序的设计思路并尝试修改。但这类人群不会太多,加上有我们自定义框架的牵制,逆向工程也绝非轻而易举。


这个世界上没有不能破解的软件,只有 不值得破解 的软件,只有 逆向的成本超过了收益 ,我们的软件资产才是安全的,混淆则可以显著增加逆向成本。


在package编译时使用proguard混淆,即使用晦涩的名字重命名类名、字段名、函数名,以精简、优化和混淆代码。使用proguard处理的好处是apk文件会有一点点变小,同时更加难于被反编译。类似说明网上有很多,大家可以自己搜索了解一下。


下面几步,开发者只用关注第 3、4、5、6步即可
1、全局混淆选项,修改build/core/package.mk
ifndef LOCAL_PROGUARD_ENABLED
ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
    # turn on Proguard by default for user & userdebug build
    LOCAL_PROGUARD_ENABLED :=full
endif
endif


2、全局flag文件修改,屏蔽-dontobfuscate。修改build/core/proguard.flags
# Don't obfuscate. We only need dead code striping.
#-dontobfuscate


3、在自己模块下创建proguard.cfg文件,用来配置混淆选项,初始文件如下:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService


-keepclasseswithmembernames class * {
    native <methods>;
}


-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}


-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}


-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}


-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}


4、在Android.mk里每个package类型的LOCAL_MODULE里LOCAL_PACKAGE_NAME下面添加两句,
      LOCAL_PROGUARD_ENABLED := full #指定当前的应用打开混淆
      LOCAL_PROGUARD_FLAG_FILES := proguard.cfg #指定混淆配置文件


5、编译时设置环境变量使用. ./setenv.sh -bv user


6、遇到报错需要就需要修改proguard.cfg文件,规则可以找google。
原创粉丝点击