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

Ton*_*Nam 9 compiler-construction gcc cygwin elf dwarf

编辑(更新的问题)

我有一个简单的C程序:

   // it is not important to know what the code does you may skip the code 
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

   //  Name          Display Name                    Type      Size     Address
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

对于这个小程序,它工作得很好,也适用于其他大型项目.

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


所以我的问题是,我不知道我不知道采取什么方法来解决这个问题.这些是我一直在考虑的选项:

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

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

  3. 安装Cygwin的,这样我可以在如Windows使用Linux命令objdump,nmelfread.当我使用这些命令时,我没有玩过足够的命令,比如readelf -w a.out我得到了更多我需要的信息.有一些缺点,为什么我没有花这么多时间用这种方法:

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

    • 优点:如果我们找到正确的使用命令,我们将不会重新发明轮子并节省一些时间.也许这是解析命令结果的问题,例如objdump -w a.out


如果你想下载a.out文件以便在这里解析它.


摘要

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

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

Ton*_*Nam 13

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

  1. 这里下载Windows上需要的linux命令.

    在bin目录中应该有: readelf.exe

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

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

    // cd "path where readelf.exe is"
    readelf.exe -s a.out
    
    Run Code Online (Sandbox Code Playgroud)

    这是将要出现的列表: 在此输入图像描述

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

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

  4. 我们要做的最后一件事就是获取类型.如果你看一下我们看到的类型是= <0x522>.这意味着我们必须转到树的522才能获得有关该时间的更多信息.如果我们去那个部分,这就是我们得到的:在此输入图像描述 通过查看树,我们知道SOME_LARGE_VARIABLE的类型为unsigned long