zoukankan      html  css  js  c++  java
  • 通过inotify实现反调试

    1.inotify

    linux下inotify可以实现监控文件系统事件(打开,读写删除等),inotify最常见的api有以下几个:

    • inotify_init:用于创建一个 inotify 实例的系统调用,并返回一个指向该实例的文件描述符。
    • inotify_add_watch:增加对文件或者目录的监控,并指定需要监控哪些事件。
    • read:读取包含一个或者多个事件信息的缓存。
    • inotify_rm_watch:从监控列表中移出监控项目。

    inotify_add_watch原型如下:

     int inotify_add_watch(int fd, const char* pathname, int mask)
    • 第一个参数fd是inotify_init的返回值。
    • 第二个参数是要监控的文件目录。
    • 第三个参数表示要监控哪些事件。

    inotify的mask类型具体定义见:linux-3.18.6/include/uapi/linux/inotify.h#29

    从read函数读出的内容是多个 inotify_event 结构体,该结构体定义如下:

    每个触发的事件都对应了一个inotify_event结构体,只要判断这个结构体中的mask是否为指定的事件(open,read等)即可判断这个发生的事件是否对我们有用。

    2.select函数

    select系统调用是用来让我们的程序监视多个文件句柄的状态变化,select函数原型及参数说明如下:

    • 参数maxfd是需要监视的最大的文件描述符值+1;
    • rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。
    • struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。

    3.通过inotify实现反调试

    通过inotify监控/proc/pid文件夹下的关键文件变化(maps的读,mem的读等),若想查看某进程的的虚拟地址空间或者想dump内存,则会触发打开或读取的事件,只要接收到这些事件,则说明进程正在被调试,直接kill主进程。主要代码如下:

    //fork子进程调用该函数,并且传入父进程pid
    voidAntiDebug(intppid){
     
    charbuf[1024],readbuf[MAXLEN];
    intpid,wd,ret,len,i;
    intfd;
    fd_set readfds;
    //防止调试子进程
    ptrace(PTRACE_TRACEME,0,0,0);
    fd=  inotify_init();
    sprintf(buf,"/proc/%d/maps",ppid);
     
    //wd = inotify_add_watch(fd, "/proc/self/mem", IN_ALL_EVENTS);
    wd=inotify_add_watch(fd,buf,IN_ALL_EVENTS);
    if(wd<0){
    LOGD("can't watch %s",buf);
    return;
    }
    while(1){
    i=0;
                    //注意要对fd_set进行初始化
    FD_ZERO(&readfds);
    FD_SET(fd,&readfds);
                    //第一个参数固定要+1,第二个参数是读的fdset,第三个是写的fdset,最后一个是等待的时间
                    //最后一个为NULL则为阻塞
    ret=select(fd+1,&readfds,0,0,0);
    if(ret==-1)
    break;
    if(ret){
    len=read(fd,readbuf,MAXLEN);
    while(i<len){
                                    //返回的buf中可能存了多个inotify_event
    structinotify_event *event=(structinotify_event*)&readbuf[i];
    LOGD("event mask %d ",(event->mask&IN_ACCESS)||(event->mask&IN_OPEN));
                                    //这里监控读和打开事件
    if((event->mask&IN_ACCESS)||(event->mask&IN_OPEN)){
    LOGD("kill!!!!! ");
                                                    //事件出现则杀死父进程
    intret=kill(ppid,SIGKILL);
    LOGD("ret = %d",ret);
    return;
    }
    i+=sizeof(structinotify_event)+event->len;
    }
    }
    }
    inotify_rm_watch(fd,wd);
    close(fd);
    }
  • 相关阅读:
    战略就是做出各种选择和不断权衡取舍;战略就是要刻意与众不同
    获取基目录,它由程序集冲突解决程序用来探测程序集
    Entity Framework的原理及使用方式
    NHibernate使用之详细图解
    最重要的不是你认识多少个人,而是你认识多少种人
    强关系利于执行,弱关系利于创新
    判断它是不是你的社群成员,你要看它对你的态度
    粉丝不在于多,在于够残
    没有请不起的人才,只有付不起的诚意
    所有有可能被互联网取代的组织一定会被取代--颠覆式创新研习社
  • 原文地址:https://www.cnblogs.com/qintangtao/p/7765638.html
Copyright © 2011-2022 走看看