10

编辑(更新的问题)

我有一个简单的 C 程序:

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

主程序

#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一个包含调试信息的 elf 文件。

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

   //  Name          Display Name                    Type      Size     Address

在此处输入图像描述

对于这个小程序,它非常适用,也适用于其他大型项目。

该代码有 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,我将不胜感激,因为这将使其更易于部署。由于这个问题要求很多,我试图将其拆分为更多:

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

4

1 回答 1

14

Here is what I will do. Why reinvent the wheel!

  1. Download linux commands that will be needing on windows from here.

    on the bin directory there should be: readelf.exe

    Note we will not need Cygwin or any program so deploying will be simple!

  2. Once we have that file execute in cmd:

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

    and this is the list that will come out: enter image description here

    so if you take a look we are interested in getting all the variables that are of type OBJECT with size greater than 0.

  3. Once we got the variables we can use the readelf.exe -w a.out command to take a look at the tree and it looks like:enter image description here let's start looking for one of the variable we found on step 2 (SOME_GREAT_COUNTER) Note that at the top we know the location where the variable is being declared, we got more information such as the line where it was declared and the memory address

  4. The last thing we are missing to do is to get the type. if you take a look we see that the type is = <0x522>. What that means is that we have to go to 522 of the tree to get more info about that time. If we go to that part this is what we get:enter image description here From looking at the tree we know that SOME_LARGE_VARIABLE is of type unsigned long

于 2012-06-15T19:01:23.597 回答