-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathModule.m
145 lines (113 loc) · 3.98 KB
/
Module.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#import <HookKit/Module.h>
#import <HookKit/Hook.h>
#import <HookKit/Module+Internal.h>
#import <mach-o/dyld.h>
@implementation HookKitModule
@synthesize functionHookBatchingSupported, memoryHookBatchingSupported, nullImageSearchSupported;
- (BOOL)executeHook:(__kindof HookKitHook *)hook {
if([hook isKindOfClass:[HookKitClassHook class]]) {
HookKitClassHook* classHook = hook;
return [self _hookClass:[classHook objcClass] selector:[classHook selector] replacement:[classHook replacement] orig:[classHook orig]];
}
if([hook isKindOfClass:[HookKitFunctionHook class]]) {
HookKitFunctionHook* functionHook = hook;
return [self _hookFunction:[functionHook function] replacement:[functionHook replacement] orig:[functionHook orig]];
}
if([hook isKindOfClass:[HookKitMemoryHook class]]) {
HookKitMemoryHook* memoryHook = hook;
return [self _hookRegion:[memoryHook target] data:[memoryHook data] size:[memoryHook size]];
}
return NO;
}
- (int)executeHooks:(NSArray<__kindof HookKitHook *> *)hooks {
int total = [hooks count];
int result = 0;
NSMutableArray<HookKitFunctionHook *>* functionHooks = [self functionHookBatchingSupported] ? [NSMutableArray new] : nil;
NSMutableArray<HookKitMemoryHook *>* memoryHooks = [self memoryHookBatchingSupported] ? [NSMutableArray new] : nil;
for(__kindof HookKitHook* hook in hooks) {
if([hook isKindOfClass:[HookKitClassHook class]]) {
if([self executeHook:hook]) {
result += 1;
}
continue;
}
if([hook isKindOfClass:[HookKitFunctionHook class]]) {
if(functionHooks) {
[functionHooks addObject:hook];
} else {
if([self executeHook:hook]) {
result += 1;
}
}
continue;
}
if([hook isKindOfClass:[HookKitMemoryHook class]]) {
if(memoryHooks) {
[memoryHooks addObject:hook];
} else {
if([self executeHook:hook]) {
result += 1;
}
}
continue;
}
}
if(functionHooks) {
result += [self _hookFunctions:functionHooks];
}
if(memoryHooks) {
result += [self _hookRegions:memoryHooks];
}
if(result < total) {
NSLog(@"[HookKit] warning: successfully hooked less than expected (%d/%lu)", result, (unsigned long)total);
}
return result;
}
- (hookkit_image_t)openImageWithURL:(NSURL *)url {
if(!url) {
return NULL;
}
return (hookkit_image_t)[self _openImage:[[url path] fileSystemRepresentation]];
}
- (hookkit_image_t)openImageWithPath:(NSString *)path {
if(!path) {
return NULL;
}
NSURL* file_url = [NSURL fileURLWithPath:path isDirectory:NO];
return [self openImageWithURL:file_url];
}
- (void)closeImage:(hookkit_image_t)image {
if(image) {
[self _closeImage:(void *)image];
}
}
- (void *)findSymbolName:(NSString *)name {
if(!name) {
return NULL;
}
return [self findSymbolName:name inImage:NULL];
}
- (void *)findSymbolName:(NSString *)name inImage:(hookkit_image_t)image {
if(!name) {
return NULL;
}
if([self nullImageSearchSupported] || image) {
return [self _findSymbol:[name UTF8String] image:(void *)image];
}
// iterate through all loaded dyld images and call findSymbol
int count = _dyld_image_count();
for(int i = 0; i < count; i++) {
const char* image_name = _dyld_get_image_name(i);
if(image_name) {
void* _image = [self _openImage:image_name];
void* symbol = [self _findSymbol:[name UTF8String] image:_image];
[self _closeImage:_image];
if(symbol) {
NSLog(@"[HookKit] found symbol %@ in image %s", name, image_name);
return symbol;
}
}
}
return NULL;
}
@end