第十三节_Android_APP_目录结构

第十三节 Android APP 目录结构

(第1章 安卓逆向概论)

学习目标

学完本节,希望你能够:搞清 APP 目录结构,尤其是 /data/data/包名 下都有啥;会 SharedPreferences、SQLite、内部/外部存储;知道 APK 安装后文件咋分布,能备份、迁移、逆向;会提取 APP 数据做逆向和调试。


一、APP 安装后目录长啥样?

Android APP 安装后,其数据主要存放在 /data/data/<package_name>/ 目录下(需 Root 访问)。

查看所有已安装 APP 的数据目录

bash 复制代码
adb shell ls /data/data/

示例:某 APP 的目录结构

复制代码
/data/data/com.example.app/
├── cache/                  # 缓存文件(临时数据)
├── code_cache/             # ART 编译缓存
├── databases/              # SQLite 数据库存储目录
│   ├── user.db             # 主要数据库文件
│   ├── user.db-shm         # SQLite 共享内存文件
│   ├── user.db-wal         # SQLite WAL 日志文件
├── files/                  # 应用存储的文件(默认目录)
│   ├── logs/               # 日志文件
│   ├── config.json         # 配置文件
├── shared_prefs/           # SharedPreferences(XML 格式存储)
│   ├── settings.xml        # APP 设置存储
│   ├── user_data.xml       # 用户数据
├── lib/                    # Native C/C++ so 库
│   ├── libnative.so        # 本地共享库
├── app_webview/            # WebView 存储数据
├── app_flutter/            # Flutter APP 资源
└── cache/                  # 临时缓存文件

查看特定 APP 的目录

bash 复制代码
adb shell ls -l /data/data/com.example.app/


二、各目录在干啥?

目录 作用 存储方式 是否可访问
cache/ 临时缓存数据 文件 可读写(应用内)
code_cache/ ART 编译缓存 OAT 文件 🚫 仅 Root 访问
databases/ APP 的 SQLite 数据库 SQLite3 🚫 仅 Root 访问
files/ APP 存储的文件 普通文件 可读写(应用内)
shared_prefs/ 共享存储,存储应用设置 XML 🚫 仅 Root 访问
lib/ 存储 Native .so 库 ELF 文件 🚫 仅 Root 访问
app_webview/ WebView 本地存储 Cache 🚫 仅 Root 访问
cache/ 临时缓存 Cache 可读写(应用内)

查看数据库文件

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

查看 SharedPreferences

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


三、APP 咋存数据?

1. 内部存储(Internal Storage)

APP 私有存储,其他 APP 不能访问(无 Root 权限)。

java 复制代码
File file = new File(getFilesDir(), "config.json");

查看 APP 内部存储

bash 复制代码
adb shell run-as com.example.app ls -l /data/data/com.example.app/files/

2. 外部存储(External Storage)

可被其他 APP 访问(需要权限 WRITE_EXTERNAL_STORAGE)。

java 复制代码
File file = new File(Environment.getExternalStorageDirectory(), "myfile.txt");

查看外部存储文件

bash 复制代码
adb shell ls -l /sdcard/Android/data/com.example.app/

3. SharedPreferences(轻量级存储)

存储简单的键值对数据(XML 格式)。

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

查看 SharedPreferences

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

4. SQLite 数据库

存储结构化数据

java 复制代码
SQLiteDatabase db = openOrCreateDatabase("user.db", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");

Dump SQLite 数据库

bash 复制代码
adb shell "sqlite3 /data/data/com.example.app/databases/user.db 'SELECT * FROM users;'"


四、逆向里咋看 APP 目录?

1. 提取 APK 资源

bash 复制代码
adb pull /data/app/com.example.app/base.apk .
apktool d base.apk -o output/

修改 AndroidManifest.xml 以查看文件存储权限

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

重新打包:

bash 复制代码
apktool b output -o modded.apk
jarsigner -verbose -keystore my.keystore modded.apk alias_name
adb install modded.apk

2. 获取数据库数据

Dump SQLite 数据库

bash 复制代码
adb shell "sqlite3 /data/data/com.example.app/databases/user.db .dump"

复制数据库到本地

bash 复制代码
adb pull /data/data/com.example.app/databases/user.db .
sqlite3 user.db

3. Hook SharedPreferences

使用 Frida Hook 读取 SharedPreferences

js 复制代码
Java.perform(function() {
    var SharedPreferences = Java.use("android.app.SharedPreferencesImpl");
    SharedPreferences.getString.implementation = function(key, defValue) {
        console.log("Hooked SharedPreferences: " + key);
        return this.getString(key, defValue);
    };
});

执行:

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

4. 拦截文件存取

使用 Xposed Hook open 读取 config.json

java 复制代码
findAndHookMethod("java.io.FileInputStream", "open", String.class, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) {
        Log.d("Xposed", "File opened: " + param.args[0]);
    }
});


动手练一练

  1. 查询某应用的存储路径
bash 复制代码
adb shell ls -l /data/data/com.example.app/
  1. 提取 SQLite 数据
bash 复制代码
adb pull /data/data/com.example.app/databases/user.db .
sqlite3 user.db
  1. 修改 SharedPreferences
bash 复制代码
adb shell cat /data/data/com.example.app/shared_prefs/settings.xml
adb shell "echo '<string name=\"is_premium\">true</string>' >> /data/data/com.example.app/shared_prefs/settings.xml"
  1. Hook 文件访问
js 复制代码
Java.perform(function() {
    var File = Java.use("java.io.File");
    File.getAbsolutePath.implementation = function() {
        console.log("File Accessed: " + this.getAbsolutePath());
        return this.getAbsolutePath();
    };
});

本节小结

你只要记住这几条就行:APP 数据在 /data/data/包名/ 下,有 cache、databases、shared_prefs、files、lib 等;SharedPreferences 是 XML,SQLite 在 databases;需 Root 或 run-as 才能读;逆向可 pull 数据库、改 shared_prefs、Hook 读写。


本节思考与练习

  1. 概念:内部存储和外部存储有啥区别?shared_prefs 和 databases 各存啥?
  2. 动手:用 adb shell run-as 包名 ls 或 Root 下 ls 看某 APP 的目录。
  3. 动手:pull 某 APP 的 shared_prefs 或 databases,用 sqlite3 查表。
  4. 动手:用 Frida Hook SharedPreferences 的 get,打印 key。

下一节预告 :下一节讲 APK 是如何加载的(第十四节),把 DEX 加载、OAT、ClassLoader 讲清楚。

相关推荐
长沙火山6 小时前
第十二节_Android_权限机制
逆向·安卓逆向
长沙火山6 小时前
第十六节_反汇编工具介绍
逆向·安卓逆向
长沙火山7 小时前
第十一节_Android_进程管理
逆向·安卓逆向
长沙火山7 小时前
第九节_Android_CPU_架构解析
逆向·安卓逆向
长沙火山1 天前
第六节_x86_vs_ARM_汇编
逆向·安卓逆向
泡泡以安1 天前
Android 逆向实战:从零突破某电商 App 登录接口全参数加密
android·爬虫·安卓逆向
长沙火山2 天前
第五节_汇编语言基础
逆向·安卓逆向
夏了茶糜4 天前
Electron应用逆向分析思路
逆向
嫂子的姐夫6 天前
25-jsl:gov公安(全扣补环境版)
爬虫·逆向·加速乐