它是在Theos開發中容許hook代碼很是的簡單明瞭,它可以替換、修改、新增方法或者類。php
這種等級必須以%end結尾,而且也不存在函數ios
%group Groupname
複製代碼
若是爲了支持適配不一樣系統的代碼,能夠經過如下方式c++
%group iOS8
%hook IOS8_SPECIFIC_CLASS
// your code here
%end // end hook
%end // end group ios8
%group iOS9
%hook IOS9_SPECIFIC_CLASS
// your code here
%end // end hook
%end // end group ios9
%ctor {
if (kCFCoreFoundationVersionNumber > 1200) {
%init(iOS9);
} else {
%init(iOS8);
}
}
複製代碼
全部的hook都有隱藏了一個「_ungrouped」的隱式分組;它用來修飾類名objective-c
%hook Classname
複製代碼
hook之間的代碼是SBApplicationController具體的函數bash
%hook SBApplicationController
-(void)uninstallApplication:(SBApplication *)application {
NSLog(@"Hey, we're hooking uninstallApplication:!");
%orig; // Call the original implementation of this method
return;
}
%end
複製代碼
給hook的類添加新方法;signature是OC類型的新方法名,必須在%hook塊之間app
%new // 修飾新的方法
%new(signature) // 修飾新的方法signature
複製代碼
%hook ClassName
%new
- (id)someValue {
return objc_getAssociatedObject(self, @selector(someValue));
}
%end
複製代碼
經過運行時建立的子類,ivars不支持;使用%new修飾新增的方法,若是須要訪問新類,必須經過%c
操做符獲取,能夠在%group塊中iphone
%subclass MyObject : NSObject
- (id)init {
self = %orig;
[self setSomeValue:@"value"];
return self;
}
//the following two new methods act as `@property (nonatomic, retain) id someValue;`
%new
- (id)someValue {
return objc_getAssociatedObject(self, @selector(someValue));
}
%new
- (void)setSomeValue:(id)value {
objc_setAssociatedObject(self, @selector(someValue), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
%end
%ctor {
MyObject *myObject = [[%c(MyObject) alloc] init];
NSLog(@"myObject: %@", [myObject someValue]);
}
複製代碼
%property (nonatomic|assign|retain|copy|weak|strong|getter|setter) Type name;
複製代碼
添加新的屬性在類中,必須在%hook
修飾或者%subclass
修飾的內部。函數
%end
複製代碼
用來修飾group/hook/subclass
的塊結束ui
這部分的指令再也不group/hook/subclass
的塊內部。this
%config(Key=Value);
複製代碼
%hookf(rtype, symbolName, args...) { … }
複製代碼
// Given the function prototype
FILE *fopen(const char *path, const char *mode);
// The hook is thus made
%hookf(FILE *, fopen, const char *path, const char *mode) {
NSLog(@"Hey, we're hooking fopen to deny relative paths!");
if (path[0] != '/') {
return NULL;
}
return %orig; // Call the original implementation of this function
}
複製代碼
CFBooleanRef (*orig_MGGetBoolAnswer)(CFStringRef);
CFBooleanRef fixed_MGGetBoolAnswer(CFStringRef string)
{
if (CFEqual(string, CFSTR("StarkCapability"))) {
return kCFBooleanTrue;
}
return orig_MGGetBoolAnswer(string);
}
%hookf(CFBooleanRef, "_MGGetBoolAnswer", CFStringRef string)
{
if (CFEqual(string, CFSTR("StarkCapability"))) {
return kCFBooleanTrue;
}
return %orig;
}
複製代碼
%ctor { … }
複製代碼
匿名構造方法
%dtor { … }
複製代碼
匿名銷燬構造方法
只在函數block中
%init;
%init([<class>=<expr>, …]);
%init(Group[, [+|-]<class>=<expr>, …]);
複製代碼
初始化分組或默認分組
%hook SomeClass
-(id)init {
return %orig;
}
%end
%ctor {
%init(SomeClass=objc_getClass("class with spaces in the name"));
}
複製代碼
%c([+|-]Class)
複製代碼
等價於實例對象,或者類名
%orig
%orig(arg1, …)
複製代碼
調用原始方法,不可以在%new裏面,
%log;
%log([(<type>)<expr>, …]);
複製代碼
打印日誌
Extension | Process order |
---|---|
.x | will be processed by Logos, then preprocessed and compiled as objective-c. |
.xm | will be processed by Logos, then preprocessed and compiled as objective-c++. |
.xi | will be preprocessed as objective-c first, then Logos will process the result, and then it will be compiled. |
.xmi | will be preprocessed as objective-c++ first, then Logos will process the result, and then it will be compiled. |
xi或者xmi文件能夠使用#define 宏
自動動幫你生成對應類的全部hook方法
$THEOS/bin/logify.pl ./SSDownloadAsset.h
複製代碼