mirror of
https://github.com/NohamR/RMHook.git
synced 2026-01-11 06:58:11 +00:00
Introduces build mode options (rmfakecloud, qmldiff, dev, all) to CMake and build scripts, enabling selective compilation of hooks for cloud redirection, Qt resource hooking, and reverse engineering. Adds new hooks and memory logging for dev mode, updates injection script to handle libzstd.1.dylib dependency, and documents build modes in README.
140 lines
5.0 KiB
Objective-C
140 lines
5.0 KiB
Objective-C
#import <Foundation/Foundation.h>
|
|
#import "MemoryUtils.h"
|
|
#import <mach-o/dyld.h>
|
|
#import "Logger.h"
|
|
#import "tinyhook.h"
|
|
|
|
@implementation MemoryUtils
|
|
|
|
+ (int)indexForImageWithName:(NSString *)imageName {
|
|
uint32_t imageCount = _dyld_image_count();
|
|
for (uint32_t i = 0; i < imageCount; i++) {
|
|
const char* currentImageName = _dyld_get_image_name(i);
|
|
NSString *currentImageNameString = [NSString stringWithUTF8String:currentImageName];
|
|
|
|
if ([currentImageNameString.lastPathComponent isEqualToString:imageName]) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
+ (BOOL)hookSymbol:(NSString *)imageName
|
|
symbolName:(NSString *)symbolName
|
|
hookFunction:(void *)hookFunction
|
|
originalFunction:(void **)originalFunction
|
|
logPrefix:(NSString *)logPrefix {
|
|
return [self hookSymbol:imageName
|
|
symbolName:symbolName
|
|
hookFunction:hookFunction
|
|
originalFunction:originalFunction
|
|
logPrefix:logPrefix
|
|
delayInSeconds:0];
|
|
}
|
|
|
|
+ (BOOL)hookSymbol:(NSString *)imageName
|
|
symbolName:(NSString *)symbolName
|
|
hookFunction:(void *)hookFunction
|
|
originalFunction:(void **)originalFunction
|
|
logPrefix:(NSString *)logPrefix
|
|
delayInSeconds:(NSTimeInterval)delayInSeconds {
|
|
|
|
if (delayInSeconds > 0) {
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
[self performHookSymbol:imageName
|
|
symbolName:symbolName
|
|
hookFunction:hookFunction
|
|
originalFunction:originalFunction
|
|
logPrefix:logPrefix];
|
|
});
|
|
return YES;
|
|
} else {
|
|
return [self performHookSymbol:imageName
|
|
symbolName:symbolName
|
|
hookFunction:hookFunction
|
|
originalFunction:originalFunction
|
|
logPrefix:logPrefix];
|
|
}
|
|
}
|
|
|
|
+ (BOOL)performHookSymbol:(NSString *)imageName
|
|
symbolName:(NSString *)symbolName
|
|
hookFunction:(void *)hookFunction
|
|
originalFunction:(void **)originalFunction
|
|
logPrefix:(NSString *)logPrefix {
|
|
|
|
NSLogger(@"%@ Starting hook installation for %@", logPrefix, symbolName);
|
|
|
|
int imageIndex = [self indexForImageWithName:imageName];
|
|
if (imageIndex < 0) {
|
|
NSLogger(@"%@ ERROR: Image %@ not found", logPrefix, imageName);
|
|
return NO;
|
|
}
|
|
|
|
void* symbolAddress = NULL;
|
|
|
|
// Try to find the symbol address using symtbl_solve first
|
|
symbolAddress = symtbl_solve(imageIndex, [symbolName UTF8String]);
|
|
|
|
if (symbolAddress) {
|
|
NSLogger(@"%@ %@ found with symtbl_solve at address: %p", logPrefix, symbolName, symbolAddress);
|
|
} else {
|
|
NSLogger(@"%@ %@ not found with symtbl_solve, trying symexp_solve...", logPrefix, symbolName);
|
|
symbolAddress = symexp_solve(imageIndex, [symbolName UTF8String]);
|
|
|
|
if (symbolAddress) {
|
|
NSLogger(@"%@ %@ found with symexp_solve at address: %p", logPrefix, symbolName, symbolAddress);
|
|
} else {
|
|
NSLogger(@"%@ ERROR: Unable to find symbol %@", logPrefix, symbolName);
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
// Install the hook using tiny_hook and get the original function trampoline if requested
|
|
int hookResult = tiny_hook(symbolAddress, hookFunction, originalFunction);
|
|
|
|
if (hookResult == 0) {
|
|
NSLogger(@"%@ Hook successfully installed for %@", logPrefix, symbolName);
|
|
return YES;
|
|
} else {
|
|
NSLogger(@"%@ ERROR: Failed to install hook for %@ (code: %d)", logPrefix, symbolName, hookResult);
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
+ (BOOL)hookAddress:(NSString *)imageName
|
|
staticAddress:(uintptr_t)staticAddress
|
|
hookFunction:(void *)hookFunction
|
|
originalFunction:(void **)originalFunction
|
|
logPrefix:(NSString *)logPrefix {
|
|
|
|
NSLogger(@"%@ Starting hook installation at static address: 0x%lx", logPrefix, staticAddress);
|
|
|
|
int imageIndex = [self indexForImageWithName:imageName];
|
|
if (imageIndex < 0) {
|
|
NSLogger(@"%@ ERROR: Image %@ not found", logPrefix, imageName);
|
|
return NO;
|
|
}
|
|
|
|
// Calculate ASLR slide
|
|
intptr_t slide = _dyld_get_image_vmaddr_slide(imageIndex);
|
|
NSLogger(@"%@ Image %@ ASLR slide: 0x%lx", logPrefix, imageName, slide);
|
|
|
|
// Calculate actual runtime address
|
|
void *actualAddress = (void *)(staticAddress + slide);
|
|
NSLogger(@"%@ Calculated runtime address: %p (static: 0x%lx + slide: 0x%lx)", logPrefix, actualAddress, staticAddress, slide);
|
|
|
|
int hookResult = tiny_hook(actualAddress, hookFunction, originalFunction);
|
|
|
|
if (hookResult == 0) {
|
|
NSLogger(@"%@ Hook successfully installed at address %p", logPrefix, actualAddress);
|
|
return YES;
|
|
} else {
|
|
NSLogger(@"%@ ERROR: Failed to install hook at address %p (code: %d)", logPrefix, actualAddress, hookResult);
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
@end
|