linuxバックデバッグ方法

4944 ワード

どのように自分のプログラムがデバッターによって追跡されるのを防ぐか、これは興味深い話題であり、逆プロジェクトの重要な話題でもある。ここではLinuxプラットフォームのアンチデバッグ技術を簡単に紹介します。
(本論文の主な参考:http://blog.txipinet.com/2006/10/05/37-tecnicas-anti-debugging-sencillas-para-gnu-linux/。身を処して温厚にして、転載して出所を明示して下さい!)
一.int 3指令
Intel Software Developer’s Manual Volume 2 Aに記載されています。
The INT 3 instruction generators a special one byte opcode(CC)that is inted for caling the debug exception handler.(This one byte form valuable because it to place the first byte byte of any streuction with blediton cleant。
int 3は特殊な割り込みコマンドです。この時、私達は簡単に思い付くべきで、逆に調整して、int 3を挿入して調合器を迷わせるだけでいいです。でも、これは正常なプログラムに影響しますか?はいint 3はユーザ空間でSIGRAPを生成するからである。大丈夫です。この信号を無視すればいいです。
ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菵include
  •  
  • void ハンドル
  • {}
  •  
  • int メーン
  • {
  • }
  •     signal(SIGraP、handler);
  •     __asm_(「nop\n\t」
  •         「int 3\n\t」);
  •     printf(「Hello from main!\n」);
  •     return 0;
  • 二.ファイル記述子
    これは巧妙な方法ですが、gdbなどの調合器にしか効きません。方法は以下の通りです
    ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菗include
  • 菵include
  •  
  • int メーン
  • {
  • }
  •     if(close(3)=-1) {
  • }
  •         printf(「OK\n」)
  •     } else{
  • }
  •         printf(「tracd!\n」)
  •         exit(-1);
  •     }
  •     return 0;
  • gdbはこのプログラムをデバッグする時に、この実行可能ファイルを読むために追加のファイル記述子を開きます。このプログラムはまさにこの「弱点」を利用しています。もちろん、このテクニックはstraceに対して無効であると推測できるはずです。
    三.getppidを利用する
    前の手法と似ていますが、これはもっと上手です。getppidを使って探査します。Linuxではプログラムを追跡するために、父のプロセスでなければできないことを知っています。そのため、もしプログラムの父プロセスが予想外のbashなどではないなら、追跡されたと説明します。プログラムコードは次の通りです。
    ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菗include
  • 〓〓include
  • 菵include
  • 菵include
  • 菵include
  • 菵include
  •  
  • int ガジェット
  • {
  • }
  •     要点 fd;
  •     char buf[1024]={0};
  •     snprintf(buf、1024、「/proc/%d/cmdline」、pid);
  •     if ((fd=open)==-1)
  •         return-1;
  •     read(fd、buf、1024)、
  •     strancpy(name,buf,1023);
  •     return 0;
  •  
  • int メーン
  • {
  • }
  •     char name[1024];
  •     pidut ppid=getppid();
  •     printf(「getppid:%d\n」、ppid);
  •  
  •         if (get-unameyup id)
  •         return-1;
  •     if (strcmp(name、bash)==0𞓜
  •         strcmp(name,「init」==0)
  •             printf(「OK!\n」);
  •     else if(strcmp(name,gdb)==0𞓜
  •         strcmp==0𞓜
  •         strcmp(name)==0)
  •         printf(「Traced!\n」);
  •     else
  •         printf(「Unknown!Maybe tracd!\n」);
  •  
  •     return 0;
  • 同様の手法で、より簡単な方法はsession idを利用することである。追跡されても、されても、session idは変わらず、ppidは変わる!以下のプログラムはこの点を利用していることを知っている。
    ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菗include
  • 菵include
  •  
  • int メーン
  • {
  • }
  •     printf(「getsid:%d\n」、getsid(getpid());
  •     printf(「getppid:%d\n」、getppid();
  •  
  •         if (getsid(getpid)!=getppid(){
  •         printf(「tracd!\n」)
  •         exit(EXIT)
  •     }
  •         printf(「OK\n」)
  •  
  •     return 0;
  • 四.環境変数を利用する
    bashには、前に実行したコマンドの最後のパラメータが保存されている環境変数があります。トレースされた状態では、この変数の値が変化します。(なぜですか?)次のような場合があります。
                    argv[0]                    getenv("_")
    shell           ./test                     ./test
    strace          ./test                     /usr/bin/strace
    ltrace          ./test                     /usr/bin/ltrace
    gdb              /home/user/test           (NULL)
    
    だから私たちもこのように判断します。
    ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菗include
  • 〓〓include
  •  
  • int main(int argc、char*argv[])
  • {
  • }
  •     printf(「getens」:%s\n、getensv(「u」);
  •     printf(「argv[0]:%s\n」、argv[0]);
  •  
  •     if(strcmp(argv[0],(char*)getensv(「u」)) {
  • }
  •         printf(「tracd!\n」)
  •         exit(-1);
  •     }
  •  
  •     printf(「OK\n」)
  •         return 0;
  • 五.ptraceを利用する
    簡単です。追跡されてからptrace(PTRACE UTRACEME)を呼び出すと、自然に成功しません。
    ヽoo。ツ。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 菵include
  •  
  • int メーン
  • {
  • }
  •      if (ptrace(PTRACE、0、1、0)<0){
  •         printf(「tracd!\n」)
  •         return 1;
  •     }
  •     printf(「OK\n」)
  •     return 0;
  • Happy hacking