1.阻止动态调试
GDB、LLDB是Xcode内置的动态调试工具。使用GDB、LLDB可以动态的调试你的应用程序(通过下断点、打印等方式,查看参数、返回值、函数调用流程等)。
为了阻止hackers使用调试器 GDB、LLDB来攻击你的App,你可以在main.m文件中插入以下代码:
#import
typedefint(*ptrace_ptr_t)(int_request,pid_t_pid,caddr_t_addr,int_data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH31
#endif
voiddisable_gdb() {
void* handle =dlopen(0,RTLD_GLOBAL|RTLD_NOW);
ptrace_ptr_tptrace_ptr =dlsym(handle,"ptrace");
ptrace_ptr(PT_DENY_ATTACH,0,0,0);
dlclose(handle);
}
int main(intargc,char* argv[]) {
appStartTime = [NSDate date];
#if !(DEBUG)
//非 DEBUG 模式下禁止调试
disable_gdb();
#endif
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
2.越狱检测
a.判断设备是否安装了越狱常用工具:
一般安装了越狱工具的设备都会存在以下文件:
/Applications/Cydia.app
/Library/MobileSubstrate/MobileSubstrate.dylib
/bin/bash
/usr/sbin/sshd
/etc/apt
b.判断设备上是否存在cydia应用
c.是否有权限读取系统应用列表
d.没有越狱的设备是没有读取所有应用名称的权限
e.检测当前程序运行的环境变量 DYLD_INSERT_LIBRARIES
f.非越狱手机DYLD_INSERT_LIBRARIES获取到的环境变量为NULL。
- (BOOL)isBroken {
// 检查是否存在越狱常用文件
NSArray *jailFilePaths = @[@"/Applications/Cydia.app",
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
@"/bin/bash",
@"/usr/sbin/sshd",
@"/etc/apt"];
for(NSString*filePathinjailFilePaths) {
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
returnYES;
}
}
// 检查是否安装了越狱工具Cydia
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]){
returnYES;
}
// 检查是否有权限读取系统应用列表
if ([[NSFileManager defaultManager] fileExistsAtPath:@"/User/Applications/"]){
NSArray *applist = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"/User/Applications/"
error:nil];
NSLog(@"applist = %@",applist);
returnYES;
}
// 检测当前程序运行的环境变量
char *env = getenv("DYLD_INSERT_LIBRARIES");
if(env !=NULL) {
returnYES;
}
return NO;
}
3.防止二次打包
可以从反编译过来的程序安装包获取二进制文件或者图片等文件,进行修改之后替换回到安装包中。对于设备已经越狱的用户,大多数更倾向于从网上下载ipa安装包进行安装。攻击者修改文件内容并诱骗给用户安装,会造成用户敏感信息被窃取的风险。
检测ipa文件是否被篡改可以通过以下方法:
通过对CodeResources读取资源文件原始hash,和当前hash进行对比,判断是否经过篡改,被篡改过的文件应从服务器重新请求资源文件进行替换;
可以通过检测SignerIdentity判断是Mach-O文件否被篡改;
可以通过检测cryptid的值来检测Mach-O文件是否被篡改,篡改过cryptid的值为1。
这里主要介绍方法2.通过检测SignerIdentity判断是Mach-O文件否被篡改
原理是:SignerIdentity的值在info.plist中是不存在的,开发者不会加上去,苹果也不会,只是当ipa包被反编译后篡改文件再次打包,需要伪造SignerIdentity。
- (BOOL)isSecondPack {
NSBundle *bundle = [NSBundle mainBundle];
NSDictionary *info = [bundle infoDictionary];
if([infoobjectForKey:@"SignerIdentity"] !=nil){
//存在这个key,则说明被二次打包了
returnYES;
}
return NO;
}
4.防止抓包篡改数据
#pragma mark -- 在网络请求前插入这个方法,再根据需求做相应的防范
- (BOOL)getDelegateStatus {
NSDictionary *proxySettings = CFBridgingRelease((__bridge CFTypeRef _Nullable)((__bridge NSDictionary *)CFNetworkCopySystemProxySettings()));
NSArray *proxies = CFBridgingRelease((__bridge CFTypeRef _Nullable)((__bridge NSArray *)CFNetworkCopyProxiesForURL((__bridge CFURLRef)[NSURL URLWithString:@"http://www.google.com"], (__bridge CFDictionaryRef)proxySettings)));
NSDictionary*settings = [proxiesobjectAtIndex: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;
}
}