《iOS防护03》sysctl防护
2020-10-30 本文已影响0人
不仅仅是个程序猿
可以使用系统函数 sysctl 来检测进程的状态。
int sysctl(int *, u_int, void *, size_t *, void *, size_t);
ViewController.m
#import "ViewController.h"
#import <sys/sysctl.h>
@interface ViewController ()
@end
@implementation ViewController
// int sysctl(int *, u_int, void *, size_t *, void *, size_t);
// #define P_TRACED 0x00000800 /* Debugged process being traced */
//判断是否是调试状态
BOOL isDebugger() {
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, 4, &info, &info_size, 0, 0);
if (error) {
NSLog(@"查询失败");
return NO;
}
/**
0000 0000 0000 0000 0100 1000 0000 0100//有调试(info.kp_proc.p_flag=18436)
&
0000 0000 0000 0000 0000 1000 0000 0000 (P_TRACED)
结果:
0000 0000 0000 0000 0000 1000 0000 0000 (不为0)
0000 0000 0000 0000 0100 0000 0000 0100//没有调试(info.kp_proc.p_flag=16388)
&
0000 0000 0000 0000 0000 1000 0000 0000 (P_TRACED)
结果:
0000 0000 0000 0000 0000 0000 0000 0000 (为0)
结果为0没有调试,结果不为0有调试
*/
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
//GCD定时器每隔1秒检查状态
static dispatch_source_t timer;
void debugCheck() {
timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0*NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
if (isDebugger()) {
NSLog(@"调试状态");
} else {
NSLog(@"正常");
}
});
dispatch_resume(timer);
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
debugCheck();
}
@end
用Xcode运行工程,控制台会打印出“调试状态”。
截屏2020-10-30下午1.24.04.png
手机断开Xcode后,运行程序后,可以通过Mac的控制台(console)查看打印。
截屏2020-10-30下午1.28.37.png