应用安全 --- 应知应会 之 加固方法大全

Android 加固方法与对应解决方案
一、加密
算法层面
| 加密算法 | 解决方法 |
|---|---|
| DES | 密钥长度短,暴力破解/已知明文攻击/动态Hook获取密钥 |
| RSA | Hook加解密函数获取密钥/中间人攻击获取公钥/侧信道攻击 |
| MD5 | 彩虹表碰撞/HashCat暴力破解/Hook比对函数绕过校验 |
| SM4 | 动态Hook获取密钥/内存搜索密钥/分析密钥派生逻辑 |
| Base64编码 | 直接解码,非加密算法 |
| AES (128/256) | Hook CipherInit/doFinal获取密钥和IV/内存dump密钥/侧信道 |
| 3DES | 同DES思路,Hook获取三组密钥/中间相遇攻击 |
| SM2 (国密非对称) | Hook签名验签函数/替换公钥/动态获取私钥 |
| SM3 (国密哈希) | Hook比对函数绕过/预计算碰撞(理论) |
| SHA-256/512 | Hook比对函数直接绕过校验/彩虹表(弱口令场景) |
| ChaCha20-Poly1305 | Hook获取密钥和Nonce/内存搜索密钥材料 |
| ECDSA | Hook签名函数替换返回值/Nonce重用攻击/替换公钥 |
| HMAC | Hook获取密钥/替换HMAC值/动态调试提取密钥 |
| RC4 | 已知明文攻击/Hook获取密钥流/统计分析(WEP类攻击) |
| Blowfish/Twofish | Hook获取密钥/内存搜索/动态调试提取轮密钥 |
| PBKDF2 (密钥派生) | Hook获取派生前原始密码/降低迭代次数绕过/内存提取派生后密钥 |
| Argon2 | Hook获取原始输入/内存提取派生密钥/修改参数降低强度 |
| 国密SM9 (标识密码) | Hook获取主私钥/用户私钥/替换标识参数 |
| 白盒加密 (WBC-AES/SM4) | DFA差分故障攻击/DCA差分计算分析/BGE攻击提取密钥/大量输入输出对分析 |
| 同态加密 (部分场景) | 性能瓶颈利用/分析未加密的控制流/侧信道攻击 |
| XOR定制变种 | 已知明文攻击/频率分析/暴力破解短密钥/动态Hook |
文件加密
| 加固方法 | 解决方法 |
|---|---|
| dex文件整体加密 | 内存dump(运行时dex必须解密加载,从/proc/pid/maps定位dump) |
| dex分片加密 | 多次内存dump后拼接还原/Hook ClassLoader追踪每片解密时机 |
| so分段加密 | 内存dump(等待所有段解密完成后dump完整so) |
| so文件整体加密 | 内存dump(Hook dlopen/linker等待加载完成后dump) |
| assets/res文件整体加密 | 动态Hook解密函数获取明文+静态分析解密算法还原 |
| 签名信息加密存储 | 动态Hook读取签名API获取明文+静态分析存储格式 |
| 壳中壳 | 动态调试逐层脱壳(多次attach,每层dump) |
| 动态密钥派生(密钥不落盘) | 动态调试在密钥拼接完成时断点提取/Hook所有密钥片段来源 |
| 配置文件加密 | 动态Hook文件读取获取明文+静态分析解密逻辑 |
| Manifest混淆加密 | 修复AXML格式/Hook PackageParser获取解析后明文 |
代码加密
| 加固方法 | 解决方法 |
|---|---|
| GOT/PLT表加密 | 动态调试等待重定位完成后dump/Hook linker的relocate函数 |
| text节区加密 | 动态调试在init_array/JNI_OnLoad执行完后dump解密后的text段 |
| dex指令抽取 | FART主动调用框架/DexHunter/自定义ART修改主动invoke还原 |
| JNI Bridge加密 | 动态调试Hook RegisterNatives/GetMethodID获取真实映射 |
| .rodata节区加密 | 动态调试等待解密函数执行后dump/Hook字符串引用获取明文 |
| 运行时才生成可执行代码 | Hook mmap/mprotect监控可执行内存分配,在生成后dump |
| 类粒度加密 | Hook ClassLoader.loadClass/defineClass,每个类加载时dump |
| 方法粒度加密 | Hook ArtMethod::Invoke,方法被调用时dump CodeItem/主动遍历调用 |
| CodeItem级别加密 | FART增强版主动调用+CodeItem粒度dump/修改ART源码拦截 |
| 注解/反射调用替换直接调用 | Hook Method.invoke/Constructor.newInstance还原调用关系图 |
| JNI动态注册加密 | Hook RegisterNatives函数,记录所有(Java方法→Native函数)映射 |
| init_array/fini_array加密 | 在linker调用init_array前后分别dump/Hook __libc_init |
| .init构造函数加密 | Hook linker的call_constructors,执行完成后dump |
数据加密
| 加固方法 | 解决方法 |
|---|---|
| 字符串/字符/常量池加密 | 动态Hook字符串使用点获取明文+静态分析解密函数批量还原 |
| 流量加密 | 动态Hook SSL_read/write获取明文+静态分析协议格式 |
| 数据库加密 | 动态Hook SQLiteDatabase.open获取密钥+静态分析密钥存储逻辑 |
| TEE加密 | 通常无法直接攻破;侧信道攻击/降级攻击/分析TEE与REE通信接口 |
| TrustZone密钥托管 | 分析CA(Client Application)与TA通信协议/利用已知TEE漏洞 |
| Keymaster/KeyStore硬件级 | 分析密钥使用时的上层API调用/利用KeyStore绑定策略缺陷 |
| 进程通信加密 | 动态Hook Binder transact/IPC接口获取明文+静态分析协议 |
| 常量池加密 (数值常量) | 动态调试观察运算时解密后的值/Hook运算指令获取操作数 |
| Binder通信加密 | Hook Parcel.writeXxx/readXxx获取明文/Hook transact |
| AIDL传输加密 | Hook AIDL生成的Stub/Proxy类方法获取传输数据明文 |
| 剪贴板数据加密 | Hook ClipboardManager.setPrimaryClip/getPrimaryClip获取明文 |
| Intent数据加密 | Hook Intent.putExtra/getExtra系列方法获取明文 |
| ContentProvider数据加密 | Hook ContentResolver.query/insert等获取明文数据 |
| WebView JS Bridge通信加密 | Hook addJavascriptInterface/evaluateJavascript获取通信明文 |
| 内存中敏感数据加密存储 | 在解密使用的瞬间断点dump/Hook解密函数获取明文 |
| Keychain/Keystore安全存储 | Hook KeyStore.getEntry/getKey获取密钥使用时的明文 |
| 传感器数据加密 (生物信息) | Hook BiometricPrompt回调/SensorManager获取原始数据 |
二、压缩
算法层面
| 压缩算法 | 解决方法 |
|---|---|
| LZ | 标准解压/识别变种后编写对应解压器 |
| LZMA | 7z标准库解压/Hook解压函数获取解压后数据 |
| LZ4 | LZ4标准库解压/内存dump解压后数据 |
| Zlib/Deflate | zlib标准库inflate解压/Hook uncompress |
| Zstd (Facebook) | Zstd标准库解压/Hook ZSTD_decompress |
| Brotli | Brotli标准库解压/Hook BrotliDecoderDecompress |
| LZSS | 编写对应解压器/动态Hook解压函数 |
| 自定义压缩算法 | 逆向分析解压函数逻辑重写解压器/Hook解压函数获取输出 |
| 多重压缩 | 逐层识别格式逐层解压/Hook最终解压出口获取明文 |
文件压缩
| 加固方法 | 解决方法 |
|---|---|
| dex/so文件压缩 | 内存dump(运行时必须解压加载到内存) |
| 资源文件压缩 (assets/res自定义压缩) | Hook AssetManager.open获取解压后数据/分析自定义解压逻辑 |
| APK内嵌压缩包 (zip/7z嵌套) | 递归解压所有嵌套层/动态监控文件释放目录 |
| 壳文件自解压 (stub解压释放payload) | 监控壳释放文件的目标目录/Hook文件写入获取payload |
代码压缩
| 加固方法 | 解决方法 |
|---|---|
| dex/so代码压缩 | 内存dump(代码执行前必须解压到内存) |
数据压缩
| 加固方法 | 解决方法 |
|---|---|
| 网络传输压缩 (gzip/brotli) | Hook SSL层获取压缩前明文/标准库解压抓包数据 |
三、混淆
算法/工具层面
| 混淆工具 | 解决方法 |
|---|---|
| ProGuard | 结合mapping文件还原/jadx反编译+人工分析逻辑 |
| R8 | 同ProGuard,利用mapping文件+反编译分析 |
| DexGuard | 专用反混淆工具/JEB高级反编译+动态分析辅助 |
| Allatori | Allatori专用反混淆/字符串解密脚本+控制流还原 |
| OLLVM (O-LLVM) | deflat反混淆脚本/符号执行/angr/Miasm还原控制流平坦化 |
| Hikari | 同OLLVM思路+针对Hikari特有Pass编写还原脚本 |
| Armariris | OLLVM变种,deflat+指令替换还原 |
| StringFog | Hook解密函数/编写批量解密脚本/反编译定位解密类 |
| 自研混淆Pass | 逆向分析混淆模式,编写针对性还原脚本/动态辅助 |
| Ipa Guard (iOS对标) | class-dump+Hopper/IDA分析+Frida动态Hook |
文件混淆
| 加固方法 | 解决方法 |
|---|---|
| assets/res名称随机化(重命名) | 追踪代码中资源访问逻辑还原映射关系/动态Hook资源加载 |
| 资源ID随机化 (打乱R.java映射) | Hook Resources.getIdentifier还原ID映射/分析resources.arsc |
| AndroidManifest混淆 (类名映射) | aapt2解析/修复工具还原/对照运行时实际加载的类 |
| 类随机分布到不同dex | 合并多dex后统一分析/Hook ClassLoader追踪类加载来源 |
| ELF节区名称混淆 | 忽略节区名,按Program Header和内容特征分析 |
| 放置虚假dex/so干扰分析 | 动态分析确认实际加载的文件/排除未被引用的文件 |
| so伪装为资源文件等 | 监控dlopen/System.load追踪实际加载路径/文件头特征识别 |
代码混淆
| 加固方法 | 解决方法 |
|---|---|
| 包名/类名/方法名/变量名随机化(重命名) | 结合上下文语义重命名/动态调试理解功能后人工标注 |
| 函数内部插入无用代码分支 | 代码追踪+符号执行识别不可达分支/opaque predicate检测移除 |
| 函数内部插入无用垃圾数据 | NOP填充识别并跳过/IDA脚本批量清除垃圾字节 |
| 代码顺序改为乱序执行 | 代码追踪还原执行流/控制流图重建/符号执行恢复顺序 |
| 中间跳转函数(间接调用) | 去除中间跳转函数/内联展开/追踪最终目标函数 |
| 多个函数间代码相互插入 | 函数边界识别+控制流分析还原各函数原始代码 |
| 指令替换 | 模式匹配还原等价原始指令/编写IDA/Ghidra脚本批量还原 |
| ARM/Thumb指令混合 | IDA Force分析/手动切换ARM/Thumb模式/递归反汇编 |
| 间接分支 (寄存器/表跳转) | 动态trace记录实际跳转目标/符号执行求解/构建跳转表 |
| Lambda/匿名类混淆 | 反编译后追踪接口实现/Hook invoke动态确认实际执行体 |
数据混淆
| 加固方法 | 解决方法 |
|---|---|
| 字符串强制分割保持 | 字符串拼接还原/Hook StringBuilder.toString获取完整字符串 |
| 简单字符串改为复杂数学表达式 | 动态执行获取计算结果+静态常量折叠/符号执行求值 |
| 字符串编码转换 (UTF-8→自定义编码) | 逆向分析编码映射表/Hook解码函数获取原始字符串 |
四、反动态调试和静态分析
| 加固方法 | 解决方法 |
|---|---|
| 自我ptrace | Hook ptrace使自我附加返回成功但不实际占用/Frida spawn模式先于ptrace执行 |
| 多线程ptrace (子线程互相附加) | Hook ptrace+kill相关检测线程/修改内核忽略ptrace限制 |
| TracePid检测 | Hook fopen/read对/proc/self/status返回TracerPid:0 |
| 软件断点检测 | 改用硬件断点(HW Breakpoint)/Hook检测函数返回未检测到 |
| 调试工具常用端口检测 | 修改调试工具为非常规端口/Hook connect/socket相关检测 |
| 调试导致的时间差检测 | Hook gettimeofday/clock_gettime返回正常时间差 |
| 信号机制反调试 | Hook signal/sigaction接管信号处理/修改信号处理函数 |
| inotify监测 | Hook inotify_init/inotify_add_watch使监控失效 |
| 内存解密数据立即销毁 | 单步调试在解密完成、销毁前断点/Hook memset阻止擦除 |
| 防止内存转储 | 动态调试修改/proc/pid/mem权限/Hook prctl绕过PR_SET_DUMPABLE |
| 自定义加载器 | 动态调试跟踪加载流程/在加载完成后dump |
| PLT桩替换 | 通常无直接绕过,分析替换后的实际函数地址 |
| 多so分段加载 | 动态调试逐段跟踪/Hook dlopen监控所有加载 |
| 插入分析工具崩溃代码 | 定位并NOP掉崩溃触发代码/patch掉检测分支 |
| 非常规dex/elf头 | 修复文件头至标准格式后分析 |
| 符号剥离 | 结合动态分析+FLIRT签名识别重命名函数/bindiff对比 |
| Section Header与Program Header不一致 | 以Program Header为准修复Section Header/忽略Section直接分析 |
| 删除symtab/strtab/shstrtab节区 | 无需节区头,基于Program Header分析/动态分析辅助标注 |
| 直接svc调用 | 动态调试在svc指令处断点/Hook内核层syscall/seccomp监控 |
| 多进程相互监控 | 动态调试逐一处理子进程/Hook fork/clone阻止监控进程创建 |
| 关闭调试配置 | 修改AndroidManifest设置debuggable=true/Magisk MagiskHide绕过 |
| 导出函数名混淆 | 动态调试+交叉引用分析确认函数功能后重命名 |
| 对齐破坏 (影响反编译器) | 修复对齐/使用支持容错的反编译器/手动调整反汇编起始点 |
| Bootloader解锁检测 | Hook sys.oem_unlock_allowed属性读取返回未解锁/Magisk隐藏 |
| OEM解锁检测 | Hook Settings.Global.getInt返回OEM未解锁状态 |
| 系统属性检测 (ro.build./ro.product.) | Hook SystemProperties.get返回正常设备属性/MagiskHide Props |
| IMEI/MEID/序列号合法性检测 | Hook TelephonyManager返回合法设备信息/设备指纹伪造 |
| VPN检测 (NetworkInterface检测tun/ppp) | Hook NetworkInterface.getName过滤tun/ppp接口/不使用VPN改用代理 |
| 代理检测 (HTTP_PROXY) | Hook System.getProperty返回无代理/使用透明代理 |
| 时区/语言/地区异常检测 | 设置设备为目标地区配置/Hook Locale/TimeZone返回正常值 |
五、检测
| 加固方法 | 解决方法 |
|---|---|
| 检测Xposed/LSPosed/Frida/EdXposed | 去除特征(Frida用hluda/stalker模式;LSPosed隐藏模式;修改特征文件名和端口) |
| 检测GOT/PLT | 在检测执行后再进行Hook/使用inline hook替代GOT hook |
| 检测inline hook | 使用更隐蔽的Hook方式(SVC Hook/虚函数表Hook)/Hook检测函数本身 |
| 签名校验 | Hook PackageManager.getPackageInfo返回原始签名/IO重定向 |
| dex/so文件完整性校验 | Hook校验函数返回通过/Hook文件读取重定向到原始文件 |
| 检测节区权限 | Hook mprotect/检测函数返回正常权限值 |
| 内存完整性校验 | Hook校验函数直接返回成功/在校验前恢复修改 |
| text代码段自校验 | Hook校验CRC/Hash函数返回预期值/修改校验基准值 |
| 检测Root/Magisk/SuperSU/su | Magisk DenyList/Shamiko模块/Hook access/fopen隐藏su路径 |
| 检测风险App | Hook PackageManager.getInstalledPackages过滤风险App列表 |
| 检测SELinux | Hook getenforce返回Enforcing/修改/sys/fs/selinux/enforce读取 |
| 检测system可读性 | Hook access/stat对system分区返回只读属性 |
| 检测Play Integrity API | 使用有效的硬件证书/TrickyStore/自定义TEE响应 |
| 检测模拟器 | 修改模拟器硬件特征(CPU/传感器/电池/Build信息)/定制ROM |
| 检测多开 | Hook检测uid/私有目录路径返回正常值/使用免检测多开方案 |
| 检测云手机 | 修改云手机硬件指纹/Hook性能和延迟检测返回正常值 |
| 检测沙箱 | 修改沙箱环境特征/Hook环境检测函数返回真机特征 |
| 过滤敏感系统调用 | 修改seccomp-bpf规则/使用允许的替代调用方式 |
| 检测截屏录屏 | Hook FLAG_SECURE检测/使用ADB截屏/虚拟显示器方式 |
| 检测脱壳机(FART/YouPK/DexHunter等) | 使用去特征的自定义ART修改版/hluda定制/去除脱壳机签名特征 |
| 防止Activity注入 | Hook taskAffinity/launchMode检测/分析注入防护逻辑后绕过 |
| 内存特征检测(hluda) | 使用重编译去特征的Frida/修改Frida agent内存特征/Stalker模式 |
| maps检测 | Hook fopen对/proc/self/maps返回过滤后内容/使用memorymaps隐藏 |
| 线程名称检测 | Hook prctl/pthread_setname_np修改线程名/重命名Frida线程 |
| D-Bus检测 | Hook D-Bus相关系统调用/关闭不必要的D-Bus通信 |
| 开发者选项检测 | Hook Settings.Global/Settings.Secure返回关闭状态 |
| USB调试检测 | Hook Settings.Global.ADB_ENABLED返回0/断开USB使用网络调试 |
| ADB连接状态检测 | Hook sys.usb.state属性/修改adbd状态返回值 |
| 自动化工具检测 (Appium/UiAutomator/Accessibility) | Hook AccessibilityService检测/去除自动化工具特征/使用底层输入注入 |
六、虚拟化
| 加固方法 | 解决方法 |
|---|---|
| Dex VMP | 分析VMP解释器(dispatcher+handler)/还原opcode映射表/编写反VMP脚本/动态trace记录handler执行序列还原原始语义 |
| SO VMP | 分析Native VMP解释器/trace记录所有handler/重建控制流/符号执行辅助还原/unicorn模拟执行 |
| Dex2C | 分析生成的Native函数/JNI调用模式识别还原Java语义/IDA+JEB联合分析/Hook JNI函数调用记录行为 |
七、流量防护
| 加固方法 | 解决方法 |
|---|---|
| 证书固定 (Certificate Pinning) | Hook SSLPeerUnverifiedException/X509TrustManager/OkHttp CertificatePinner/objection自动绕过 |
| 私有协议 | 逆向分析协议格式/Hook Socket层send/recv获取原始数据/编写协议解析器 |
| 防止中间人攻击 | 绕过证书固定后即可中间人/Hook SSL验证逻辑 |
| 防重放 | 分析timestamp/nonce生成逻辑/Hook获取算法后自行生成有效请求 |
| 请求签名 | 逆向分析签名算法/Hook签名函数获取密钥和算法/重放时重新计算签名 |
| 防抓包 | Hook网络库底层绕过代理检测/使用iptables透明代理/VPN层抓包/Hook SSL_read/write |
八、云防护
| 加固方法 | 解决方法 |
|---|---|
| 设备行为分析 | 模拟真实用户操作行为模式/使用真机/添加随机延迟和操作 |
| 用户画像 | 养号/使用真实用户行为数据模拟/长期模拟正常使用习惯 |
| 异常登录 | 使用目标地区IP/固定设备指纹/模拟正常登录时间和频率 |
| 支付风控 | 模拟正常支付行为/使用真实设备环境/避免批量异常操作 |
| 核心算法服务化 | 分析API接口协议/中间人抓包/逆向客户端请求构造逻辑/模拟请求 |
| dex/so动态下发 | Hook网络下载接口获取下发文件/监控DexClassLoader/dlopen捕获 |
| 业务动态下发 | Hook下发解析逻辑/监控文件写入目录获取下发内容/MITM截获 |
| 反爬反自动化 | 模拟真实浏览器/设备指纹/行为验证码破解/使用真机farm |
九、其他安全
| 加固方法 | 解决方法 |
|---|---|
| 只提供特定架构so文件 | 使用对应架构设备或模拟器/libhoudini ARM翻译层/QEMU模拟 |
| Logcat日志泄露 | 直接adb logcat获取敏感信息/过滤目标包名日志 |
| 日志文件泄露 | 查找应用私有目录/sdcard下的日志文件获取敏感信息 |
免责声明
本文档所有内容仅供安全研究、学术交流与技术学习使用,严禁用于任何未经授权的逆向破解、网络攻击、隐私窃取、恶意软件开发及其他违反《中华人民共和国网络安全法》《数据安全法》等法律法规的行为,使用者应确保已获得目标软件权利人的合法授权并自行承担因使用本文档内容所产生的一切法律责任与后果,作者不对任何直接或间接损害承担任何责任,继续阅读即视为您已知悉并同意上述全部条款。
浙公网安备 33010602011771号