第十九节_Android_APP_安全机制

第十九节 Android APP 安全机制

(第1章 安卓逆向概论)

学习目标

学完本节,希望你能够:搞清 Android 安全机制(沙盒、SELinux、签名、Root 检测);掌握代码保护(混淆、加固、反调试);知道存储安全、别明文泄露;会动态分析、绕过 Root 检测/反调试/加固(仅学习);能分析并绕过 APP 安全防护。


一、应用沙盒是啥?

用一句话说清楚

  • 每个 Android APP 运行在 独立的 Linux 进程 中,具有 独立的 UID/GID
  • 不同应用的文件、数据、进程默认不能互相访问

查看某应用的 UID

bash 复制代码
adb shell dumpsys package com.example.app | grep userId=

示例输出:

复制代码
userId=10123

👉 每个 APP 都有唯一的 UID,防止数据泄露。

尝试访问其他 APP 目录

bash 复制代码
adb shell ls /data/data/com.other.app/

如果未 Root,访问会被拒绝!



二、SELinux 是啥?

SELinux(Security-Enhanced Linux)用于限制 进程间通信、访问系统资源

查看 SELinux 状态

bash 复制代码
adb shell getenforce

示例输出:

复制代码
Enforcing  # 说明 SELinux 已启用

禁用 SELinux(Root 权限)

bash 复制代码
adb shell setenforce 0

查看 SELinux 拒绝的访问

bash 复制代码
adb shell dmesg | grep avc


三、Android 签名验证是咋回事?

Android APP 在安装时需要 数字签名 以确保应用完整性。

检查 APK 签名

bash 复制代码
apksigner verify --print-certs app.apk

示例输出:

复制代码
Signer #1 certificate DN: CN=Developer, O=Example Corp, C=US

绕过签名校验

AndroidManifest.xml 添加:

xml 复制代码
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>

然后重新签名:

bash 复制代码
zipalign -v 4 modded.apk aligned.apk
apksigner sign --ks my.keystore --out signed.apk aligned.apk
adb install signed.apk


四、Root 检测是啥、咋绕过?

许多应用 检测设备是否 Root 以防止被逆向分析。

常见 Root 检测方法

  1. 检查 su
java 复制代码
File f = new File("/system/bin/su");
if (f.exists()) {
    Log.d("RootCheck", "Device is Rooted!");
}
  1. 检测 Root 进程
bash 复制代码
adb shell ps -A | grep magiskd

示例输出:

复制代码
magiskd       1023  567   123456K fg    00000000 S magiskd

绕过 Root 检测
使用 Frida Hook File.exists()

js 复制代码
Java.perform(function() {
    var File = Java.use("java.io.File");
    File.exists.implementation = function() {
        return false;
    };
});

执行 Frida

bash 复制代码
frida -U -n com.example.app -e "..."


五、代码混淆和加固是啥?

1. ProGuard 混淆

proguard 复制代码
-dontobfuscate
-keep class com.example.** { *; }

反混淆 DEX

bash 复制代码
jadx -d output/ app.apk

2. 加固

加固(如 360加固, 腾讯加固)用于 隐藏代码逻辑,防止逆向

检查 APK 是否加固

bash 复制代码
unzip -l app.apk | grep classes

如果 classes.dex 被拆分或替换,则 APK 可能被加固

绕过加固(Frida Dump DEX)

bash 复制代码
frida -U -n com.example.app -e "Java.perform(function() {
    Java.use('dalvik.system.BaseDexClassLoader').loadClass.implementation = function(name) {
        console.log('Load Class: ' + name);
    };
});"


六、存储安全咋做?

1. 避免明文存储

不安全

java 复制代码
SharedPreferences prefs = getSharedPreferences("settings", MODE_PRIVATE);
prefs.edit().putString("password", "123456").apply();

查看存储数据

bash 复制代码
adb shell cat /data/data/com.example.app/shared_prefs/settings.xml

解决方案:使用加密存储

java 复制代码
EncryptedSharedPreferences encryptedPrefs = EncryptedSharedPreferences.create(
    "settings",
    MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
encryptedPrefs.edit().putString("password", "123456").apply();


七、逆向里咋绕过这些机制?(仅学习)

1. 绕过 Root 检测

js 复制代码
Java.perform(function() {
    var File = Java.use("java.io.File");
    File.exists.implementation = function() {
        return false;
    };
});

2. 绕过反调试

js 复制代码
Java.perform(function() {
    var Debug = Java.use("android.os.Debug");
    Debug.isDebuggerConnected.implementation = function() {
        return false;
    };
});

3. Dump DEX

js 复制代码
Java.perform(function() {
    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.loadClass.implementation = function(name) {
        console.log("Hooked Dex Load: " + name);
        return this.loadClass(name);
    };
});


动手练一练

  1. 检查应用的 UID
bash 复制代码
adb shell dumpsys package com.example.app | grep userId=
  1. 禁用 SELinux
bash 复制代码
adb shell setenforce 0
  1. Hook File.exists() 绕过 Root 检测
js 复制代码
Java.perform(function() {
    var File = Java.use("java.io.File");
    File.exists.implementation = function() {
        return false;
    };
});
  1. Dump DEX
js 复制代码
Java.perform(function() {
    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.loadClass.implementation = function(name) {
        console.log("Hooked Dex Load: " + name);
        return this.loadClass(name);
    };
});

本节小结

你只要记住这几条就行:每个 APP 独立 UID 沙盒,SELinux 再加强制访问控制;签名保证完整性,改包要重签;Root 检测、反调试、加固都可被 Hook 或 dump 绕过(仅限学习);敏感数据别明文放 SharedPreferences,用加密存储。


本节思考与练习

  1. 概念:沙盒、SELinux、签名各在干啥?Root 检测一般查啥?
  2. 动手:用 Frida Hook File.exists() 绕过某 APP 的 Root 检测(仅学习环境)。
  3. 动手:用 Frida Hook Debug.isDebuggerConnected 绕过反调试。

下一节预告 :下一节讲 CTF 逆向挑战(初级)(第二十节),用 ELF/APK/JNI 小题目练手拿 flag。

相关推荐
长沙火山19 小时前
第十七节_ELF_文件解析
逆向·安卓逆向
长沙火山21 小时前
第十三节_Android_APP_目录结构
逆向·安卓逆向
长沙火山1 天前
第十二节_Android_权限机制
逆向·安卓逆向
长沙火山1 天前
第十六节_反汇编工具介绍
逆向·安卓逆向
长沙火山1 天前
第十一节_Android_进程管理
逆向·安卓逆向
长沙火山1 天前
第九节_Android_CPU_架构解析
逆向·安卓逆向
长沙火山2 天前
第六节_x86_vs_ARM_汇编
逆向·安卓逆向
泡泡以安2 天前
Android 逆向实战:从零突破某电商 App 登录接口全参数加密
android·爬虫·安卓逆向
长沙火山2 天前
第五节_汇编语言基础
逆向·安卓逆向