windows - 找出模式以便在编译的程序中找到变量

标签 windows dwarf readelf debug-information

我需要从已编译的 C 程序中提取全局变量。我现在正在做的是使用 Linux readelf 命令来获取该信息。换句话说,当我这样做时:

  readelf.exe -w[i]  myFile.out      

我使用 readelf.exe 来做到这一点可以从 here 下载的程序.因为我使用的是 Windows,这是我唯一需要的命令。在 Linux 上,我将只打开控制台并执行 readelf -w[i] myFile.out

无论如何,当我执行该命令时,我会得到如下信息:

 <1><86923>: Abbrev Number: 2 (DW_TAG_base_type)
    <86924>   DW_AT_name        : unsigned int  
    <86925>   DW_AT_encoding    : 7 (unsigned)
    <86927>   DW_AT_byte_size   : 4 
<1>..
...
... bla bla bla
... 
<1><870a1>: Abbrev Number: 12 (DW_TAG_variable)
    <870a2>   DW_AT_decl_file   : 25    
    <870a3>   DW_AT_decl_line   : 543   
    <870a5>   DW_AT_external    : 1 
    <870a6>   DW_AT_name        : NetBuf_ID_Ctr     // <------------------- First variable
    <870b4>   DW_AT_type        : <0x86923> 
    <870b8>   DW_AT_location    : 5 byte block: 3 ff f9 b 20    (DW_OP_addr: fff90b20)
 <1><870be>: Abbrev Number: 3 (DW_TAG_typedef)
    <870bf>   DW_AT_decl_file   : 26    
    <870c0>   DW_AT_decl_line   : 192   
    <870c2>   DW_AT_name        : NET_CONN_FAMILY   
    <870d2>   DW_AT_type        : <0x862f1> 
 <1><870d6>: Abbrev Number: 3 (DW_TAG_typedef)
    <870d7>   DW_AT_decl_file   : 26    
 ....

有了那棵“树”,我就能得到所有的全局变量和类型。例如,如果您查看第一个变量 NetBuf_ID_Ctr我们可以看到我们可以获取节点<0x86923>上的类型信息.该节点在树中的某个地方!如果您看一下实际上是第一个节点。开始的那个 <1><86923>....如果您在该节点内部看到,我们知道该变量是一个大小为 4 字节的无符号整数。


现在我的问题是 当我使用 readelf 命令时,我得到 enter image description here 我需要解析 192883 行文本!这棵树给了我比我需要的更多的信息。如果我使用十六进制编辑器查看该文件,我将看到以下内容:

enter image description here

请注意,我能够找到相同的变量 NetBuf_ID_Ctr在它旁边(突出显示)是它的地址 <0x86923> !

互联网上有没有什么地方可以指导我如何构建树?命令 readelf.exe 需要 0.1 秒来创建树!它将它的输出放在 StreamReader 上,这就是它如此之快的原因。如果我希望将该 StreamReader 放在内存中,将其转换为需要很长时间的字符串。


编辑

总而言之,我想知道树(readelf 的输出)是如何从 myFile.out 构建的。我无法弄清楚该模式,也没有在互联网上解释如何的地方。

最佳答案

基本上,ELF 对象文件中的 dwarf 调试信息位于 sections

  • .debug_aranges
  • .debug_frame
  • .debug_info
  • .debug_line
  • .debug_pubnames
  • .debug_pubtypes

通过解析 .debug_info 中描述调试信息条目 (DIE) 之间关系的信息来构建芯片树。如何存储此信息在 DWARF 标准中有描述,可以找到 here

从你的问题来看,你似乎想尽可能快地转储所有全局符号。 如果你想从你自己的程序中做到这一点,你可以使用 libdwarf解析 .debug_pubnames 的内容。此部分包含标题集,后跟许多名称、偏移量对。名称是全局名称,偏移量是 DIE 从其编译单元开始的偏移量。 libdwarf 可以再次使用它来获取有关它的更多详细信息。

libdwarf 可以很容易地在 Windows 上编译,但您还需要 libelf。 另见 this更简单地解释 DWARF 调试信息格式

关于windows - 找出模式以便在编译的程序中找到变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11312521/

相关文章:

c++ - 如何在 C++ 中读取 "Contributing Artist"元数据?

python - Windows 中 TEMP 目录的限制?

c - 打印 vmlinux 二进制文件中的所有符号信息

c - 读取 ELF 二进制文件的 plt 部分并打印函数虚拟地址

c++ - 在 Linux 中使用插件的 C++ 程序的最佳实践

windows - 适用于 Windows 和 Mac 的窗口管理器

windows - 如何在内核模式 Hook 中获取调用者 SID? ( Windows )

Linux 进程访问自己的 DWARF 调试信息?

debugging - 使用 DWARF 信息将内存地址映射到行号

gdb - readelf 的 DWARF 转储中最左边的数字是什么意思?