【问题标题】:How to undo strip - i.e. add symbols back to stripped binary如何撤消剥离 - 即将符号添加回剥离的二进制文件
【发布时间】:2013-04-05 08:53:29
【问题描述】:

我有一个剥离的二进制文件和符号文件。是否可以将符号添加回二进制文件并创建一个未剥离的二进制文件。

我的用例是使用这个带有 valgrind 的二进制文件。

【问题讨论】:

  • 我想说重新编译,想不出别的了:)

标签: linux gdb valgrind strip


【解决方案1】:

对于那些不支持单独的调试信息文件的工具,您可以将调试部分粘贴回原始二进制文件

你可以按照这些思路做一些事情,例如:

  • 首先构建一个小程序,可以有效地从文件中提取任意块

    (请注意dd 不会有效地执行此操作,因为我们必须使用bs=1 来支持任意偏移量长度,而objcopy -O binary 不会复制部分不是ALLOC, LOAD)

    cat <<EOF | gcc -xc -o ./mydd -
    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <macros.h>
    
    char buf[1024*1024];
    
    int main(int argc, char** argv) {
      char    *fin, *fout;
      int     fdin, fdout;
      off_t   off;
      size_t  len;
      ssize_t rd;
      int     status;
    
      if (argc != 5) {
        fprintf(stderr, "Usage: %s fin skip count fout\n", argv[0]);
        return 1;
      }
    
      fin   = argv[1];
      off   = strtoul(argv[2], NULL, 0);
      len   = strtoul(argv[3], NULL, 0);
      fout  = argv[4];
      fdin  = -1;
      fdout = -1;
    
      if ((fdin  = open(fin,  O_RDONLY)) < 0) {
        status = errno;
        perror(fin);
      } else if ((fdout = open(fout, O_WRONLY|O_TRUNC|O_CREAT, 0660)) < 0) {
        status = errno;
        perror(fout);
      } else if (lseek(fdin, off, SEEK_SET) == (off_t)-1) {
        status = errno;
        perror("Seeking input");
      } else {
        while (len > 0 && (rd = read(fdin, buf, min(len, sizeof(buf)))) > 0) {
          if (write(fdout, buf, rd) != rd) {
            /*don't bother with partial writes or EINTR/EAGAIN*/
            status = errno;
            perror(fin);
            break;
          }
          len -= rd;
        }
        if (rd < 0) {
          status = errno;
          perror(fin);
        }
      }
      if (fdin >= 0)  close(fdin);
      if (fdout >= 0) close(fdout);
      return status;
    }
    EOF
    
  • 最后,提取.debug 部分并将它们粘贴到剥离的二进制文件中。

    objcopy `
        objdump -h program.dbg  |
        awk '$2~/^\.debug/' |
        while read idx name size vma lma off algn ; do
            echo "$name" >&2
            echo " --add-section=$name=$name.raw"
            ./mydd program.dbg 0x$off 0x$size $name".raw"
        done
    ` program program_with_dbg
    

【讨论】:

  • dd 可以在不将块大小缩小为 1 的情况下查找任意地址。请参阅 dd 手册中的标志“skip_bytes”。
  • 请注意,这不会复制与节关联的重定位
【解决方案2】:

Valgrind 支持separate debug files,因此您应该使用answer here,并且valgrind 应该可以与外部化调试文件一起正常工作。

【讨论】:

  • 不:你不能从一个剥离的二进制文件中创建一个未剥离的二进制文件(至少不容易)。但你不应该这样做,因为这个答案正确地指出。
  • 我很抱歉,但不清楚如何使用这个带有 valgrind 的调试文件。不胜感激。
  • “此处的答案”中提供的说明似乎很清楚。您构建单独的调试信息,然后 Valgrind 和 GDB 将自动加载它们。
  • 谢谢 - 会试一试的。
【解决方案3】:

elfutils 附带工具eu-unstrip,可用于将符号文件与可执行文件合并。然后可以使用结果代替剥离的版本。

【讨论】:

    猜你喜欢
    • 2016-03-21
    • 2012-10-22
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多