iOS开发安全 - 防重签名、越狱、调试检测

文章目录

一、判断Mach-O文件否被篡改

二次签名会篡改信息文件

复制代码
public static func isSecondIPA() -> Bool {
        let bundle = Bundle.main
        let info = bundle.infoDictionary
        if info?["SignerIdentity"] != nil {
            return true
        }
        return false
    }

二、重签名检测

检测包签名是否和已知自己签名一致

复制代码
public static func checkCodeSign(_ provisionID: String) -> Bool {
        // 描述文件路径
        let embededPath = Bundle.main.path(forResource: "embedded", ofType: "mobileprovision")
        guard let embededPath = embededPath,
              FileManager.default.fileExists(atPath: embededPath) == true
        else {
            return true
        }
        // 读取application-identifier
        guard let embeddedProvisioning = try? String.init(contentsOfFile: embededPath, encoding: .ascii) else {
            return true
        }
        let embeddedProvisioningLines = embeddedProvisioning.components(separatedBy: CharacterSet.newlines)
        for i in 0..<embeddedProvisioningLines.count {
            let emStr = embeddedProvisioningLines[i]
            guard let index = emStr.range(of: "application-identifier")?.lowerBound,
                  index.hashValue != NSNotFound
            else {
                continue
            }
            let positionStr = embeddedProvisioningLines[i + 1]
            let fromPosition = positionStr.range(of: "<string>")?.upperBound ?? positionStr.startIndex
            let toPosition = positionStr.range(of: "</string>")?.lowerBound ?? positionStr.endIndex
            
            let range = Range(uncheckedBounds: (fromPosition, toPosition))
            
            let fullIdentifier = positionStr[range]
            let identifierComponents = fullIdentifier.components(separatedBy: ".")
            let appIdentifier = identifierComponents.first
            // 对比签名ID
            if appIdentifier == provisionID {
                return false
            } else {
                return true
            }
            
        }
        return false
    }

三、是否越狱

复制代码
public static func isJailbreak() -> Bool {
        guard TARGET_OS_SIMULATOR == 0 else {
            return false
        }
        // 越狱检查
        // CanOpenURL检查
        let fakeURL = URL(string: "cydia://package/com.fake.package")
        if UIApplication.shared.canOpenURL(fakeURL!) == true {
            return true
        }
        
        // Cydia应用检查
        var stat_info: stat
        // 使用stat系列函数检测Cydia等工具
        if stat("/Applications/Cydia.app", &stat_info) == 0 {
            return true
        }
        
        // fork函数检查
//        if fork()>=0 {
//            return true
//        }
        
        // 注入动态库检查
        if let env = getenv("DYLD_INSERT_LIBRARIES") {
            return true
        }
        
        // 无法访问文件检查
        let files = ["/Applications/Cydia.app",
                     "/Applications/limera1n.app",
                     "/Applications/greenpois0n.app",
                     "/Applications/blackra1n.app",
                     "/Applications/blacksn0w.app",
                     "/Applications/redsn0w.app",
                     "/Applications/Absinthe.app",
                     "/Library/MobileSubstrate/MobileSubstrate.dylib",
                     "/bin/bash",
                     "/usr/sbin/sshd",
                     "/etc/apt",
                     "/private/var/lib/apt/"]
        for fileName in files {
            if FileManager.default.fileExists(atPath: fileName) {
                return true
            }
        }
        return false
    }

四、防止抓包

发起请求之前判断是否存在代理,存在代理就直接返回,请求失败

复制代码
+ (BOOL)getProxyStatus {
    NSDictionary *proxySettings =  (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
    NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:@"http://www.baidu.com"]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
    NSDictionary *settings = [proxies objectAtIndex:0];
    
    NSLog(@"host=%@", [settings objectForKey:(NSString *)kCFProxyHostNameKey]);
    NSLog(@"port=%@", [settings objectForKey:(NSString *)kCFProxyPortNumberKey]);
    NSLog(@"type=%@", [settings objectForKey:(NSString *)kCFProxyTypeKey]);
    
    if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]){
        //没有设置代理
        return NO;
    }else{
        //设置代理了
        return YES;
    }
}

五、防调试

复制代码
+ (void)antiDebug {
    
    gx_disable_gdb();

    gx_AntiDebugASM();

    gx_AntiDebug_isatty();
    
}

/// ptrace反调试,阻止GDB依附
typedef int (*ptrace_ptr_t)(int _request, pid_t pid, caddr_t _addr, int _data);
#if !defined(PT_DENT_ATTACH)
#define PT_DENT_ATTACH 31
#endif
void gx_disable_gdb() {
    void * handle = dlopen(0, RTLD_GLOBAL|RTLD_NOW);
    ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
    ptrace_ptr(PT_DENT_ATTACH, 0, 0, 0);
    dlclose(handle);
}


/// 内联 svc + ptrace 实现和内联 svc + syscall + ptrace 实现
// 使用inline方式将函数在调用处强制展开,防止被hook和追踪符号
__attribute__((always_inline)) void gx_AntiDebugASM() {
#ifdef __arm__
    asm volatile(
                 "mov r0,#31\n"
                 "mov r1,#0\n"
                 "mov r2,#0\n"
                 "mov r12,#26\n"
                 "svc #80\n"
                 );
#endif
#ifdef __arm64__
    asm volatile(
                 "mov x0,#26\n"
                 "mov x1,#31\n"
                 "mov x2,#0\n"
                 "mov x3,#0\n"
                 "mov x16,#0\n"
                 "svc #128\n"
                 );
#endif
}

/// isatty检测是否正在被调试
//需要头文件#include <unistd.h>
void gx_AntiDebug_isatty() {
    if (isatty(1)) {
        _exit(1);
    } else {
    }
}
相关推荐
2501_915909063 分钟前
HTTPS 错误解析,常见 HTTPS 抓包失败、443 端口错误与 iOS 抓包调试全攻略
android·网络协议·ios·小程序·https·uni-app·iphone
云边云科技5 小时前
门店网络重构:告别“打补丁”,用“云网融合”重塑数字竞争力!
大数据·人工智能·安全·智能路由器·零售
lingggggaaaa7 小时前
小迪安全v2023学习笔记(八十一讲)—— 框架安全&ThinkPHP&Laravel&Struts2&SpringBoot&CVE复现
笔记·学习·struts·安全·网络安全·laravel
NewCarRen7 小时前
汽车EPAS ECU功能安全建模分析:Gamma框架+深度概率编程落地ISO 26262(含寿命预测案例)
安全·汽车
Amy187021118238 小时前
中线安防保护器,也叫终端电气综合治理保护设备为现代生活筑起安全防线
人工智能·安全·智慧城市
云边云科技8 小时前
企业跨区域组网新解:SD-WAN技术打造安全稳定网络体系
运维·网络·人工智能·安全·边缘计算
猫耳君10 小时前
汽车网络安全 CyberSecurity ISO/SAE 21434 测试之一
python·安全·网络安全·汽车·iso/sae 21434·cybersecurity
Rverdoser10 小时前
如何打造自主安全的下一代域名系统
安全
他们都不看好你,偏偏你最不争气12 小时前
【iOS】UIViewController
开发语言·macos·ios·objective-c·cocoa
德迅云安全杨德俊13 小时前
游戏盾:构筑网络安全防线,抵御DDoS攻击的解决方案
网络·安全·游戏·ddos