mohamad-aljeiawi/android-memdump-elf
GitHub: mohamad-aljeiawi/android-memdump-elf
单文件Python工具,通过ADB从Android进程内存dump原生库并重建ELF节头,使加壳保护的.so文件能在IDA/Ghidra中正常分析。
Stars: 0 | Forks: 0
直接从进程内存中 Dump 并重建 Android 原生库—— 单个 Python 脚本,零编译。
快速开始 • 工作原理 • 用法 • ELF 修复器 • 环境要求 • 致谢
## 这是什么? 一个单文件 Python 工具,具备以下功能: 1. 通过 ADB 从运行中的 Android 进程内存中 **Dump** 已加载的 `.so` 库 2. 通过从头重建所有 16 个节头**修复** Dump 下来的 ELF 修复后的输出文件可以在 IDA Pro、Ghidra 或任何 ELF 分析工具中正常加载 —— 包含完整的符号解析、`.plt`/`.got` 恢复以及正确的节映射。 **专为以下场景构建:** 安全研究人员、逆向工程师,以及调试加壳/保护原生库(如 UPX、Bangcle、360 加固、腾讯等)的开发者。 ## 功能特性 | 功能 | 描述 | |---|---| | **区域感知 Dump** | 单独读取每个映射区域 —— 绝不触碰未映射的间隙 | | **分块传输** | 将大区域拆分为 2 MB 的块,并显示实时进度 | | **ELF 节重建器** | 仅凭 `PT_DYNAMIC` 即可重建 16 个节头 | | **ELF32 + ELF64** | 完整支持 ARM (armeabi-v7a) 和 AArch64 (arm64-v8a) | | **单文件** | 仅需一个 `memdump.py` —— 无需编译,除 Python 3.7+ 外无其他依赖 | | **仅修复模式** | 无需 ADB 即可修复任何现有的内存 Dump | | **反反 Dump** | 可选的 `SIGSTOP` 以在提取期间冻结进程 | ## 快速开始 ``` # 克隆 git clone https://github.com/mohamad-aljeiawi/android-memdump-elf.git cd android-memdump-elf # 使用单条命令 Dump + 修复 python memdump.py com.example.app libtarget.so --fix # 输出: # libtarget_dump.bin ← 原始内存 dump # libtarget_dump_fixed.so ← 可用于 IDA/Ghidra ``` ## 工作原理 ``` flowchart TD A[Start memdump.py] --> B[Connect via ADB] B --> C[Find PID by package name] C --> D["Read /proc/PID/maps"] D --> E[Filter regions matching library name] E --> F[Split each region into 2 MB chunks] F --> G["Dump each chunk via dd from /proc/PID/mem"] G --> H[Pull chunks to PC + merge with zero-filled gaps] H --> I{--fix flag?} I -->|No| J[Output: raw dump] I -->|Yes| K[Parse ELF header + Program Headers] K --> L["Walk PT_DYNAMIC to find all section addresses"] L --> M[Rebuild 16 section headers] M --> N[Fix relocation bias + symbol values] N --> O["Append .shstrtab + section header table"] O --> P[Output: fixed .so ready for IDA] style A fill:#1a1a2e,color:#fff style P fill:#16213e,color:#fff style K fill:#0f3460,color:#fff style M fill:#0f3460,color:#fff ``` ### Dump 阶段 该工具读取 `/proc/PID/maps` 以查找属于目标库的所有内存区域。它不是读取一个巨大的连续范围(这会在未映射的间隙处停滞),而是以 2 MB 的块为单位单独 Dump 每个映射区域: ``` Region 0: 0x7400000000 - 0x7405700000 [87 MB] r--p → 44 chunks Region 1: 0x7405700000 - 0x7405713000 [76 KB] r-xp → 1 chunk Region 2: 0x7405713000 - 0x7405715000 [8 KB] rwxp → 1 chunk ... ``` 每个块都是一个直接的 `adb shell su -c 'dd ...'` 调用,并立即拉取和清理。区域之间的未映射间隙用零字节填充,以保留正确的偏移量。 ### 修复阶段 修复器完全根据 `PT_DYNAMIC` 中可用的信息重建 ELF 节头: ``` flowchart LR DYN["PT_DYNAMIC"] --> SYMTAB["DT_SYMTAB → .dynsym"] DYN --> STRTAB["DT_STRTAB → .dynstr"] DYN --> HASH["DT_HASH → .hash\n(+ symbol count)"] DYN --> REL["DT_REL/RELA → .rel.dyn"] DYN --> JMPREL["DT_JMPREL → .rel.plt"] DYN --> PLTGOT["DT_PLTGOT → .got"] DYN --> INIT["DT_INIT_ARRAY → .init_array"] DYN --> FINI["DT_FINI_ARRAY → .fini_array"] style DYN fill:#e63946,color:#fff ``` **重建的节(共 16 个):** `NULL` · `.dynsym` · `.dynstr` · `.hash` · `.rel.dyn` · `.rel.plt` · `.plt` · `.text` · `.ARM.exidx` · `.fini_array` · `.init_array` · `.dynamic` · `.got` · `.data` · `.bss` · `.shstrtab` **应用的额外修复:** - 从程序头中的所有 `p_vaddr` / `p_offset` 中减去加载偏移 - 设置 `p_offset = p_vaddr` 和 `p_filesz = p_memsz`(内存布局 = 文件布局) - 修复 `R_ARM_RELATIVE` / `R_AARCH64_RELATIVE` 重定位偏移 - 修复 `R_ARM_JUMP_SLOT` / `R_AARCH64_JUMP_SLOT` 条目 - 从 `.dynsym` 中的所有 `st_value` 减去偏移 - 纠正无效的符号类型(为了 IDA 兼容性) - 从 `R_*_RELATIVE` 指向的值中减去镜像基地址 ## 用法 ### Dump + 修复(最常用) ``` python memdump.py com.example.app libtarget.so --fix ``` 生成: - `libtarget_dump.bin` — 原始内存 Dump - `libtarget_dump_fixed.so` — 带有节头、可直接用于 IDA 的文件 ### 自定义输出名称 ``` python memdump.py com.example.app libtarget.so -o my_dump.bin --fix ``` ### 修复现有 Dump(无需 ADB) ``` python memdump.py --fix-only dumped.bin 0x740004D000 fixed.so ``` ### Dump 期间冻结进程(反反 Dump) ``` python memdump.py com.example.app libtarget.so --fix --stop ``` 在 Dump 前发送 `SIGSTOP`,在之后发送 `SIGCONT`。当应用检测到内存读取时很有用。 ### 将每个区域保存为单独的文件 ``` python memdump.py com.example.app libtarget.so --segments ``` ### 更大的块大小(在良好的 USB 连接上速度更快) ``` python memdump.py com.example.app libtarget.so --fix --chunk-mb 4 ``` ### 所有选项 ``` python memdump.py [-h] [--fix] [--stop] [--segments] [--chunk-mb N] [-o OUTPUT] [--fix-only DUMP BASE_HEX OUTPUT] package library ``` | 标志 | 描述 | |---|---| | `--fix` | Dump 后重建 ELF 节头 | | `--stop` | 在 Dump 期间向进程发送 `SIGSTOP` | | `--segments` | 将每个内存区域保存为单独的文件 | | `--chunk-mb N` | 块大小,单位 MB(默认值:2.0) | | `-o OUTPUT` | 自定义输出文件路径 | | `--fix-only` | 仅修复模式 —— 不使用 ADB,参数为 `
标签:360加固, ADB调试, Android安全, ARM64, ELF32, ELF64, ELF重构, Ghidra, Hook检测, IDA Pro, Native库分析, Ruby on Rails, SecList, SO文件Dump, UPX脱壳, URL提取, 二进制分析, 云安全运维, 云资产清单, 内存取证, 内存转储, 加壳识别, 反编译, 后渗透, 流量嗅探, 目录枚举, 移动安全, 端点检测与响应, 脱壳工具, 腾讯加固, 进程内存, 逆向工具, 逆向工程, 配置审计