移动应用
134
反调试的方法很多,不过由于android系统是开源的,所以反调试其实也不是很神秘的东西。 下面是常见的也是很多厂商都在使用,包括我们项目组也在使用的。多个方案相互结合可以实现更好反调试。
1.1 ptrace自己,使得android_server附加不上
void anti_ptrace() { ptrace(PTRACE_TRACEME, 0, 0, 0); }
1.2. 检测Tracepid的值
void anti_Tracepid() { try { const int bufsize = 1024; char filename[bufsize]; char line[bufsize]; int pid = getpid(); sprintf(filename, “/proc/%d/status”, pid); FILE* fd = fopen(filename, “r”); if (fd !=NULL) { while (fgets(line, bufsize, fd)) { if (strncmp(line, “TracerPid”, 9) == 0) { int statue = atoi(&line[10]); if (statue != 0) { fclose(fd); int ret = kill(pid, SIGKILL); } break; } } fclose(fd); } else { // LOGD(“open %s fail…”, filename); } } catch (…) { } }
1.3 检测端口号,针对android_server这个端口号
void anti_serverport() { const int bufsize=512; char filename[bufsize]; char line[bufsize]; int pid =getpid(); sprintf(filename,"/proc/net/tcp"); FILE* fd=fopen(filename,“r”); if(fd!=NULL){ while(fgets(line,bufsize,fd)){ if (strncmp(line, “5D8A”, 4)==0){ int ret = kill(pid, SIGKILL); } } } fclose(fd); }
1.4 检测这些调试进程的名字
void anti_processstatus(){ const int bufsize = 1024; char filename[bufsize]; char line[bufsize]; char name[bufsize]; char nameline[bufsize]; int pid = getpid(); //先读取Tracepid的值 sprintf(filename, “/proc/%d/status”, pid); FILE *fd=fopen(filename,“r”); if(fd!=NULL){ while(fgets(line,bufsize,fd)){ if(strstr(line,“TracerPid”)!=NULL) { int statue =atoi(&line[10]); if(statue!=0){ sprintf(name,"/proc/%d/cmdline",statue); FILE *fdname=fopen(name,“r”); if(fdname!= NULL){ while(fgets(nameline,bufsize,fdname)){ if(strstr(nameline,“android_server”)!=NULL){ int ret=kill(pid,SIGKILL); } } } fclose(fdname); } } } } fclose(fd); }
1.5. 检测常放目录:/data/local/tmp
void anti_localtmp(){ int pid=getpid(); const int bufsize=1024; char line[bufsize]; char filename[bufsize]; sprintf(filename,"/data/local/tmp"); FILE *fd=fopen(filename,“r”); if(fd!=NULL){ while(fgets(line,bufsize,fd)){ if(strstr(line,“android_server”)!=NULL){ int ret=kill(pid,SIGKILL); } } } fclose(fd); }
1.6 检测break point指令
unsigned long GetLibAddr() { unsigned long ret = 0; char name[] = “libptrace.so”; char buf[4096], *temp; int pid; FILE *fp; pid = getpid(); sprintf(buf, “/proc/%d/maps”, pid); fp = fopen(buf, “r”); if (fp == NULL) { puts(“open failed”); goto _error; } while (fgets(buf, sizeof(buf), fp)) { if (strstr(buf, name)) { temp = strtok(buf, “-”); ret = strtoul(temp, NULL, 16); break; } } _error: fclose(fp); return ret; }
1.7 通过使用Linux inotify特性来对文件的读写,以及打开等权限进行监控
void anti_debug06() { int ret, len, i; int pid6 = getpid(); const int MAXLEN = 2048; char buf[1024]; char readbuf[MAXLEN]; int fd, wd; fd_set readfds; fd = inotify_init(); sprintf(buf, “/proc/%d/maps”, pid6); wd = inotify_add_watch(fd, buf, IN_ALL_EVENTS); if(wd>=0){ while (1) { i = 0; FD_ZERO(&readfds);//使得readfds清零 FD_SET(fd, &readfds);//将fd加入readfds集合 ret = select(fd + 1, &readfds, 0, 0, 0); if(ret==-1){ break; } if (ret) { len = read(fd, readbuf, MAXLEN); while (i < len) { struct inotify_event *event = (struct inotify_event *) &readbuf[i]; if ((event->mask & IN_ACCESS) || (event->mask & IN_OPEN)) { int ret = kill(pid6, SIGKILL); return; } i += sizeof(struct inotify_event) + event->len; } } } } inotify_rm_watch(fd, wd); close(fd); }
1.8.检测被调试代码的前后时间的差异;
int gettimeofday(struct timeval *tv,struct timezone *tz); void anti_debug07(){ int pid=getpid(); struct timeval t1; struct timeval t2; struct timezone tz; gettimeofday(&t1,&tz); gettimeofday(&t2,&tz); // int timeoff=gettimeofday(&t1,0)-gettimeofday(&t2,0); int timeoff=(t2.tv_sec)-(t1.tv_sec); if(timeoff>1){ int ret=kill(pid,SIGKILL); return ; } }
更多安全技术文章,请关注 “小道安全”公众号,一起交流,一起进步。