二次签名会篡改信息文件
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..")?.upperBound ?? positionStr.startIndex
let toPosition = positionStr.range(of: "")?.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
void gx_AntiDebug_isatty() {
if (isatty(1)) {
_exit(1);
} else {
}
}