第一:反调试,修改main.m
#import <dlfcn.h>
#import <sys/types.h>
//定义一个函数指针用来接收动态加载出来的函数ptrace
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif
// 阻止调试器attach
void disable_gdb() {
//第一个参数path为0时, 它会自动查找 $LD_LIBRARY_PATH,$DYLD_LIBRARY_PATH, $DYLD_FALLBACK_LIBRARY_PATH 和 当前工作目录中的动态链接库.
void * handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
//动态加载ptrace函数,ptrace函数的参数个数和类型,及返回类型跟ptrace_ptr_t函数指针定义的是一样的
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
//执行ptrace_ptr相当于执行ptrace函数
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
//关闭动态库,并且卸载
dlclose(handle);
}
int main(int argc, char * argv[]) {
@autoreleasepool {
#ifndef DEBUG
disable_gdb();
#endif
signal(SIGPIPE, SIG_IGN);
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
第二:反注入,定时查看(不能在开始只检查一次)。原理为lib库白名单检查
//代码防注入
bool HKCheckWhitelist(){
int count = _dyld_image_count();
NSArray * arr = @[@"libstdc++.tbd",...,@"libViewDebuggerSupport.dylib"];
for (int i = 0; i < count; i++) {
//遍历拿到库名称!
const char * imageName = _dyld_get_image_name(i);
//只判断自己app内的库
if (!strstr(imageName, "/var/mobile/Containers/Bundle/Application") ) {
continue;
}
//系统的lib Debug库 除外
if (strstr(imageName, "/System/Library/Frameworks/") || strstr(imageName, "/Developer/") ) {
continue;
}
if (strstr(imageName, "libAppProxy") || strstr(imageName, "PacketTunnel")) {
continue;
}
NSString *str= [NSString stringWithCString:imageName encoding:[NSString defaultCStringEncoding]];
str = [str lastPathComponent];
//应用本身除外
if ([str isEqualToString:@"workspace"] ) {
continue;
}
BOOL isMyLib = NO;
for (NSString * libName in arr) {
if ([libName containsString:str]) {
isMyLib = YES;
}
}
if (isMyLib == NO) {
printf("lib已被修改==!!%s",imageName);
TLogD(@"lib已被修改==!!%s",imageName);
exit(0);
return NO;
}else{
return YES;
}
}
return YES;
}
第三:防止重签打包的简单验证,原理为读出打包的证书ID,然后和预埋的比较
+ (void)prepareEnv {
NSString *embeddedPath = [[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
if ([[NSFileManager defaultManager] fileExistsAtPath:embeddedPath]) {
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 objectAtIndex:i] rangeOfString:@"application-identifier"].location != NSNotFound) {
NSInteger fromPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"<string>"].location+8;
NSInteger toPosition = [[embeddedProvisioningLines objectAtIndex:i+1] rangeOfString:@"</string>"].location;
NSRange range;
range.location = fromPosition;
range.length = toPosition - fromPosition;
NSString *fullIdentifier = [[embeddedProvisioningLines objectAtIndex:i+1] substringWithRange:range];
NSArray *identifierComponents = [fullIdentifier componentsSeparatedByString:@"."];
NSString *appIdentifier = [identifierComponents firstObject];
// 对比签名ID
if ([appIdentifier caseInsensitiveCompare:@“*******”] != NSOrderedSame) {
exit(0);
}
break;
}
}
}
}
第四:日志敏感信息。原理,利用fishhook,hook系统方法“NSLog”,进行过滤处理
#import "UIApplication+NSLog.h"
#import "fishhook.h"
@implementation UIApplication (NSLog)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//定义rebinding结构体
/*
struct rebinding {
const char *name;//需要HOOK的函数名称,字符串
void *replacement;//替换到那个新的函数上(函数指针,也就是函数的名称)
void **replaced;//保存原始函数指针变量的指针(它是一个二级指针!)
};
*/
rebind_symbols((struct rebinding[1]){{"NSLog", new_NSLog, (void *)&orig_NSLog}}, 1);
});
}
// orig_NSLog是原有方法被替换后 把原来的实现方法放到另一个地址中
// new_NSLog就是替换后的方法了
static void (*orig_NSLog)(NSString *format, ...);
void(new_NSLog)(NSString *format, ...) {
va_list args;
if(format) {
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
DDLogInfo(@"Hook:%@", message); //使用DDLog保存日志到本地
#ifndef DEBUG
orig_NSLog(@"===%@", message);//debug状态下打印日志方便查看
#endif
va_end(args);
}
}
@end
网友评论