前沿
Hook是逆向研发的常用技能,Hook能够快速验证猜想,更改原有逻辑。在iOS端,常用Hook分为4类:OC runtime交换方法,captainhook, Fishhook, Dobbyx。
操作流程
- OC runtime原理&示例
- CaptainHook原理&示例
- FishHook原理&示例
- Dobbyx原理&示例
OC runtime原理&示例
1.原理
1.1.runtime是iOS端的运行机制,在这种机制下,苹果给开发者提供了相关API,供开发者实现方法交换,通过这个方法method_exchangeImplementations
即可实现方法交换。
这种能力的使用场景很多:全埋点,对于老代码中某个方法的全局修改。
2.示例
- 封装一个方法交换方法
+ (BOOL)swizzleOriginMethod:(SEL)originalSEL withAlternateMethod:(SEL)alternateSEL {
//获取原始的方法
Method originalMethod = class_getInstanceMethod(self, originalSEL);
if (!originalMethod) {
return NO;
}
//获取将要交换的方法
Method alternateMethod = class_getInstanceMethod(self, alternateSEL);
if (!alternateMethod) {
return NO;
}
//交互两个方法的实现
method_exchangeImplementations(originalMethod, alternateMethod);
//返回yes,方法交换成功
return YES;
}
- 在
+(void)load{}
方法中实现方法交换
+ (void)load {
[self swizzleOriginMethod:@selector(hook1:) withAlternateMethod:@selector(hook1_:)];
}
CaptainHook原理&示例
1.原理
Captainhook是一个头文件,由很多宏定义构成,是越狱机上的一个hook方案,配合MonkeyDev项目可以快速编写Hook。
mobilesubstrate分为MobileHooker
、MobileLoader
以及Safe mode
MobileHooker
,是CydiaSubstrate
的一个组件,对C
和Objective-C
均有效,
MobileHooker
组件主要提供了MSHookMessageEx
和MSHookFunction
两个函数针对不同语言的inline hook
功能,其中MSHookMessageEx
负责用来hook Objective-C
函数,MSHookFunction
负责用来hook C/C++
函数
MSHookMessageEx
本质还是利用runtime去获取某个类的一些信息,然后class_replaceMethod
。
static inline Class CHLoadClass_(CHClassDeclaration_ *declaration, Class value)
{
declaration->class_ = value;//自己本身
declaration->metaClass_ = object_getClass(value);//他的isa地址
declaration->superClass_ = class_getSuperclass(value);//从父类开始查找value(也可以说是symbol)
return value;
}
2.示例
//声明要操作的类
CHDeclareClass(ViewController)
//要操作的方法
CHOptimizedMethod1(self, void, ViewController, testFunc, NSString*, arg1) {
arg1 = @"new testFun";
CHSuper1(ViewController, testFunc, arg1);
}
//在main之前加载进去
CHConstructor{
CHLoadLateClass(ViewController);
CHHook1(ViewController, testFunc);
}
FishHook原理&示例
1.原理
C语言是静态的,调用某个函数跳转到某个地址,这是在编译链接时就决定了。
如果调用的C函数是动态库中的,那么在启动前是不知道这个函数的地址的,这个地址是运行时算出来的,既然是运行时算的,那么就有机会操作。
在macho文件DATA段中
__la_symbol_ptr
懒加载指针表,表中的指针一开始都指向__stub_helper
,第一次调用才绑定值。
fishhook通过遍历
__la_symbol_ptr
,找到第i个元素对应的名字,就可以将__la_symbol_ptr
中第i个元素改掉,完成hook。
2.示例
static int (*open_origin)(const char *, int, ...);
int new_open(const char *path, int oflag, ...) {
printf("我就是不打开文件\n");
return 0;
}
- (void)fishHookAction {
// struct rebinding {
// const char *name; //需要hook的函数名称,C字符串
// void *replacement;//新函数地址
// void **replaced;//原始函数地址的指针(二级指针)
// };
//rebind_symbols rebinding结构体的数组,包含重新绑定的信息
//rebindings_nel 绑定的个数
//int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel);
//初始化rebinding结构体
struct rebinding open_rebinding = { "open", new_open, (void *)&open_origin };
//将结构体包装数组,传入数组大小,对原符号重新绑定
rebind_symbols((struct rebinding[1]){open_rebinding}, 1);
//调用open函数
int fd = open("~/DeskTop/1.txt", O_RDWR);
}
Dobbyx原理&示例
1.原理
2.示例
- (void)dobbyxAction {
NSLog(@"最新的结果是: %d",sum(3,2));
}
int sum(int a,int b){
return a + b;
}
//函数指针用于保留原来的执行流程
static int(*sum_p)(int a,int b);
//新函数
int mySum(int a,int b){
NSLog(@"原有的结果是:%d",sum_p(a,b));
return a - b;
}
总结: 正向开发用swizzle,逆向OC方法Captainhook,逆向系统C函数Fishhook,逆向自定义C函数Dobbyx。
只做技术分享
5.附件
请联系作者索取