iOS 越狱插件 主动调用C函数和OC函数

发布于:2025-07-03 ⋅ 阅读:(19) ⋅ 点赞:(0)

主动调用函数,尤其在函数参数构造,内部依赖比较好修复的情况下,可以加速我们的动态调试。可以快速的触发逻辑,触发断点,进行调试。

直接上代码。

主动调用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");
       }
   }
}