zoukankan      html  css  js  c++  java
  • 每天学点GDB14

    在上一篇文章中讲到了ptrace,那么我们完全可以用ptrace来写一个非常简单的trace工具,用以trace程序的具体运行过程。

    用它可以很清楚的回答,使用glibc编译后的hello world是从什么地方开始运行的。

    (注:本文内容根据“A really simple tracing debugger"翻译而来,具体链接见参考资料一节)

    itrace.c

    #include <stdio.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    #include <sys/user.h>
    #include <sys/ptrace.h>
    
    int main(int argc, char **argv)
    {
      int pid = fork();
      if(pid == 0) {
        if(ptrace(PTRACE_TRACEME) < 0) {
          perror("ptrace");
          _exit(1);
        }
        execvp(argv[1], argv + 1);
        perror("exec");
        _exit(1);
      }
      while(1) {
        int status;
        struct user_regs_struct regs;
        if(waitpid(pid, &status, 0) < 0)
          perror("waitpid");
        if(!WIFSTOPPED(status))
          break;
        if(ptrace(PTRACE_GETREGS, pid, 0, &regs) < 0)
          perror("ptrace/GETREGS");
        printf("%lx %lx
    ", regs.eip, regs.esp);
        if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)
          perror("ptrace/SINGLESTEP");
      }
      return 0;
    }

    编译

    gcc -m32 itrace.c -o itrace

    译者注: -m32表示编译成32位格式,如果是在64位机器上,不需要加此选项,同时将itrace.c源码中的eip和esp转换为rip,rsp.

    hellow.c

    #include <stdio.h>
    int main() { 
      printf("Hello, world!
    ");
      return 0;
    }

    编译

    gcc -static -o hellow hellow.c

    译者注: itrace保持一致,itrace如果是按32位格式来编译的,此处也应该一样。

    测试运行

    ./itrace ./hellow | addr2line -e ./hellow -f | grep -v "??|:?" | uniq

    说明如下

    addr2line 是将地址转换为相应的源码

    运行的结果很长,所以就不打算没有贴出来了。

    treeify

    为了让运行结果在显示的时候能够更好的反映出调用关系,根据堆栈(%esp)中的信息采用python脚本将其层次化的打印出来。

    import subprocess
    import sys
    
    def read():
        for line in sys.stdin:
            try:
                regs = [int(x, 16) for x in line.split(" ")]
                yield {"eip": regs[0], "esp": regs[1]}
            # Ignore lines interspersed with other output!
            except (ValueError, IndexError):
                pass
    
    def addr2line(iterable):
        proc = subprocess.Popen(["addr2line", "-e", sys.argv[1], "-f"],
                                stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        for regs in iterable:
            proc.stdin.write("%x
    " % regs["eip"])
            a = proc.stdout.readline().rstrip("
    ")
            b = proc.stdout.readline().rstrip("
    ")
            regs["func"] = "%s %s" % (a, b)
            yield regs
    
    def entry_points(iterable):
        funcs = {}
        # We treat the first address we see for the function as its entry
        # point, and only report those entries from this point on.
        for regs in iterable:
            func = regs["func"].split(":")[0]
            if funcs.setdefault(func, regs["eip"]) == regs["eip"]:
                yield regs
    
    def add_nesting(iterable):
        stack = [2 ** 64]
        for regs in iterable:
            stack_pos = regs["esp"]
            if stack_pos < stack[-1]:
                stack.append(stack_pos)
            while stack_pos > stack[-1]:
                stack.pop()
            regs["indent"] = "  " * len(stack)
            yield regs
    
    for x in add_nesting(entry_points(addr2line(read()))):
        print x["indent"], x["func"], "%x" % x["eip"]

    运行

    ./itrace ./hellow|python2 ./treeify.py ./hellow

    测试结果

         _start /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/start.S:61 8048d40
           __libc_start_main ??:? 8048ea0
             _dl_aux_init ??:? 806e590
             _dl_discover_osversion ??:? 806f3b0
               uname ??:? 80921c0
                 ?? ??:0 b77e0414
             index ??:? 805b250
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
               __init_cpu_features ??:? 806f570
             strncasecmp_l ??:? 80b5ac0
             strcmp ??:? 805b460
             memset ??:? 805ba70
             strcasecmp_l ??:? 805bc10
             bcmp ??:? 805b6b0
             strstr ??:? 806b080
             memchr ??:? 808ce90
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
             strrchr ??:? 808c660
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
             wcslen ??:? 808eae0
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
             __rawmemchr ??:? 805bcc0
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
             memmove ??:? 805b9d0
             __strnlen ??:? 808c620
               __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
             strcpy ??:? 805b4d0
             stpcpy ??:? 805bb30
             __pthread_initialize_minimal ??:? 80494d0
               __libc_setup_tls ??:? 8049240
                 sbrk ??:? 806cd70
                   __brk ??:? 80928e0
                     ?? ??:0 b77e0414
                   __brk ??:? 80928e0
                     ?? ??:0 b77e0414
                 memcpy ??:? 805bc50
             __libc_init_first ??:? 806f4b0
               __setfpucw ??:? 807ac00
               __libc_init_secure ??:? 806f360
               _dl_non_dynamic_init ??:? 806e7f0
                 _dl_get_origin ??:? 809a800
                   ?? ??:0 b77e0414
                   malloc ??:? 8058f60
                     malloc_hook_ini malloc.o:? 805a020
                       ptmalloc_init.part.7 malloc.o:? 8059c20
                         __linkin_atfork ??:? 806e0f0
                     malloc ??:? 8058f60
                       _int_malloc malloc.o:? 8057060
                         malloc_consolidate malloc.o:? 80560b0
                         malloc_init_state malloc.o:? 80552e0
                         __default_morecore ??:? 805b230
                           sbrk ??:? 806cd70
                             __brk ??:? 80928e0
                               ?? ??:0 b77e0414
                         __default_morecore ??:? 805b230
                           sbrk ??:? 806cd70
                             __brk ??:? 80928e0
                               ?? ??:0 b77e0414
                   mempcpy ??:? 805bb00
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 _dl_new_object ??:? 80972a0
                   strlen ??:? 805b5f0
                   __calloc ??:? 8059720
                     _int_malloc malloc.o:? 8057060
                     __memset_sse2_rep ??:? 805f690
                   memcpy ??:? 805bc50
                 _dl_setup_hash ??:? 8097150
                 strlen ??:? 805b5f0
                 malloc ??:? 8058f60
                   _int_malloc malloc.o:? 8057060
                 memcpy ??:? 805bc50
                 _dl_add_to_namespace_list ??:? 8097200
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 _dl_init_paths ??:? 80951f0
                   _dl_important_hwcaps ??:? 80991b0
                     malloc ??:? 8058f60
                       _int_malloc malloc.o:? 8057060
                     mempcpy ??:? 805bb00
                   malloc ??:? 8058f60
                     _int_malloc malloc.o:? 8057060
                   malloc ??:? 8058f60
                     _int_malloc malloc.o:? 8057060
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
                 getenv ??:? 804e240
                   strlen ??:? 805b5f0
               __init_misc ??:? 806dd90
                 __strrchr_sse2_bsf ??:? 808d830
             __ctype_init ??:? 807abb0
             __cxa_atexit ??:? 804e5d0
               __new_exitfn ??:? 804e440
             __libc_csu_init ??:? 80494f0
               _init /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:63 8048190
                 __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
               _init /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crtn.S:40 80481ae
               frame_dummy crtstuff.c:? 8048e20
                 __register_frame_info_bases ??:? 80bd5a0
                   __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
               register_tm_clones crtstuff.c:? 8048db0
               init_cacheinfo cacheinfo.o:? 8048b10
                 handle_intel cacheinfo.o:? 806b380
                   intel_check_word cacheinfo.o:? 806b0b0
                   intel_check_word cacheinfo.o:? 806b0b0
                   intel_check_word cacheinfo.o:? 806b0b0
                   intel_check_word cacheinfo.o:? 806b0b0
                 handle_intel cacheinfo.o:? 806b380
                   intel_check_word cacheinfo.o:? 806b0b0
                   intel_check_word cacheinfo.o:? 806b0b0
             _setjmp ??:? 804d970
             main ??:? 8048e7c
               puts ??:? 804f350
                 strlen ??:? 805b5f0
                 _IO_new_file_xsputn ??:? 8052470
                   _IO_file_overflow ??:? 8052e60
                     _IO_doallocbuf ??:? 8053b10
                       _IO_file_doallocate ??:? 808a730
                         _IO_file_stat ??:? 8051f20
                           ___fxstat64 ??:? 806c300
                             ?? ??:0 b77e0414
                         __mmap ??:? 806ce60
                           ?? ??:0 b77e0414
                         _IO_setb ??:? 8053aa0
                     _IO_new_do_write ??:? 80527b0
                   _IO_default_xsputn ??:? 8053bc0
             exit ??:? 804e420
               __run_exit_handlers ??:? 804e320
                 __libc_csu_fini ??:? 8049590
                   fini sdlerror.o:? 8048b00
                   check_free.isra.0 sdlerror.o:? 80a6f30
                   __do_global_dtors_aux crtstuff.c:? 8048df0
                     deregister_tm_clones crtstuff.c:? 8048d80
                     __deregister_frame_info_bases ??:? 80bd7c0
                       __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
                 _fini /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:82 80bec78
                   __x86.get_pc_thunk.bx /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crti.S:66 8048d70
                 _fini /root/glibc/src/glibc-2.18/csu/../sysdeps/i386/crtn.S:45 80bec87
                 _IO_cleanup ??:? 80543b0
                   _IO_flush_all_lockp ??:? 8054190
                     _IO_file_overflow ??:? 8052e60
                       _IO_new_do_write ??:? 80527b0
                         new_do_write fileops.o:? 8051100
                           _IO_file_write ??:? 8051f50
                             __write ??:? 806c420
                               ?? ??:0 b77e0414
                   _IO_file_setbuf ??:? 8051060
                     _IO_default_setbuf ??:? 8053d10
                       _IO_file_sync ??:? 8053060
                       _IO_setb ??:? 8053aa0
                 _Exit ??:? 806ba24
                   ?? ??:0 b77e0414

    参考资料

    1. http://lackingrhoticity.blogspot.ca/2009/05/really-simple-tracing-debugger.html
  • 相关阅读:
    单片机触摸屏校准
    C中的预编译宏定义
    Android之网络摄像头
    曾经的UCOSii
    关于ST-Link下载STM32程序的使用
    关于IAR开发STM32配置
    学习C#(一)
    ESP8266使用详解--基于Lua脚本语言
    (五)Lua脚本语言入门
    (四)Lua脚本语言入门(数组遍历)
  • 原文地址:https://www.cnblogs.com/hseagle/p/3304826.html
Copyright © 2011-2022 走看看