A powerful, quickly, light-weight hooking tool on iOS device without jailbreak.
在非越狱 iOS 平台上的强大的、快速的、轻量级 Hook 工具。
- Hook methods of ObjC class. Hook一个二进制文件中的类的对象方法
- Create subclass extends ObjC class. 创建一个二进制文件中的类的子类
- Create instances of the classes in binary file, 创建一个二进制文件中的类的对象
- Send message to class in binary file. 向二进制文件中的类发消息(工厂方法)
- Support code hinting in Xcode. 支持 Xcode 的代码提示
orig code 原代码
@interface MUFastCallClass : NSObject
{
NSString *_name;
}
- (instancetype)initWithInteger:(NSInteger)integer object:(id)object;
+ (instancetype)instanceWithInteger:(NSInteger)integer object:(id)object;
@end
hook code 插件代码
// Alloc an instance without linking.
// 创建一个对象,如果直接 [[Class alloc] init] 调用,编译时候报 link 错误
MUFastCallClass *instance = MUHAllocInitWith(MUFastCallClass, initWithInteger:1 object:[NSObject new]);
// Get associated object
// 取关联对象
NSObject *obj = MUHGetObjectAsct(instance, object);
// Set associated object, supporting: strong/weak/assign/copy
// 设置关联对象,最后一个值支持: strong、weak、assign、copy
MUHSetObjectAsct(instance, object, nil, strong);
// Get ivar value
// 取实例变量
NSString *name = MUHGetObjectIvar(instance, _name);
// Set ivar value
// 设置实例变量
MUHSetObjectIvar(instance, _name, @"New Name");
See more: MUHookDemo/Sample-FastCall
orig code 原代码
@interface MUHookClass : NSObject
+ (instancetype)instanceWithInt:(NSInteger)integer object:(id)object;
- (void)voidMethodWithObject:(id)object;
- (id)returnValueMethod;
@end
hook code 插件代码
// Define a class method named 'factory' to hook +[MUHookClass instanceWithInt:object:]
// 定义一个新的类方法实现体,称之'factory'(该名称只要自己保证类内唯一性即可)
MUHClassImplementation(MUHookClass, factory, MUHookClass *, NSInteger integer, id object) {
NSLog(@"__hook__ -[MUHookClass instanceWithInt:object:]");
MUHookClass *instance = MUHOrig(MUHookClass, factory, integer, object);
return instance;
}
// Define an instance method named 'voidMethod' to hook
// -[MUHookClass voidMethodWithObject:]
// 定义一个新的带参数、无返回值的实例方法实现体
MUHInstanceImplementation(MUHookClass, voidMethod, void, id object) {
NSLog(@"__hook__ -[MUHookClass voidMethodWithObject:]");
MUHOrig(MUHookClass, voidMethod, object);
}
// Define an instance method named 'returnMethod' to hook
// -[MUHookClass returnValueMethod]
// 定义一个新的带返回值,无参数的实例方法体
MUHInstanceImplementation(MUHookClass, returnMethod, id) {
NSLog(@"__hook__ -[MUHookClass returnValueMethod]");
return MUHOrig(MUHookClass, returnMethod);
}
// Execute hook
// You need call the function MUHInitClass() in MUHMain()
// 执行 Hook
// 请在 MUHMain() 中手动调用该函数以生效以上 hook
void MUHInitClass(MUHookClass)
// Hook class method:ClassName,MethodName,SEL
// 参数列表:类名,自己取得方法名(与上面的方法体相同),SEL
MUHHookClassMessage(MUHookClass, factory, instanceWithInt:object:);
// Hook instance method:ClassName,MethodName,SEL
// 参数列表:类名,自己取得方法名(与上面的方法体相同),SEL
MUHHookInstanceMessage(MUHookClass, voidMethod, voidMethodWithObject:);
MUHHookInstanceMessage(MUHookClass, returnMethod, returnValueMethod);
}
// In the other files(such as: Main.m).
// Create an entry function to excute all hook.
// 在某个文件中(如 Main.m)
// 创建一个 MUHMain() 函数,来执行以上所有类的 Hook。
void MUHMain() {
MUHInitClass(MUHookClass);
MUHInitClass(...);
...
}
See more: MUHookDemo/Sample-Hook
orig code 原父类代码
@interface MUExtendsSuperClass : NSObject
+ (instancetype)superInstanceWithInt:(NSInteger)integer object:(id)object;
- (void)superVoidMethodWithObject:(id)object;
- (id)superReturnValueMethod;
@end
hook code 插件子类代码
// Define a class method named 'subInstance' to override
// +[MUExtendsSuperClass superInstanceWithInt:object:]
MUHClassImplementation(MUExtendsSubClass, subInstance, MUExtendsSubClass *, NSInteger integer, id object) {
NSLog(@"+[MUExtendsSubClass superInstanceWithInt:(NSInteger)%ld object:(id)%@]", integer, object);
integer += 1; // Modify arguments
MUExtendsSubClass *subInstancce = MUHSuper(MUExtendsSubClass, subInstance, integer, object);
return subInstancce;
}
// Define an instance method named 'voidMethod' to override
// +[MUExtendsSuperClass superVoidMethodWithObject:]
MUHInstanceImplementation(MUExtendsSubClass, voidMethod, void, id object) {
NSLog(@"+[MUExtendsSubClass superVoidMethodWithObject:(id)%@]", object);
object = [MUExtendsSuperClass new]; // Modify arguments
MUHSuper(MUExtendsSubClass, voidMethod, object);
}
// Define an instance method named 'returnMethod' to override
// +[MUExtendsSuperClass superReturnValueMethod]
MUHInstanceImplementation(MUExtendsSubClass, returnMethod, id) {
NSLog(@"+[MUExtendsSubClass superReturnValueMethod]");
id returnValue = MUHSuper(MUExtendsSubClass, returnMethod);
return returnValue;
}
void MUHInitClass(MUExtendsSubClass) {
/**
* PS: When you call MUHCreateClass(), it will call createClass() and registerClassPair().
* So you can't add any ivar to this class.
* Please use association-object if you want to add propertys to the new class.
*
* 注意:当你调用 MUHCreateClass(),会自动调用 createClass() 和 registerClassPair() 函数。
* 所以你不能自定义添加实例变量到新的子类中
* 如果你需要定义属性,请使用关联对象
*/
// Create a subclass
MUHCreateClass(MUExtendsSubClass, MUExtendsSuperClass);
// Add class method:ClassName,MethodName,SEL,typeencoding
MUHAddClassMethod(MUExtendsSubClass, subInstance, superInstanceWithInt:object:, @@:q@);
// Add instance method:ClassName,MethodName,SEL,typeencoding
MUHAddInstanceMethod(MUExtendsSubClass, voidMethod, superVoidMethodWithObject:, v@:@);
MUHAddInstanceMethod(MUExtendsSubClass, returnMethod, superReturnValueMethod, @@:);
}
See more: MUHookDemo/Sample-Extends
// Define function to hook malloc()
// 定义一个新的 malloc 函数实现体
MUHSymbolImplementation(malloc, void *, size_t size) {
printf("malloc(%lu)\n", size);
return MUHSymbolOrig(malloc, size);
}
// Define function to hook getchar()
// 定义一个新的 getchar 函数实现体
MUHSymbolImplementation(getchar, int) {
printf("New temp\n");
return MUHSymbolOrig(getchar);
}
// Hook functions.
// You need call the function in MUHMain().
// 执行本文件的模块 hook
// 该函数需要在 MUHMain() 中被调用,以上实现才生效
void initMUHookSymbolSample() {
MUHHookSymbolFunction(getchar);
MUHHookSymbolFunction(malloc);
}