經過inotify實現反調試

1.inotify

linux下inotify能夠實現監控文件系統事件(打開,讀寫刪除等),inotify最多見的api有如下幾個:linux

  • inotify_init:用於建立一個 inotify 實例的系統調用,並返回一個指向該實例的文件描述符。
  • inotify_add_watch:增長對文件或者目錄的監控,並指定須要監控哪些事件。
  • read:讀取包含一個或者多個事件信息的緩存。
  • inotify_rm_watch:從監控列表中移出監控項目。

inotify_add_watch原型以下:api

 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 結構體,該結構體定義以下:cookie

每一個觸發的事件都對應了一個inotify_event結構體,只要判斷這個結構體中的mask是否爲指定的事件(open,read等)便可判斷這個發生的事件是否對咱們有用。函數

2.select函數

select系統調用是用來讓咱們的程序監視多個文件句柄的狀態變化,select函數原型及參數說明以下:ui

  • 參數maxfd是須要監視的最大的文件描述符值+1;
  • rdset,wrset,exset分別對應於須要檢測的可讀文件描述符的集合,可寫文件描述符的集合及異常文件描述符的集合。
  • struct timeval結構用於描述一段時間長度,若是在這個時間內,須要監視的描述符沒有事件發生則函數返回,返回值爲0。

3.經過inotify實現反調試

經過inotify監控/proc/pid文件夾下的關鍵文件變化(maps的讀,mem的讀等),若想查看某進程的的虛擬地址空間或者想dump內存,則會觸發打開或讀取的事件,只要接收到這些事件,則說明進程正在被調試,直接kill主進程。主要代碼以下:spa

//fork子進程調用該函數,而且傳入父進程pid
void AntiDebug ( int ppid ) {
 
char buf [ 1024 ] , readbuf [ MAXLEN ] ;
int pid , wd , ret , len , i ;
int fd ;
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
struct inotify_event * event = ( struct inotify_event* ) & readbuf [ i ] ;
LOGD ( "event mask %d\n" , ( event -> mask & IN_ACCESS ) || ( event -> mask & IN_OPEN ) ) ;
                                 //這裏監控讀和打開事件
if ( ( event -> mask & IN_ACCESS ) || ( event -> mask & IN_OPEN ) ) {
LOGD ( "kill!!!!!\n" ) ;
                                                 //事件出現則殺死父進程
int ret = kill ( ppid , SIGKILL ) ;
LOGD ( "ret = %d" , ret ) ;
return ;
}
i += sizeof ( struct inotify_event ) + event -> len ;
}
}
}
inotify_rm_watch ( fd , wd ) ;
close ( fd ) ;
}
相關文章
相關標籤/搜索