从a.out文件中提取全局变量

时间:2012-06-12 19:20:09

标签: gcc compiler-construction cygwin elf dwarf

编辑(更新的问题)

我有一个简单的C程序:

   // it is not important to know what the code does you may skip the code 

的main.c

#include <bsp.h>

unsigned int   AppCtr;
unsigned char  AppFlag;
int SOME_LARGE_VARIABLE;

static  void  AppTest (void);

void  main (void)
{
    AppCtr  = 0;
    AppFlag = 0;        
    AppTest();
}

static void Foo(void){
    SOME_LARGE_VARIABLE=15; 
}


static  void  AppTest (void)
{
    unsigned int  i;
    i = 0;
    while (i < 200000) {
        i++;
    }

    BSP_Test();      
    SOME_LARGE_VARIABLE=3;    
    Foo();
}

bsp.c

extern int SOME_LARGE_VARIABLE;
extern unsigned char  AppFlag;

unsigned int long My_GREAT_COUNTER;

void  BSP_Test (void) {
  SOME_LARGE_VARIABLE = 5;
  My_GREAT_COUNTER = 4;
}

(该程序没有做任何有用的事情...... 我的目标是提取变量名称的位置以及它们的内存地址

当我编译程序时,我得到文件a.out,这是一个包含调试信息的精灵文件。

该公司有人在5年前在.net上编写了一个程序,它将从a.out文件中获取所有这些信息。这是代码返回的内容:

   //  Name          Display Name                    Type      Size     Address

enter image description here

对于这个小程序,它可以很好地工作,也适用于其他大型项目。

该代码长度为2000行,有几个错误,并且它不支持.NET版本4.这就是我尝试重新创建它的原因。


所以我的问题是,因为我不知道采取什么方法来解决这个问题,我迷失了。这些是我一直在考虑的选择:

  1. 组织我在第一张图片上显示的程序的错误代码,并尝试查看它的作用以及它如何解析a.out文件以获取该信息。一旦我完全理解它,试着弄清楚为什么它不支持版本3和4。

  2. 我可以创建正则表达式,所以也许尝试通过执行以下操作来查找a.out文件中的模式:enter image description here到目前为止,我能够找到只有...的模式一个文件(main.c)。但是当有几个文件时会变得更复杂。我还没有尝试过。也许它不会那么复杂,有可能找到模式。

  3. 安装Cygwin,以便我可以在objdumpnmelfread等窗口上使用linux命令。当我使用readelf -w a.out这些命令时,我没有玩过命令,我得到了更多我需要的信息。有一些缺点,为什么我没有花这么多时间用这种方法:

    • 缺点:在Windows上安装cygwin需要一段时间,在向客户提供此应用程序时,我们不希望他们必须安装它。也许有一种方法只需安装命令objdump和elfread而无需安装整个事情

    • 优点:如果我们找到合适的命令,我们将不会重新发明轮子并节省一些时间。也许这是解析objdump -w a.out

    • 等命令结果的问题

  4. 如果您要下载a.out文件以便解析它here it is


    摘要

    我将能够在a.out文件中获取全局变量。我想知道每个变量的类型(int,char,..),它们有什么内存地址,我也想知道变量被声明的文件(main.c或someOtherFile.c)。如果我不必使用cygwin,我会很感激,因为这样可以更容易部署。由于这个问题要求很多,我试图把它分成更多:

    也许我应该删除其他问题。抱歉多余了。

1 个答案:

答案 0 :(得分:13)

这是我要做的。为什么重新发明轮子!

  1. here.

    下载Windows上需要的linux命令 bin目录上的

    应该是:readelf.exe

    请注意,我们不需要Cygwin或任何程序,因此部署简单!

  2. 一旦我们在cmd中执行该文件:

    // cd "path where readelf.exe is"
    readelf.exe -s a.out
    

    这是将要出现的列表: enter image description here

    所以如果你看看我们有兴趣获得OBJECT类型大小大于0的所有变量。

  3. 获得变量之后,我们可以使用readelf.exe -w a.out命令来查看树,它看起来像:enter image description here让我们开始寻找变量之一我们在第2步找到(SOME_GREAT_COUNTER)注意,在顶部我们知道声明变量的位置,我们获得了更多信息,例如声明它的行和内存地址

  4. 我们要做的最后一件事就是获取类型。如果你看一下我们看到的类型是=&lt; 0x522&gt;。这意味着我们必须转到树的522才能获得有关该时间的更多信息。如果我们去那个部分,这就是我们得到的:enter image description here从树上看,我们知道SOME_LARGE_VARIABLE的类型是unsigned long