- 博客(200)
- 资源 (7)
- 收藏
- 关注
原创 动态篡改 so 函数返回值:一篇带你玩转 Android Hook 技术!
第三方 SDK 中的 so ,VMP壳 + OLLVM 混淆。ca 函数在 libhexymsb.so 偏移 0x09C8 的位置。需求:修改 so 中 ca 函数的返回值,固定为 true。只需要在 java 层添加如下代码,加载 sohooker 动态库就能实现篡改目标 so 函数的返回值。
2025-07-29 17:44:13
716
原创 OLLVM 混淆 + VMP 壳照样破!绕过加壳 SDK 的核心检测逻辑
逆向目标是一个第三方 SDK,核心代码在 so 层,已知 so 有加壳。调用入口是 *******************************************,会触发 libhexymsb.so 中的 token 和 time 检查方法,目标是绕过检查并成功调用 SDK。
2025-07-28 09:30:04
1127
原创 手把手教你改造 AAR:解包、注入逻辑、重打包,一条龙玩转第三方 SDK!
AAR 文件(Android Archive)是 Android Studio 用来打包 Android Library(库模块) 的一种压缩文件格式,扩展名是 .aar,类似于 Java 的 .jar 文件,但功能更丰富,用于复用 UI 组件、资源和代码。AAR 文件结构(解压后)├── AndroidManifest.xml # 库模块的清单文件├── classes.jar # 编译后的 Java/Kotlin 类文件(字节码)
2025-07-28 09:27:24
910
原创 一键反编译、签名、安装 APK!手把手带你玩转 ApkTool + 签名工具
apktool 用于对 Android 应用(.apk 文件)进行 反编译 和 重打包(回编译)。它可以将 APK 中的资源文件、AndroidManifest.xml 以及 DEX 代码(转换为 smali 代码)提取出来并可编辑,便于进行逆向分析、修改资源或注入逻辑等操作。
2025-07-25 15:03:20
667
原创 彻底搞懂 Retrofit:使用、封装与 Converter 原理
Retrofit 是 Square 公司开发的一个 类型安全的 HTTP 网络请求库,广泛应用于 Android 开发中。它极大地简化了 REST API 的调用方式,让网络请求就像调用本地接口一样简单。
2025-07-21 14:28:58
950
原创 打造自己的 Jar 文件分析工具:类名匹配 + 二进制搜索 + 日志输出全搞定
在逆向分析、APK 解包或 Java 工程排查中,我们常常需要检查某个 .class 文件是否存在于某个 JAR 包中,或者判断某个关键字是否被硬编码在类的字节码里。如何通过编写 Python 脚本,帮助你在 JAR 文件中快速定位类、字段,甚至二进制内容。
2025-07-21 13:23:55
912
原创 一文搞懂 Smali 与 Baksmali:Java 层逆向必备技能
dex2smali.py 是一个用于批量反编译 Android .dex 文件为 .smali 的 Python 脚本,底层调用 baksmali.jar 进行实际转换。支持将多个 dex 反编译结果:合并到一个目录(默认),或分别输出(使用 --no-merge)smali:将 smali 代码(Java汇编语言)编译成 DEX 文件。-o smali:指定输出目录,保存生成的 .smali 文件。-o new_classes.dex:输出的 DEX 文件名。smali:输入的 smali 文件目录。
2025-07-21 13:20:23
1328
原创 如何实现 Android App 的抓包防护?又该如何绕过?一文看懂攻防博弈
常见反抓包手段:No Proxy(禁用代理)启用 HTTPS + SSL Pinning使用 DNS-over-HTTPS / DoT(隐藏 DNS 请求)检查系统代理(Java 层检查 System.getProperty(“http.proxyHost”))检测 VPN 或 adb 代理使用 native 层自己实现网络请求(绕过 Java 层)证书双向校验所谓 “无代理模式” 实际上是通过主动避免走系统代理,从而规避传统的中间人抓包。设置 OkHttp 不使用系统代理,直接访问服务器:设置 NO_P
2025-07-02 15:36:34
717
原创 全面解析 OkHttp 原理与实战:从拦截器机制到 Frida Hook 打印请求响应
OkHttp 中的 Chain.proceed(request: Request): Response 是 拦截器(Interceptor)机制的核心方法,它用于在拦截器链中将请求传递给下一个拦截器并获取响应。HttpLoggingInterceptor 打印响应的核心原理是:通过 responseBody.source().buffer.clone() 克隆缓冲区内容,在不消费原始流的前提下读取并打印响应体。打印请求方法、URL、请求头、请求体(支持 UTF-8 判断和输出)
2025-06-26 19:39:13
1165
原创 手把手教你用 Chrome 断点调试 Frida 脚本,JS 调试不再是黑盒
Frida 提供 V8 和 QuickJS 两个 runtime,是为了在追求高性能(V8)和低资源消耗、快速启动、移植性强(QuickJS)之间做出权衡,并支持更强的调试能力(V8 支持 Chrome DevTools)。
2025-06-24 21:12:18
831
原创 逆向某物 App 登录接口:热修复逻辑挖掘隐藏参数、接口完整调用
找到 he.a.i 实际类型是 com.shizhuang.duapp.common.base.delegate.tasks.net.a$d。所以 he.a.C0253a 应该不是运行时的 he.a$i 实现类,通过 frida 打印一下 he.a 静态变量 i 的实际类型。t() 中调用了 yc.e0.c(null) 方法,最后实际调用的是 yc.e0 的 a() 返回 Android ID。he.a.i 是一个静态变量,类型 he.a$i ,默认值是 he.a.C0253a 实例。
2025-06-23 14:07:17
1308
原创 逆向某物 App 登录接口:还原 newSign 算法全流程
j_AES_128_ECB_PKCS5Padding_Encrypt 实际调用的是 AES_128_ECB_PKCS5Padding_Encrypt 函数。AES_128_ECB_PKCS5Padding_Encrypt 里面调用 j_AES128_ECB_encrypt 加密数据。返回值 v19 来自于 v18,是 j_AES_128_ECB_PKCS5Padding_Encrypt 方法的返回值。NCall.IL 实际调用的是 sub_17EB8 函数,而且函数内部大量引用了x y 开头的全局变量。
2025-06-22 21:30:34
1618
原创 逆向某物 App 登录接口:抓包分析 + Frida Hook 还原加密算法
Cipher.init(‘int’, ‘java.security.Key’) 方法初始化密钥,密钥是 ****************使用 Charles 分析登录接口,打开 APP,输入用户名和密码,点击登录后,可以看到会调用一个 unionLogin 接口。先尝试修改 frida-server 文件名和端口,绕过常规的文件名和端口检测,发现可以正常 Hook 了。发现当加载到 libmsaoaidsec.so 时,frida 就停止了,日志信息如下。可以看到和 App 的参数加密结果是一致的。
2025-06-21 16:39:43
1706
原创 破解 VMP+OLLVM 混淆:通过 Hook jstring 快速定位加密算法入口
j_AES_128_ECB_PKCS5Padding_Encrypt 实际调用的是 AES_128_ECB_PKCS5Padding_Encrypt 函数。AES_128_ECB_PKCS5Padding_Encrypt 里面调用 j_AES128_ECB_encrypt 加密数据。返回值 v19 来自于 v18,是 j_AES_128_ECB_PKCS5Padding_Encrypt 方法的返回值。某电商APP的加密算法经过dex脱壳分析,找到参数加密的方法在 DuHelper.doWork 中。
2025-06-20 16:12:24
374
原创 逆向 JNI 函数找不到入口?动态注册定位技巧全解析
使用 IDA Pro 静态分析时,JNI 函数并没有出现在导出表中,根本找不到函数实现的位置。这是因为很多 App 为了安全性和混淆目的,采用了 JNI 动态注册(RegisterNatives) 的方式,绕开了传统的静态绑定机制。那么遇到这种情况我们该怎么办?
2025-06-19 21:42:34
1663
原创 一文搞懂 SO 脱壳全流程:识别加壳、Frida Dump、原理深入解析
Frida 在 Android 上枚举模块(如 Process.enumerateModules())时,核心机制是:👉 遍历 linker(动态链接器)内部维护的 soinfo 链表,dlopen 成功后,linker 会将 .so 加入 solist。2、在 dump_so.js 的 dumpmodule 中获取目标 .so 文件的基地址和大小,返回内存中的 so 数据。除了用来脱壳 so ,也可以用 dump_so.js 中的函数查找 so 或打印所有 so 信息。
2025-06-11 01:30:15
1073
原创 FART 脱壳某大厂 App + CodeItem 修复 dex + 反编译还原源码
主动调用时 dump 得到的 dex (*_dex_file.dex)和此时 dex 中的所有类列表,以及该 dex 中所有函数的 CodeItem( bin 文件)Execute 脱壳点得到的 dex (*_dex_file_execute.dex)和 dex 中的所有类列表( txt 文件)是一个将 Android 的 .dex 文件转换为 Java 的 .jar 文件的工具,方便反编译和分析 APK。修复组件就是通过读取 bin 文件的 method_idx 和 ins 进行 dex 的修复的。
2025-06-06 23:26:41
1218
原创 FART 精准脱壳:通过配置文件控制脱壳节奏与范围
由于 FART 默认会对所有 app 进行脱壳,每次 app 启动都会自动脱壳,而且会对 app 中所有类发起主动调用,这样效率比较慢,遇到 FART 对抗类也不能选择性跳过。如何通过一份简单的配置文件,实现对 FART 脱壳过程的精准控制:包括是否启用脱壳、延迟时间、需要主动调用的类列表、排除类规则等。提高脱壳效率,也可以避开一些垃圾类(FART 对抗类)的调用。FART 自动化脱壳框架简介与脱壳点的选择FART 主动调用组件设计和源码分析移植 FART 到 Android 10 实现自动化脱壳。
2025-06-04 17:56:31
888
原创 攻防 FART 脱壳:特征检测识别 + 对抗绕过全解析
proc/self/maps 是 Linux(含 Android)系统中一个非常重要的伪文件,它提供了当前进程内存映射(memory mapping)信息,是分析当前进程加载了哪些资源的重要窗口。FART 在 art/runtime/native/java_lang_reflect_Method.cc 中新增了以下方法。映射的 /system/, /data/, /apex/, /dev/ashmem 等文件。通过检测 /proc/self/maps下的加载 so库列表得到各个库文件绝对路径。
2025-06-01 21:11:15
1029
原创 使用 Frida 增强 FART:实现更强大的 Android 脱壳能力
主动调用时 dump 得到的 dex (*_dex_file.dex)和此时 dex 中的所有类列表,以及该 dex 中所有函数的 CodeItem( bin 文件)Execute 脱壳点得到的 dex (*_dex_file_execute.dex)和 dex 中的所有类列表( txt 文件)枚举出所有 ClassLoader 后,再结合 FART 的 api 就可以实现动态加载 dex 的脱壳。增强 FART 的脱壳能力:解决对抗 FART 的壳、动态加载的 dex 的 dump 和修复;
2025-05-28 23:32:37
879
原创 FART 自动化脱壳框架一些 bug 修复记录
FART 中通过 mkdir 函数在 sdcard 上创建 dump 文件存放目录,但是这样必须 app 拥有存储卡读写权限。在 Android 编译构建阶段的 dex2oatd 工具执行时 调用了 art_method.cc 中的方法,导致出现下面的日志。解决方案:把 dump 路径改为:/sdcard/Android/data/<packageName>/fart。下面时一个 frida 脚本,调用系统 的 mkdir 函数创建目录。成功时:返回一个非负整数(即 >= 0),它是打开的文件描述符。
2025-05-28 00:10:19
750
原创 移植 FART 到 Android 10 实现自动化脱壳
~~~~~~~^说明:Android 6.0 中有 mirror::AbstractMethod;Android 10 中已经移除或合并进 Executable / Method 等类型。修复方式:使用 mirror::Executable(它是 ART 中 java.lang.reflect.Method 和 Constructor 的基类)代替。= nullptr);
2025-05-24 00:33:00
1277
原创 FART 主动调用组件设计和源码分析
/ DEX 字节码必须按照 4 字节对齐private:// 方法使用的虚拟寄存器数量(包括本地变量和参数)// 方法的入参占用的寄存器数量// 方法调用其他方法时所需的最大出参寄存器数量(即调用其他方法时的参数空间)// try-catch 块的数量。如果不为 0,则在 insns_ 后紧跟 try_item 和 catch_handler。// 调试信息在 DEX 文件中的偏移,指向 debug_info 结构// 包括局部变量名、源码行号映射等。
2025-05-19 23:50:19
832
原创 FART 自动化脱壳框架简介与脱壳点的选择
ART 环境下基于主动调用的自动化脱壳方案,可以解决函数抽取壳。基于 art 下的类加载机制,实现函数抽取壳FART 的作用就是所有这些被抽空的函数的还原和修复,把加固的 dex 整体 dump 下来。
2025-05-19 23:43:51
1074
原创 如何让 Google 收录 Github Pages 个人博客
SEO(Search Engine Optimization,搜索引擎优化)信息是指你在网页中设置的一些帮助搜索引擎理解、索引和展示你网站内容的内容和元数据(meta data),让你的网站更容易被搜索引擎(如 Google、Bing)收录和排到靠前的位置。将此文件放在你的 GitHub Pages 仓库下的根目录下,git push 重新构建网站。点击 “尝试使用 Google Search Console”,输入网址,点击继续。description:页面简介,可能显示在搜索结果摘要中。
2025-05-16 19:04:05
1129
原创 在 Hugo 博客中集成评论系统 Waline 与 浏览量统计
5、点击顶部的 Settings - Environment Variables 进入环境变量配置页,并配置三个环境变量 LEAN_ID, LEAN_KEY 和 LEAN_MASTER_KEY。此时请点击 Visit ,即可跳转到部署好的网站地址,此地址即为你的服务端地址。在你的 Hugo 主题中添加 Waline 的前端代码,一般是在 themes\m10c\layouts_default\single.html。的 init() 函数初始化,并传入必要的 el 与 serverURL 选项。
2025-05-15 15:47:45
801
原创 打造基于 ART 的 Android 函数抽取壳:原理剖析与完整源码实战
函数抽取壳其实就是基于 art 下的类加载机制,只有 ArtMethod 初始化完成后,java 函数才能被调用,所以通过劫持 ClassLinker::LoadMethod 函数对 ArtMethod 中的 CodeItem 打补丁的方式实现脱壳。
2025-05-14 16:23:15
731
原创 Android PLT hook 与 Inline hook
Android Native 函数 Hook 技术是一种在应用运行时拦截或替换系统或自身函数行为的手段,常见实现包括 PLT Hook、Inline Hook。PLT Hook 和 Inline Hook 是两种不同层次和机制的函数 Hook 技术,常用于逆向工程、安全分析、壳保护或热修复等场景。
2025-05-11 22:39:26
888
原创 ADB 命令使用大全(建议收藏) Android 调试必备
通过 stat 命令查看更加详细的文件信息,包括访问时间、修改时间、文件类型和 inode 号等。查找 /data 路径下所有包含 com.cyrus.example 的文件或目录。通过 adb shell 进入命令行通过 ls -alh 查看当前路径下所有文件。此时屏幕左下角会显示 – INSERT --,表示你现在可以开始输入内容。head 用于查看文本文件的前几行内容,默认是前 10 行。按下 Esc 键即可退出插入模式,回到普通模式。如果文件不存在,vim 会创建一个新的。
2025-05-10 20:37:24
2033
原创 关于 dex2oat 以及 vdex、cdex、dex 格式转换
为了提高性能,Android 会将 .dex 文件进一步编译为 .oat 文件(或 .odex/.vdex 文件),以便设备可以直接执行本地代码而不是解释执行 .dex 字节码。在 Android 9(Pie)中,APP 的 .cdex 文件 是由 dex2oat 优化生成的,通常以 odex, vdex 或直接优化后的 .art 文件形式存在。输入:一个或多个 .dex 文件(通常来自 APK 中的 classes.dex)。.oat / .odex:包含从 dex 编译来的 优化后的中间表示代码。
2025-05-05 23:47:04
1092
原创 ART 下 Dex 加载流程源码分析 和 通用脱壳点
进入 dex2oat.cc 的 main(),在 dex2oat::ReturnCode Setup() 方法中 将 dex 注册到 VerificationResults 时候可以拿到 dex_file 对象,这里也是一个很好的脱壳点。重新执行 frida 脚本 dump dex,从输出可以看到 dump 下来的 dex 魔数都是 dex 039 / dex 035 (标准 Dex 文件的魔数)不是 cdex001,可以直接用 jadx 去反编译了。
2025-05-04 22:38:16
891
原创 使用 Dex2C 加壳保护 Android APK 代码
因为 jarsigner 只能生成老的 v1 签名,apksigner 支持 v1/v2/v3/v4 新版签名,才能确保 APK 在 Android 7.0 及以上系统正常、安全安装。首先在 app 代码合适的位置,如 Application 的静态代码块或 onCreate 等,添加加载 so 库代码,并重新生成 apk。project-source.zip 是个 jni 工程,里面包含我们编译出来的 C 代码,解压出来后可以直接使用 ndk 编译。
2025-04-27 22:48:45
1062
原创 Android APP 热修复原理
从日志可以看到 PathClassLoader 的 DexPathList 中 目前有两个 Element:plugin-debug.apk 和 base.apk,而且 plugin-debug.apk 前面所以会优先找到 plugin 中的 PluginClass。PluginClass.getString:通过 Class.forName 加载 com.cyrus.example.plugin.PluginClass 类 创建对象并调用 getString方法,并显示结果。
2025-04-25 19:54:25
857
原创 Android 加壳应用运行流程 与 生命周期类处理方案
因为 系统在启动组件(如 Activity、Service)时,是通过 AMS → ActivityThread → Instrumentation 最终调用 Class.forName(组件类名) 来加载组件类的,而这个过程默认使用的是系统的 ClassLoader(通常是 PathClassLoader),而不是我们自定义的 DexClassLoader。替换系统组件类加载器为我们的 DexClassLoader,同时设置 DexClassLoader 的 parent 为系统组件类加载器。
2025-04-25 02:29:13
1007
原创 全面解析 Android App 启动流程与事件循环机制底层原理
当 Zygote fork 出新进程后,这个进程(即你的 App)会启动并运行 ActivityThread.main(),随后 系统会通过 Binder 调用 ApplicationThread.bindApplication(),然后由主线程调用 handleBindApplication()。ActivityThread 是 Android 应用进程的 主线程(UI 线程)管理类,它是系统在启动你的 App 时,创建和调度 Application 和 Activity 的关键组件。
2025-04-24 03:56:57
658
原创 Android 下的 ClassLoader 与 双亲委派机制
getClassNameList 方法需要一个参数 mCookie,mCookie 是一个 native 层的句柄(handle)或指针,它指向底层的 ART 或 Dalvik 虚拟机中加载的 DEX 文件对象,是 DexFile 对象的唯一标识。Android 中的类加载器的作用就是将 .dex、.jar 或 .apk 中的类文件(字节码)加载到内存中,转化为 Android 虚拟机 可用的 Class<?常用于插件化、热修复以及 dex 加壳。它提供了在类加载过程中对类的访问控制和安全检查的能力。
2025-04-21 02:41:58
795
原创 Android NDK 编译 so 文件 抹除导出符号 反逆向
Android 的 ART 虚拟机会用 dlsym() 查找你导出的 JNI 方法(如Java_com_example_native_NativeUtils_secretMethod),所以这些你不能隐藏,否则会导致运行时崩溃。但除了必须导出的 JNI 函数外,其余 C/C++ 函数符号不导出其实也完全没影响,编译器/链接器内部可以调用,运行时照样可以正常执行。此时 .so 中不需要导出 Java_com_example_xxx 符号,IDA 也就看不到!
2025-04-15 12:47:26
1451
原创 Frida 调用 kill 命令挂起&恢复 Android 线程
kill 是 Linux 系统中用来向进程发送信号的命令,最常用于终止进程。在底层,kill() 实际上会触发系统调用(比如 Linux 的 syscall kill),让内核发送信号给指定的进程。实现一个 suspendOtherThread 函数,挂起除了 excludeList 中指定名字的所有线程。kill 在 C 语言中是定义在 <signal.h> 中的一个标准函数,它本质上是一个系统调用的封装函数。这个目录中每一个子目录的名字就是该 App 的一个线程的 TID(Thread ID)。
2025-04-09 18:23:33
1068
原创 Frida Stalker Trace 指令跟踪&寄存器变化监控
putCallout 会在你指定的位置插入一个“钩子”,在那一刻调用你指定的 JS 函数,提供当前上下文(CPU 寄存器状态)。在 Stalker.follow 的 transform 回调函数中 处理目标线程执行的每一条汇编指令。你无法在那时访问寄存器、调用栈等。iterator 是一个 指令迭代器对象,它让你能够 逐条处理目标线程将要执行的原始机器指令。指令级跟踪:Stalker 可精确到指令级别,对应用的原生代码进行实时监控。对比当前和上一次的寄存器值,返回发生变化的寄存器(不包括 pc 寄存器)。
2025-04-07 19:41:47
1089
原创 Frida Native 层 Hook 技巧:JNI 函数调用、字符串解析、so 加载
android_dlopen_ext 是 Android 特有的 dlopen 扩展版本,允许开发者在加载共享库时使用额外的选项,比如 指定库的加载路径 或 共享库的保护标志。dlopen 函数 在 linker 模块,是 Android 系统上的动态库加载函数,用于在运行时加载共享库(.so 文件)。在 Android 系统中,这些函数的原型通常可以在 Bionic(Android 的 C 库)中找到。argTypes:一个数组,指定函数的参数类型,如 [“pointer”, “int”]。
2025-04-03 04:02:05
836
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人