zoukankan      html  css  js  c++  java
  • Linux下的反调试技术

    Linux下的反调试技术

    2014年01月30日 ⁄ 综合 ⁄ 共 2669字 ⁄ 字号    ⁄ 评论关闭

    转自  http://wangcong.org/blog/archives/310

    如何防止自己的程序被调试器跟踪,这是一个很有趣的话题,也是反逆向工程中的一个重要话题。这里简单介绍一下Linux平台上的反调试技术。

    (本文主要参考:http://blog.txipinet.com/2006/10/05/37-tecnicas-anti-debugging-sencillas-para-gnu-linux/
    做人要厚道,转载请指明出处!

    一. int3指令

    Intel Software Developer’s Manual Volume 2A中提到:

    The INT 3 instruction generates a special one byte opcode (CC) that is intended for
    calling the debug exception handler. (This one byte form is valuable because it can be
    used to replace the first byte of any instruction with a breakpoint, including other one
    byte instructions, without over-writing other code).

    int3是一个特殊的中断指令(从名字上也看得出来),专门用来给调试器使用。这时,我们应该很容易想到,要反调试,只要插入int3来迷惑调试器即可。不过,这会不会影响正常的程序?会!因为int3会在用户空间产生SIGTRAP。没关系,我们只要忽略这个信号就可以了。

    #include 
    #include 
    void handler(int signo)
    {}
     
    int main(void)
    {
        signal(SIGTRAP, handler);
        __asm__("nop
    	"
            "int3
    	");
        printf("Hello from main!
    ");
        return 0;
    }
    

    二. 文件描述符

    这是一个很巧妙的办法,不过它只对gdb之类的调试器有效。方法如下:

    #include 
    #include 
    #include  
    int main(void)
    {
        if(close(3) == -1) {
            printf("OK
    ");
        } else {
            printf("traced!
    ");
            exit(-1);
        }
        return 0;
    }
    

    gdb要调试这个程序时会打开一个额外的文件描述符来读这个可执行文件,而这个程序正是利用了这个“弱点”。当然,你应该能猜到,这个技巧对strace是无效的。

    三. 利用getppid

    和上面一个手法类似,不过这个更高明,它利用getppid来进行探测。我们知道,在Linux上要跟踪一个程序,必须是它的父进程才能做到,因此,如果一个程序的父进程不是意料之中的bash等(而是gdb,strace之类的),那就说明它被跟踪了。程序代码如下:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include  
    
    int get_name_by_pid(pid_t pid, char* name)
    {
        int fd;
        char buf[1024] = {0};
        snprintf(buf, 1024, "/proc/%d/cmdline", pid);
        if ((fd = open(buf, O_RDONLY)) == -1)
            return -1;
        read(fd, buf, 1024);
        strncpy(name, buf, 1023);
        return 0;
    }
     
    int main(void)
    {
        char name[1024];
        pid_t ppid = getppid();
        printf("getppid: %d
    ", ppid);
     
            if (get_name_by_pid(ppid, name))
            return -1;
        if (strcmp(name, "bash") == 0 ||
            strcmp(name, "init") == 0)
                printf("OK!
    ");
        else if (strcmp(name, "gdb") == 0 ||
            strcmp(name, "strace") == 0 ||
            strcmp(name, "ltrace") == 0)
            printf("Traced!
    ");
        else
            printf("Unknown! Maybe traced!
    ");
     
        return 0;
    }
    

    同样的手法,一个更简单的方式是利用session id。我们知道,不论被跟踪与否,session id是不变的,而ppid会变!下面的程序就利用了这一点。

    #include 
    #include 
    #include  
    
    int main(void)
    {
        printf("getsid: %d
    ", getsid(getpid()));
        printf("getppid: %d
    ", getppid());
     
            if (getsid(getpid()) != getppid()) {
            printf("traced!
    ");
            exit(EXIT_FAILURE);
        }
            printf("OK
    ");
     
        return 0;
    }
    

    四. 利用环境变量

    bash有一个环境变量叫$_,它保存的是上一个执行的命令的最后一个参数。如果在被跟踪的状态下,这个变量的值是会发生变化的(为什么?)。下面列出了几种情况:

                    argv[0]                    getenv("_")
    shell           ./test                     ./test
    strace          ./test                     /usr/bin/strace
    ltrace          ./test                     /usr/bin/ltrace
    gdb              /home/user/test           (NULL)
    

    所以我们也可以据此来判断。

    #include 
    #include 
    #include  
    
    int main( int argc, char *argv[])
    {
        printf("getenv(_): %s
    ", getenv("_"));
        printf("argv[0]: %s
    ", argv[0]);
     
        if(strcmp(argv[0], (char *)getenv("_"))) {
            printf("traced!
    ");
            exit(-1);
        }
     
        printf("OK
    ");
            return 0;
    }
    

    五. 利用ptrace

    很简单,如果被跟踪了还再调用ptrace(PTRACE_TRACEME…)自然会不成功。

    #include 
    #include 
    #include  
    
    int main(void)
    {
         if ( ptrace(PTRACE_TRACEME, 0, 1, 0) < 0 ) {
            printf("traced!
    ");
            return 1;
        }
        printf("OK
    ");
        return 0;
    }
    
  • 相关阅读:
    poj 2479
    纯CSS实现小圆点和三角形图案
    HDOJ1084 What Is Your Grade?
    4星|《一世富贵》:穿越到宋朝去抢了狄青、范仲淹的风头
    世界不是平的,发达国家在本地生产越来越合算。观点宏大,证据薄弱:3星|《后全球化时代》
    饥饿疗法是目前唯一确信能够延缓衰老的办法:4星|《三联生活周刊》2018年3期
    4星|《重塑》:消费者的信息能力是一个重要的经济变量。新颖的、有见地的国人原创经济理论
    3星|《高情商谈判》:谈判中控制情绪非常重要
    中间商赚差价让世界更美好:3.5星|《中间人经济》
    3.5星|《新零售的未来》:中美两国零售业的现状的分析和未来的展望
  • 原文地址:https://www.cnblogs.com/SZLLQ2000/p/5093054.html
Copyright © 2011-2022 走看看