iOS 越狱插件 主动调用C函数和OC函数
主动调用函数,尤其在函数参数构造,内部依赖比较好修复的情况下,可以加速我们的动态调试。可以快速的触发逻辑,触发断点,进行调试。
直接上代码。
主动调用C函数 NSString *__fastcall sub_100099999():
//
// hook_test_captain.mm
// hook_test_captain
//
//#if TARGET_OS_SIMULATOR
#error Do not support the simulator, please use the real iPhone Device.
#endif#import <Foundation/Foundation.h>
#import "CaptainHook/CaptainHook.h"
#import <mach-o/dyld.h>
#import <mach-o/getsect.h>CHConstructor
{@autoreleasepool{// 获取主可执行文件的正确ASLR偏移量uint32_t imageCount = _dyld_image_count();NSLog(@"Image count: %d", imageCount);// 打印所有镜像的信息,找到主可执行文件intptr_t slide = 0;for (uint32_t i = 0; i < imageCount; i++) {const char* imageName = _dyld_get_image_name(i);intptr_t currentSlide = _dyld_get_image_vmaddr_slide(i);NSLog(@"[%d] Image: %s, Slide: 0x%lx", i, imageName, (unsigned long)currentSlide);// 检查是否为主可执行文件NSString *imagePath = [NSString stringWithUTF8String:imageName];if ([imagePath isEqualToString:[[NSBundle mainBundle] executablePath]]) {slide = currentSlide;NSLog(@"Found main executable at index %d with slide: 0x%lx", i, (unsigned long)slide);break;}}// 如果没有找到主可执行文件,尝试使用另一种方法if (slide == 0) {// 获取TEXT段的实际加载地址const struct mach_header* header = _dyld_get_image_header(0);uintptr_t textSegmentCmd = (uintptr_t)(header + 1);uintptr_t textVmaddr = 0;// 遍历所有load commands找到__TEXT段for (uint32_t i = 0; i < header->ncmds; i++) {const struct load_command* loadCmd = (struct load_command*)textSegmentCmd;if (loadCmd->cmd == LC_SEGMENT || loadCmd->cmd == LC_SEGMENT_64) {const struct segment_command_64* segmentCmd = (struct segment_command_64*)loadCmd;if (strncmp(segmentCmd->segname, "__TEXT", 16) == 0) {textVmaddr = segmentCmd->vmaddr;break;}}textSegmentCmd += loadCmd->cmdsize;}if (textVmaddr != 0) {// 计算slide = 实际加载地址 - 预期加载地址slide = (intptr_t)header - textVmaddr;NSLog(@"Calculated slide using TEXT segment: 0x%lx", (unsigned long)slide);}}// 计算函数的实际地址// 主动调用 NSString *__fastcall sub_100099999()void *functionAddress = (void *)(0x100099999 + slide);NSLog(@"Static function address: 0x100099999");NSLog(@"Calculated runtime function address: %p", functionAddress);// 定义函数指针类型并调用NSString * (*targetFunction)(void) = (NSString * (*)(void))functionAddress;// 调用函数并打印返回值NSString *result = targetFunction();NSLog(@"Function at 0x100099999 returned: %@", result);}
}
主动调用OC函数:
CHConstructor // code block that runs immediately upon load
{@autoreleasepool{// 主动调用这个函数 +[ClazzTarget calcKeyStr]Class ClazzTargetClass = NSClassFromString(@"ClazzTarget");if (ClazzTargetClass) {SEL calcKeyStrSelector = NSSelectorFromString(@"calcKeyStr");if ([ClazzTargetClass respondsToSelector:calcKeyStrSelector]) {NSString *result14 = [ClazzTargetClass performSelector:calcKeyStrSelector];NSLog(@"[htest] calcKeyStr返回值: %@", result14);} else {NSLog(@"[htest] Error: calcKeyStr method not found in ClazzTarget class");}} else {NSLog(@"[htest] Error: ClazzTarget class not found");}// 主动调用这个函数 +[ClazzTarget calcKeyStr2]if (ClazzTargetClass) {SEL calcKeyStr2Selector = NSSelectorFromString(@"calcKeyStr2");if ([ClazzTargetClass respondsToSelector:calcKeyStr2Selector]) {NSString *result15 = [ClazzTargetClass performSelector:calcKeyStr2Selector];NSLog(@"[htest] calcKeyStr2返回值: %@", result15);} else {NSLog(@"[htest] Error: calcKeyStr2 method not found in ClazzTarget class");}} else {NSLog(@"[htest] Error: ClazzTarget class not found");}}
}