Mac OS开发工具集

破解InterfaceInspector的3种方法

2017-03-16  本文已影响731人  学无止境吧

这个是用于浏览mac os app页面布局的利器。
下载地址:

http://www.interface-inspector.com/

软件是收费的,当然也可以破解。作者没有做特别复杂的防逆向手段,这里提供3种破解思路。对于其他类似应用,大家可以举一反三。

1.注入破解

内容如下:

#import "Main.h"
#import <objc/runtime.h>
#import <objc/message.h>

@implementation NSObject (InterfaceInspectorFramework)
    
#pragma mark - SMLicenseManager
- (BOOL)hook_isLicensed {
    return YES;
}
#pragma mark - NSBundle
- (int)hook_codeSignState {
    return 0x02;
}

@end

static void __attribute__((constructor)) initialize(void) {
    CBHookInstanceMethod(SMLicenseManager, @selector(isLicensed), @selector(hook_isLicensed));
    CBHookInstanceMethod(NSBundle, @selector(codeSignState), @selector(hook_codeSignState));
}

注入之后,发现软件虽然已经授权了,但是却没有办法正常attach应用。
看下系统日志


是interface-inspector依赖了一个注入库,注入库里的一个方法过时了(在mac OS Sierra下)。
具体看这个帖子:

http://www.th7.cn/system/mac/201611/188607.shtml

去github上下载一份源码编译一下。

https://github.com/rentzsch/mach_inject

编译出mach_inject_bundle.framework文件放在/Library/Frameworks/mach_inject_bundle.framework目录下,替换掉旧的。

好了,再次使用interface-inspector注入app,成功了。

2.利用静态patch方式破解

下载app,将Interface Inspector.app/Contents/MacOS/Interface Inspector 这个二进制拖进hopper。

先去掉签名校验
在hopper的搜索框里输入finishL ,找到


我们需要干掉的2个地方就这这2个函数里。
先进void -[SMAppDelegate applicationWillFinishLaunching:]

看下下图圈起来的位置:


就是调用codeSignState 方法,返回值与0x2比较。
jne就是 jump not equal,不等于0x02,就跳往 loc_100024851

loc_100024851 是什么?就是签名不对的错误消息。

接下来就是把这段逻辑干掉,方法很多。可以吧jne改成je,我这里是直接把跳转语句nop掉了。
操作过程:鼠标选中jne loc_100024851这条汇编

hopper上面菜单选择Modify->NOP Region

处理完签名校验,接下来处理Licence
很容易在 -[SMAppDelegate applicationDidFinishLaunching:]:中找到这一段:

调用了:[[SMLicenseManager sharedInstance]isLicensed]
我们只需要改isLicensed 这个方法,让他返回true就行了。
搜索SMLicenseManager这个类,找到isLicensed函数。

选中汇编,修改为 mov rax,0x01,然后把不需要的代码nop掉。



然后选中刚才nop的位置,Modify->Assemble instruction



修改为:

把多出来的4个点也nop掉。


最终

将修改后的可执行文件,导出,替换旧的。如果有弹出框移除签名,点移除。

点击执行替换后的app,成功了!

3,打内存补丁

原理是先注入模块,然后在main函数开始之前,用静态函数搜索内存里的目标位置,把相应的二进制patch掉。
方法如下:

#import <dlfcn.h>
#import <stdlib.h>
#import <string.h>
#import <sys/types.h>
#import <mach-o/dyld.h>
#import <mach-o/loader.h>
#import <mach-o/nlist.h>
#include <sys/sysctl.h>
#include <mach/mach.h>


//patch_mem(g_xxAddr,0x00000000);
static void patch_mem(uintptr_t p,unsigned int data){//patch 8字节
    int page = getpagesize();
    uintptr_t address = (uintptr_t)(p);
    uintptr_t base = address/page * page;
    mach_port_t self = mach_task_self();
    kern_return_t error;
    if((page - (uintptr_t)(p) - base)<12){
        page *= 2;
    }
    if((error = vm_protect(self,base,page,FALSE ,VM_PROT_READ|VM_PROT_WRITE|VM_PROT_COPY))){
        return;
    }
    
    *(unsigned int *) p = data;
    if((error = vm_protect(self,base,page,FALSE,VM_PROT_READ|VM_PROT_EXECUTE))){
        return;
    }
}

static void __attribute__((constructor)) initialize_mem_patch(void) {
    const struct mach_header *mhp = _dyld_get_image_header(0);
    BOOL is64bit = mhp->magic == MH_MAGIC_64 || mhp->magic == MH_CIGAM_64;
//    uintptr_t module_base_cursor = (uintptr_t)mhp + (is64bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));
    uintptr_t module_base_cursor = (uintptr_t)mhp;
    if (is64bit) {
        uintptr_t targetCursor = module_base_cursor + 0x2447E;
        patch_mem(targetCursor,0x441f0f66);//将baseModel偏移0x2447E的位置nop掉。
        uintptr_t licenceTarget = module_base_cursor + 0x10fe7b;
        patch_mem(licenceTarget,  0x01c0c748);//mov rax,0x01
    }
}

参考文章:
http://iosre.com/t/mac-app-ui-interface-inspector-reveal-mac/3453
http://www.th7.cn/system/mac/201611/188607.shtml

上一篇下一篇

猜你喜欢

热点阅读