近期在开发一款软件时,遇上了加密、解密数据方面的一些技术问题无法攻克,于是抱着试试看的态度使用 jadx-gui
工具进行反编译一下。哎,居然还成功了,更骚的是,这一款App没有对应用进行混淆、加密、加固,没多久我就研究明白了他们的应用是如何解决我所遇到的问题,升职加薪又离我更近一步了🤭
但是呢,为了防止我所编写的软件遇上像我这样的老六,特地写一篇文章来告诉大家如何能成为我这样的老六,以及如何加强App的软件防护等级。
反编译
可以用于反编译 App 的工具有很多,敲命令行实现反编译的已经成为过去式了,这里分享一个有 GUI ,同时也是博主目前在使用的反编译工具:jadx
jadx-gui
jadx-gui
是用于从Android Dex
和Apk
文件生成 Java 源代码的命令行和 GUI 工具。
我们可以借助该工具,实现反编译 App。
这里我使用 StepDemo 作为演示的项目,下载 jadx
安装到电脑上,使用 jadx
打开一个 .app
或 .apk
文件 ,就可以得到如图的 app 信息。
使用 Android Studio 查看项目的源代码是这样:
将 StempDemo
打包成一个 .apk
或者 .aab
,使用 jadx
打开后自动反编译的代码:
咋样?你学会了没?
预防反编译
哈!反编译很简单吧!
上面讲了如何反编译他人的 app ,接下来就讲解,如何预防你们的 app 被某个老六给反编译抄走辛辛苦苦写的代码😊
代码混淆
代码混淆可以说是应用安全中最基础的知识了,但同时也是坑最多的方式之一。
关于代码混淆可参考往期文章 👉【Android】App攻防之代码混淆
打开 app 项目的 build.gradle.kts
文件,启用 isMinifyEnabled
即可开启混淆。
android {
buildTypes {
// 应用处于release模式时
release {
isMinifyEnabled = true // 开启混淆
isShrinkResources = true // 开启资源压缩
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
// 设置定义混淆规则的文件
"proguard-rules.pro"
)
}
// 应用处于debug模式时
debug {
isMinifyEnabled = true // 开启混淆
isShrinkResources = true // 开启资源压缩
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
// 设置定义混淆规则的文件
"proguard-rules.pro"
)
}
}
}
打包完成,我们再来反编译一下。通过以下反编译前、后对比,就可以看出,右边的代码相对于左边的代码变得更加复杂了,同时,开启混淆的 apk 文件比未开启混淆的 apk 占用空间更小。
![](https://i-blog.csdnimg.cn/blog_migrate/83168131d4342a153457e925fcebda69.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d11f380566ba321160f255818d02993f.png)
小结
1.代码混淆只是增加了代码复杂度,对于有耐心的人来说,破解你的代码只是时间问题。
2.代码混淆若混淆规则编写不正确,会出现各种离谱的问题,且难以追踪问题产生原因。
3.代码混淆只是混淆了代码,并没有对 app 的资源文件进行加密,使得资源文件容易被他人窃取。
应用加固
应用加固的方式有很多,比如说 360 加固助手、百度应用加固、网易易盾等,360 加固助手每个月都是有免费加固次数使用,本文使用的是 360 加固助手。
使用 360 加固助手加固后的 app 再使用 jadx
打开,app 的源码、资源等信息已经提取不到了。
其它
SDK 加固 & 插件加固
SDK 加固、插件加固没有免费实现的方式,目前 360 加固助手、百度应用加固、网易易盾等,都需要花钱开通 VIP 才能使用该功能。
加密重要数据
对于一些重要的数据,如:API密钥,可以使用加密算法进行加密,然后在运行时进行解密。
使用C/C++代码
将一些关键的算法或者逻辑使用 C/C++ 实现,并通过 JNI 调用。因为 C/C++ 代码编译后为机器码,相比 Java 代码更难以反编译。
防止调试
当应用完成开发准备上线时,可以添加部分代码防止应用被调试。如下:
- 在
AndroidManifest.xml
文件中,添加android:debuggable="false"
以阻止用户调试。
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:debuggable="false">
...
</application>
- 在代码中添加判断是否处于
Debug
模式,若处于Debug
模式,则退出应用程序。
if (android.os.Debug.isDebuggerConnected()) {
// 当前处于调试模式,可以执行相应的操作,例如退出应用
android.os.Process.killProcess(android.os.Process.myPid());
}