一、sysctrl反调试
#import "ViewController.h"
#import <sys/sysctl.h>
@interface ViewController ()
@end
@implementation ViewController
BOOL isDebugger(){
int name[4];//里面放字节码。查询的信息
name[0] = CTL_KERN;//内核查询
name[1] = KERN_PROC;//查询进程
name[2] = KERN_PROC_PID;//传递的参数是进程的ID
name[3] = getpid();//PID的值
struct kinfo_proc info;//接受查询结果的结构体
size_t info_size = sizeof(info);
if(sysctl(name, 4, &info, &info_size, 0, 0)){
NSLog(@"查询失败");
return NO;
}
//看info.kp_proc.p_flag 的第12位。如果为1,表示调试状态。
//(info.kp_proc.p_flag & P_TRACED)
return ((info.kp_proc.p_flag & P_TRACED) != 0);
}
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.0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
if (isDebugger()) {
NSLog(@"调试状态!!");
}else{
NSLog(@"正常!");
}
});
dispatch_resume(timer);
}
- (void)viewDidLoad {
[super viewDidLoad];
debugCheck();
}
#import "InjectCode.h"
#import "fishhook.h"
#import <sys/sysctl.h>
@implementation InjectCode
//原始函数指针
int (*sysctl_p)(int *, u_int, void *, size_t *, void *, size_t);
//新函数地址
int my_sysctl(int *name, u_int namelen, void *info, size_t *infosize, void *newInfo, size_t newInfoSize){
if (namelen == 4
&& name[0] == CTL_KERN
&& name[1] == KERN_PROC
&& name[2] == KERN_PROC_PID
&& info
&& (int)*infosize == sizeof(struct kinfo_proc)) {
int err = sysctl_p(name,namelen,info,infosize,newInfo,newInfoSize);
struct kinfo_proc * myinfo = (struct kinfo_proc *)info;
if ((myinfo->kp_proc.p_flag & P_TRACED) != 0) {
//使用异或可以取反
myinfo->kp_proc.p_flag ^= P_TRACED;
}
return err;
}
return sysctl_p(name,namelen,info,infosize,newInfo,newInfoSize);
}
+(void)load
{
//交换
rebind_symbols((struct rebinding[1]){{"sysctl",my_sysctl,(void *)&sysctl_p}}, 1);
}
@end
网友评论