InspectiveC终极指南:iOS调试神器如何通过objc_msgSend Hook实现消息追踪
InspectiveC终极指南:iOS调试神器如何通过objc_msgSend Hook实现消息追踪
【免费下载链接】InspectiveCobjc_msgSend hook for debugging/inspection purposes.项目地址: https://gitcode.com/gh_mirrors/in/InspectiveC
InspectiveC是一款基于MobileSubstrate和Fishhook的iOS调试工具,通过objc_msgSend Hook技术实现Objective-C消息追踪,帮助开发者深入分析应用运行时行为。本文将带你快速掌握这款调试神器的核心功能与使用方法,让iOS开发调试效率提升10倍!
🚀 为什么选择InspectiveC进行iOS调试?
作为iOS开发中不可或缺的调试工具,InspectiveC具备以下核心优势:
- 全架构支持:完美兼容arm64和arm32架构设备
- 精准追踪:支持监控特定对象、类实例和选择器
- 详细日志:自动记录方法调用参数与层级关系
- 灵活集成:提供Cycript注入、Tweak集成等多种使用方式
日志文件默认保存在**/var/mobile/Documents/InspectiveC目录(沙盒应用位于/var/mobile/Containers/Data/Application/<App-Hex>/Documents/InspectiveC**),文件命名格式为**<exe>/<pid>_<tid>.log**,方便开发者定位问题。
🔍 核心原理:深入理解objc_msgSend Hook机制
InspectiveC的核心能力源于对Objective-C运行时核心函数objc_msgSend的Hook。通过替换系统默认的消息发送函数,实现对所有Objective-C方法调用的拦截与记录。
在InspectiveCarm64.mm中可以看到arm64架构下的Hook实现:
// arm64 hooking magic static void hook() { MSHookFunction(&objc_msgSend, (id (*)(id, SEL, ...))&replacementObjc_msgSend, &orig_objc_msgSend); }当应用调用任何Objective-C方法时,都会经过InspectiveC的replacementObjc_msgSend函数,在此完成日志记录后再调用原始的objc_msgSend函数,实现无侵入式的调试追踪。
💻 快速开始:3种安装与使用方式
1️⃣ Cycript注入方式(推荐)
这是最灵活高效的使用方式,无需重新编译应用即可动态注入:
- 确保已安装Cycript(可通过Cydia获取)
- 终端执行以下命令注入目标进程(以SpringBoard为例):
cycript -p SpringBoard- 在Cycript环境中加载InspectiveC:
intFunc=new Type("v").functionWith(int);objFunc=new Type("v").functionWith(id);classFunc=new Type("v").functionWith(Class);selFunc=new Type("v").functionWith(SEL);voidFunc=new Type("v").functionWith(new Type("v"));objSelFunc=new Type("v").functionWith(id,SEL);classSelFunc=new Type("v").functionWith(Class,SEL);handle=dlopen("/usr/lib/libinspectivec.dylib",RTLD_NOW);setMaximumRelativeLoggingDepth=intFunc(dlsym(handle,"InspectiveC_setMaximumRelativeLoggingDepth"));watchObject=objFunc(dlsym(handle,"InspectiveC_watchObject"));unwatchObject=objFunc(dlsym(handle,"InspectiveC_unwatchObject"));watchSelectorOnObject=objSelFunc(dlsym(handle,"InspectiveC_watchSelectorOnObject"));unwatchSelectorOnObject=objSelFunc(dlsym(handle,"InspectiveC_unwatchSelectorOnObject"));watchClass=classFunc(dlsym(handle,"InspectiveC_watchInstancesOfClass"));unwatchClass=classFunc(dlsym(handle,"InspectiveC_unwatchInstancesOfClass"));watchSelectorOnClass=classSelFunc(dlsym(handle,"InspectiveC_watchSelectorOnInstancesOfClass"));unwatchSelectorOnClass=classSelFunc(dlsym(handle,"InspectiveC_unwatchSelectorOnInstancesOfClass"));watchSelector=selFunc(dlsym(handle,"InspectiveC_watchSelector"));unwatchSelector=selFunc(dlsym(handle,"InspectiveC_unwatchSelector"));enableLogging=voidFunc(dlsym(handle,"InspectiveC_enableLogging"));disableLogging=voidFunc(dlsym(handle,"InspectiveC_disableLogging"));enableCompleteLogging=voidFunc(dlsym(handle,"InspectiveC_enableCompleteLogging"));disableCompleteLogging=voidFunc(dlsym(handle,"InspectiveC_disableCompleteLogging"))2️⃣ 使用InspectiveC Wrapper
适合集成到Tweak开发中,通过DEBUG宏控制:
- 在Tweak文件中包含Wrapper:
#if INSPECTIVEC_DEBUG #include "InspCWrapper.m" #endif- 调用API开始调试:
// 监控特定对象 watchObject(choose(SBUIController)[0]); // 监控特定选择器 watchSelector(@selector(viewDidLoad)); // 监控特定类 watchClass([UIViewController class]);3️⃣ 直接链接库文件
在Makefile中添加链接配置:
<YOUR_TWEAK_NAME>_LIBRARIES = inspectivec然后包含头文件使用完整API:
#include "InspectiveC.h" // 设置最大日志深度 InspectiveC_setMaximumRelativeLoggingDepth(5); // 启用完整日志 InspectiveC_enableCompleteLogging();📊 实战示例:解读InspectiveC日志
以下是典型的InspectiveC日志输出:
***-|SpringBoard@<0x15455d320> _run|*** +|NSAutoreleasePool alloc| +|NSAutoreleasePool allocWithZone:| NULL -|NSAutoreleasePool@<0x170442a00> init| -|SpringBoard@<0x15455d320> _accessibilityInit| -|SpringBoard@<0x15455d320> performSelector:withObject:afterDelay:| @selector(_accessibilitySetUpQuickSpeak) nil 1.5 +|NSArray arrayWithObject:| @"kCFRunLoopDefaultMode" -|SpringBoard@<0x15455d320> performSelector:withObject:afterDelay:inModes:| @selector(_accessibilitySetUpQuickSpeak) nil 1.5 <__NSArrayI@0x174233560>日志格式说明:
***-|...|***:表示方法调用的起始点+|:表示类方法调用-|:表示实例方法调用@<0x...>:对象内存地址- 缩进层级:表示方法调用嵌套关系
⚙️ 高级配置:优化你的调试体验
编译配置
对于iOS 10及以上系统,需使用Fishhook替代MobileSubstrate:
make package USE_FISHHOOK=1 FOR_RELEASE=1 install日志深度控制
通过设置最大相对日志深度避免日志泛滥:
// Cycript方式 setMaximumRelativeLoggingDepth(5) // 直接API调用 InspectiveC_setMaximumRelativeLoggingDepth(5);线程日志控制
灵活启用/禁用特定线程的日志记录:
// 启用当前线程日志 InspectiveC_enableLogging(); // 禁用当前线程日志 InspectiveC_disableLogging(); // 启用完整日志模式 InspectiveC_enableCompleteLogging();🔧 常见问题与解决方案
Q:在iOS 11+上无法Hook objc_msgSend?
A:需要使用Fishhook编译选项:make package USE_FISHHOOK=1
Q:日志文件过大怎么办?
A:通过setMaximumRelativeLoggingDepth限制递归深度,或使用disableLogging临时关闭日志
Q:如何只监控特定方法?
A:使用watchSelectorOnObject或watchSelectorOnClass精确监控对象或类的特定方法
📥 获取与安装
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/in/InspectiveC- 编译安装:
cd InspectiveC make package install- 或直接从stable_debs目录安装预编译deb包:
dpkg -i stable_debs/com.golddavid.inspectivec_1.2.0_iphoneos-arm.deb🎯 总结
InspectiveC通过创新的objc_msgSend Hook技术,为iOS开发者提供了强大的运行时调试能力。无论是追踪复杂的方法调用流程,还是分析第三方库的内部实现,InspectiveC都能成为你调试工具箱中的必备神器。
立即尝试InspectiveC,开启你的iOS深度调试之旅吧!如有任何问题,欢迎查阅项目中的README.md获取更多帮助。
【免费下载链接】InspectiveCobjc_msgSend hook for debugging/inspection purposes.项目地址: https://gitcode.com/gh_mirrors/in/InspectiveC
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考