Имена исходных общих библиотек для импортированных символов в формате ELF - PullRequest
3 голосов
/ 12 июля 2011

Я работаю над программой, которая будет анализировать объектные файлы в форматах ELF и PE (тип школы / исследовательский проект). Сейчас я собираюсь обработать динамические символы импорта в исполняемых файлах. Я хотел бы найти как можно больше информации о символе.

В формате PE импорт хранится в разделе .idata. Есть несколько таблиц с разной информацией, но что меня интересует, так это то, что нет проблем выяснить, в какой библиотеке определяется символ. Всегда есть имя разделяемой библиотеки и затем импортируемые из нее имена / порядковые номера символов.

Я хотел бы также найти такую ​​информацию в файлах ELF. Все импорт / экспорт находятся в разделе .dynsym - таблица динамических символов. Импортируемые символы помечаются как неопределенные, например:

00000000      DF *UND*  00000000  GLIBC_2.0   fileno

Но нет информации, что является исходным файлом этого символа. Все необходимые общие библиотеки перечислены в разделе .dynamic, например:

Dynamic Section:
  NEEDED               libz.so.1

Только информация о библиотеке в символе является версией String = GLIBC_2.0. Я думал о том, чтобы получить реальное имя библиотеки через это, но когда я посмотрел на вывод objdump -p, я обнаружил, что GLIBC_2.0 может быть связан с несколькими библиотеками:

Version References:
  required from libm.so.6:
    0x0d696910 0x00 13 GLIBC_2.0
  required from libgcc_s.so.1:
    0x0b792650 0x00 12 GLIBC_2.0

Если я правильно понимаю процесс динамического связывания ELF, не будет возможности найти эту информацию в исполняемом файле ELF. Откуда именно импортируется символ, определяется компоновщиком после загрузки всех таблиц символов в память. Но я хотел бы убедиться в этом, прежде чем я продолжу, поэтому мой вопрос: есть ли способ, как я могу узнать имя общей библиотеки символов из исполняемого файла ELF?

Спасибо за любой совет.

Ответы [ 2 ]

0 голосов
/ 13 июля 2011

Хорошо, поэтому, вероятно, вообще невозможно присвоить имя библиотеки каждому импортированному символу. Но я мог бы найти решение с помощью Symbol Versioning. Конечно, разделы версий sybol не обязательно должны присутствовать в каждом файле ELF.

struct elf_obj_tdata *pElf = bfdFile->tdata.elf_obj_data;
for (long i = 0; i < dynNumSyms; i++)
{
    asymbol *dynSym = dynSymTab[i];

    // If there is version information in file.
    if (pElf->dynversym_section != 0
        && (pElf->dynverdef_section != 0
        || pElf->dynverref_section != 0))
    {
        unsigned int vernum;
        const char *version_string;
        const char *fileName;

        vernum = ((elf_symbol_type *) dynSym)->version & VERSYM_VERSION;

        if (vernum == 0)   // local sym
            version_string = "";
        else if (vernum == 1)   // global sym, defined in this object
            version_string = "Base";
        else if (vernum <= pElf->cverdefs)
            version_string = pElf->verdef[vernum - 1].vd_nodename;
        else
    {
        Elf_Internal_Verneed *t;

        version_string = "";
        fileName = "";

        // Iterate through all Verneed entries - all libraries
        for (t = pElf->verref; t != NULL; t = t->vn_nextref)
        {
            Elf_Internal_Vernaux *a;

            // Iterate through all Vernaux entries
            for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
            {
                // Find associated entry
                if (a->vna_other == vernum)
                {
                    version_string = a->vna_nodename;
                    fileName = t->vn_filename;
                    break;
                }
            }
        }

        // here we have got:
        // name of symbol  = dynSym->name
        // version string  = version_string
        // name of library = fileName
    }
    }
}

Так что вы думаете, это правильно?

0 голосов
/ 12 июля 2011

Несколько месяцев назад я работал над довольно похожими вещами - я смог ответить на все мои вопросы, взяв источник в nm и readelf.(См. http://ftp.gnu.org/gnu/binutils/) Я также нашел это полезным -> http://www.skyfree.org/linux/references/ELF_Format.pdf

...