iOS重签名防护和sysctl调试

  • 一 重签名防护
    想自己的app不被重签名,可以在代码中检测签名信息,然后采取措施
    查看证明组织单位进入.app的包内容,查看embedded.mobileprovision信息security cms -D -i embedded.mobileprovision 找到application-identifier的value的第一部分就是

利用签名信息进行重签名防护

void  checkCodesign(NSString *id){
    // 描述文件路径
    NSString *embeddedPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
    // 读取application-identifier  注意描述文件的编码要使用:NSASCIIStringEncoding
    NSString *embeddedProvisioning = [NSString stringWithContentsOfFile:embeddedPath encoding:NSASCIIStringEncoding error:nil];
    NSArray *embeddedProvisioningLines = [embeddedProvisioning componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];

    for (int i = 0; i < embeddedProvisioningLines.count; i++) {
        if ([embeddedProvisioningLines[i] rangeOfString:@"application-identifier"].location != NSNotFound) {

            NSInteger fromPosition = [embeddedProvisioningLines[i+1] rangeOfString:@"<string>"].location+8;

            NSInteger toPosition = [embeddedProvisioningLines[i+1] rangeOfString:@"</string>"].location;

            NSRange range;
            range.location = fromPosition;
            range.length = toPosition - fromPosition;

            NSString *fullIdentifier = [embeddedProvisioningLines[i+1] substringWithRange:range];
            NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."];
            NSString *appIdentifier = [identifierComponents firstObject];

            // 对比签名ID
            if (![appIdentifier isEqual:id]) {
                //exit
                asm(
                    "mov X0,#0\n"
                    "mov w16,#1\n"
                    "svc #0x80"
                    );
            }
            break;
        }
    }
}
  • 二 sysctl检测是否被调试
#import <sys/sysctl.h>
bool checkDebugger(){
    //控制码
    int name[4];//放字节码-查询信息
    name[0] = CTL_KERN;//内核查看
    name[1] = KERN_PROC;//查询进程
    name[2] = KERN_PROC_PID; //通过进程id查进程
    name[3] = getpid();//拿到自己进程的id
    //查询结果
    struct kinfo_proc info;//进程查询信息结果
    size_t info_size = sizeof(info);//结构体大小
    int error = sysctl(name, sizeof(name)/sizeof(*name), &info, &info_size, 0, 0);
    assert(error == 0);//0就是没有错误

    //结果解析 p_flag的第12位为1就是有调试
    //p_flag 与 P_TRACED =0 就是有调试
    return ((info.kp_proc.p_flag & P_TRACED) !=0);

}

检测到调试就退出

if (checkDebugger()) {
        asm("mov X0,#0\n"
            "mov w16,#1\n"
            "svc #0x80"
            );

    }
  • 三 针对二 破解sysctl
    因为sysctl是系统方法,所以可以被fishhook给hook,所以可以动态库注入,hook到sysctl,改变sysctl的查询结果使用异或取反kp_proc.p_flag
//原始函数的地址
int (*sysctl_p)(int *, u_int, void *, size_t *, void *, size_t);

//自定义函数
int mySysctl(int *name, u_int namelen, void *info, size_t *infosize, void *newinfo, size_t newinfosize){
    if (namelen == 4
        && name[0] == CTL_KERN
        && name[1] == KERN_PROC
        && name[2] == KERN_PROC_PID
        && info
        && (int)*infosize == sizeof(struct kinfo_proc))
    {
        int err = sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
        //拿出info做判断
        struct kinfo_proc * myInfo = (struct kinfo_proc *)info;
        if((myInfo->kp_proc.p_flag & P_TRACED) != 0){
            //使用异或取反
            myInfo->kp_proc.p_flag ^= P_TRACED;
        }


        return err;
    }

    return sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
}


+(void)load
{
    //交换
    rebind_symbols((struct rebinding[1]){{"sysctl",mySysctl,(void *)&sysctl_p}}, 1);
}
  • 四 针对三 不让sysctl失效
    可以在fishhook sysctl之前就检测,根我之前ptrace生效的策略一样,自己写库,在库中每隔一段时间就检测一下sysctl。因为自己的库最新被调用.

  • 五 用汇编调用关键系统方法
    自己库最新被调用的防护方法,可以符号断点断住,然后定位到sysctl的位置,最后改变macho的二进制从而破解,所以通过汇编调用sysctl ptrace exit等是相对安全的
    exit:

        asm("mov X0,#0\n"
            "mov w16,#1\n"
            "svc #0x80"
            );
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# Resign ipa签名(resign),只需一个证书的p12和一个mobileprovision文件就可以实现ipa的签名 ## (1)使用规则 ### 1.将Resign.sh与你的mobileprovision文件和ipa文件放在同一个文件夹内。 ### 2.打开命令行,复制 chmod +x ,再敲一个空格,再将Resign.sh拖入命令行里面,回车。 ### 3.继续将Resign.sh拖入命令行内,回车,将会出现证书选择项,选择与你mobileprovision文件相匹配的证书,回车。 ### 4.等待数秒钟(视你的ipa资源文件的多少而定)。最后在output文件中就可以找到签名成功地ipa。 ### 5.安装,完美! !_ ! ## (2)工程配置选项 ### 1.打开Resign.sh 在头部有: 1).hiddenWorkspace:是否隐藏工作目录,默认设置1为隐藏。 2).Debug:测试模式;功能有:debug模式不会删除工作目录,也不会隐藏工作目录。 3).日志文件:在Resign.sh同一目录下地log.txt,里面有详细的日志输出。 ## (3)错误提示 ### 1."该文件夹中包含多个ipa,请只放置一个需签名的ipa":文件夹内没放或者放了多个ipa文件,导致无法读取ipa文件;解决办法:只留一个需签名的ipa文件。 ### 2."该文件夹中包含多个provisitionFile,请只放置一个需签名的provisitionFile":同上 ### 3."XX文件不存在":该文件没有在Resign.sh同一目录下。 ### 4."Entitlements处理失败":请前往log日志里面查看原因。 ### 5."所选证书与provisionfile的group不匹配":请检查证书和provisionfile是否匹配。 ### 6."XX解压ipa失败":请确定ipa文件是否有损坏或者是否为ipa文件。 ### 7."XX拷贝失败":请确认该文件是否在Resign.sh同一目录下。 ### 8."修改info.plist失败":请确认文件目录是否有改变。 ### 9."签名失败":同第4点。 ### 10."验证签名完整性失败":请开启debug模式再次运行查看Payload文件是否存在。 注意: 部分ipa含screenShare可能会导致签后无法安装, 可以删除screenShare 或者从ipa 里删了screenShare screenshare.appex 再执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值