Выяснить шаблон, чтобы найти переменные в скомпилированной программе

Мне нужно извлечь глобальные переменные из скомпилированной программы c. Что я сейчас делаю, так это использую команду Linux readelf для получения этой информации. Другими словами, когда я делаю:

  readelf.exe -w[i]  myFile.out      

Я делаю это с readelf.exe программа, которую можно скачать отсюда. потому что я использую 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, я получаю192883 строк текста, которые мне нужно разобрать! Это дерево дает мне больше информации о том, что мне нужно. Если я смотрю в файл с помощью шестнадцатеричного редактора, это то, что я вижу:

обратите внимание, что мне удалось найти ту же переменную NetBuf_ID_Ctr и рядом с ним (выделено) это адрес <0x86923>!

Есть ли в Интернете место, которое поможет мне понять, как построить дерево? команда readelf.exe занимает 0,1 секунды, чтобы создать дерево! Он помещает свой вывод в StreamReader, поэтому он такой быстрый. Если я хочу поместить этот StreamReader в память, преобразуя его в строку, которая занимает так много времени.


редактировать

В заключение я хотел бы знать, как дерево (вывод readelf) построено из myFile.out . Я не могу понять модель, ни место в Интернете, которое объясняет, как.

1 ответ

По сути, отладочная информация карлика в объектном файле ELF находится в разделах

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

Дерево штампов строится путем анализа информации в.debug_info, которая описывает отношения между записями отладочной информации (DIE). Как хранится эта информация, описано в стандарте DWARF, который можно найти здесь

От вашего вопроса, кажется, вы хотите сбросить все глобальные символы так быстро, как вы можете. Если вы хотите сделать это из своей собственной программы, вы можете использовать libdwarf для анализа содержимого.debug_pubnames. Этот раздел содержит наборы заголовков, за которыми следуют несколько пар имени и смещения. Имена - это глобальные имена, а смещение - это смещение DIE от начала блока компиляции. Это может снова использоваться libdwarf для получения более подробной информации о нем.

libdwarf можно довольно легко скомпилировать в windows, но вам также понадобится libelf. Смотрите также это для более простого объяснения формата отладочной информации DWARF.

Другие вопросы по тегам