2013-07-05 3 views
2

Я пишу скрипт для извлечения всех функций (написанных пользователем) в двоичном формате.Извлечение только моих имен функций из двоичного файла ELF

Следующий сценарий оболочки извлекает свои имена функций, а также некоторые функции библиотеки, которая начинается с __

readelf -s ./a.out | gawk ' 
{ 
    if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main") { 
    print "b " $NF; //***Updated 
    } 
}' &> function_names; 

Вывод function_names файла:

b __libc_csu_fini 
b PrintDivider  
b PrintFooter  
b __libc_csu_init  
b PrintHeader 

Я хотел бы извлечь только свою функцию. поэтому, как проверить, начинается ли имя функции с __, или любые другие альтернативы также высоко оцениваются.

Обновление:
Решение @djf прекрасно работает. Что делать, если файлы .c, которые скомпилированы, также могут содержать функцию, начинающуюся с __? В таком случае, как дифференцироваться?

ответ

6

Что об использовании readelf на файл объекта (ов) вместо выполняемого файла? Тогда нет спама из функций библиотеки. Используйте флаг -c для компиляции в объектный файл, а не ссылку сразу.

PS: Правильный инструмент для извлечения имен из исполняемого файла или объектного файла: nm, а не readelf. Использование nm -P file имеет все, что вы хотите.

$ nm -P tst.o | awk '$2 == "T" {print "b " $1}' 
b foo 
b main 

EDIT: Для того, чтобы игнорировать main и символы, начинающиеся с символа подчеркивания, используйте

$ nm -P a.out | awk '$2 == "T" && $1 !~ /^_/ && $1 != "main" {print "b " $1}' 
+0

nm также дает '_init, _start, _fini' – Jeyaram

+0

@Jeyaram Нет, если вы не используете его в объектных файлах вместо исполняемого файла. Но см. Мое редактирование. – Jens

+0

+1 есть .. исправленный. все еще 'main' идет :) – Jeyaram

1

Протяните его через grep ^[^_]. [30 char]

+0

Спасибо за ваш ответ. Может у, пожалуйста, объясните немного больше? – Jeyaram

+1

@Jeyaram Объясните, что? Вы передаете результат через эту команду, а BOOM вы получаете то, что хотите. –

+0

Спасибо, что отлично работает. Я обновил свой вопрос сейчас. Пожалуйста, проверьте. – Jeyaram

4

Вы можете добавить проверку regex, чтобы имя функции начиналось с буквы.

Я полагаю, что $ 8 содержит имя функции:

readelf -s ./a.out | gawk ' 
{ 
    if($4 == "FUNC" && $3 != "0" && $7 == "13" && $8 != "main" && $8~/^[[:alpha:]]/) { 
    print $NF; 
    } 
}' 
+0

Отлично !!!!! Работает так, как ожидалось. – Jeyaram

+0

Если пользовательская функция также начинается с __, то как различать? Есть идеи?? PLS доля. – Jeyaram

+1

@Jeyaram - это действительно плохая практика, чтобы назвать ваши функции ведущими символами подчеркивания, поскольку эти имена зарезервированы для компилятора и основных библиотек ... не делайте этого, если можете - на C++ его запрещено стандартом языка. Однако я не уверен в C.Я не могу сказать, как отличить, потому что вы не сказали нам, как выглядят ваши имена функций ... C-библиотеки обычно добавляют префикс для всех имен функций, чтобы избежать конфликтов имен с другими библиотеками. Может быть, вы можете отфильтровать такой префикс? – djf

Смежные вопросы