objdump-дизассемблирование, странные call-конструкции

Модератор: Модераторы разделов

Цинтров
Сообщения: 4

objdump-дизассемблирование, странные call-конструкции

Сообщение Цинтров »

Здравствуйте товарищи.

Вот мне потребовалось дизассемблировать несколько o-файлов, и сразу наткнулся
на непонятную вещь.

Дизассемблирование провожу через команду objdump -d ./file.o

И вот что вижу в коде

Код: Выделить всё

000012b8 <AllArraysInit>:
    12b8:       55                      push   %ebp
    12b9:       89 e5                   mov    %esp,%ebp
    12bb:       83 ec 08                sub    $0x8,%esp
    12be:       e8 fc ff ff ff          call   12bf <AllArraysInit+0x7>
    12c3:       c7 05 00 00 00 00 01    movl   $0x1,0x0
    12ca:       00 00 00
    12cd:       c7 05 00 00 00 00 01    movl   $0x1,0x0
    12d4:       00 00 00
    12d7:       83 ec 0c                sub    $0xc,%esp
    12da:       6a 01                   push   $0x1
    12dc:       e8 fc ff ff ff          call   12dd <AllArraysInit+0x25>
    12e1:       83 c4 10                add    $0x10,%esp
    12e4:       c7 05 00 00 00 00 00    movl   $0x0,0x0
    12eb:       00 00 00
    12ee:       c7 05 08 00 00 00 0d    movl   $0xd,0x8
    12f5:       00 00 00
    12f8:       c7 05 0c 00 00 00 00    movl   $0x0,0xc
    12ff:       00 00 00
...


Меня беспокоят конструкции "e8 fc ff ff ff". Какой-то странный call, который указывает
на середину этой же иструкции - по идее, после этой команды должен начать
выполняться код "fc ff ff ff ...". Какой в этом смысл? Что обозначают эти
странные call - вызовы?

Сразу скажу, что исходный текст был написан на чистом C, без всяких
ухищрений в стиле анти-дебуггинга. Сейчас код утерян, а функции нужно
немного изменить, а я не могу начать из-за вот этой непонятки.

Может это какая-то хитрая оптимизация компилера? Тогда какому asm-коду
этоти команды call xxxx эквивалентны?
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Zeus »

Цинтров писал(а):
20.05.2006 22:53
Какой-то странный call, который указывает
на середину этой же иструкции - по идее, после этой команды должен начать
выполняться код "fc ff ff ff ...". Какой в этом смысл? Что обозначают эти
странные call - вызовы?

Судя по тому, что машинный код в обоих строках одинаков, похоже, что команды должны быть одинаковы. Т.е. параметры разными у них быть не могут.
Сдаётся мне, что call-вызов происходит посредством косвенной адресации, через регистры.
А вот что за ff'ы. А машинный код NOP'а какой? 0 или может это FF и есть?
Спасибо сказали:
Цинтров
Сообщения: 4

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Цинтров »

Zeus писал(а):
21.05.2006 00:10
Судя по тому, что машинный код в обоих строках одинаков, похоже, что команды должны быть одинаковы. Т.е. параметры разными у них быть не могут.
Сдаётся мне, что call-вызов происходит посредством косвенной адресации, через регистры.
А вот что за ff'ы. А машинный код NOP'а какой? 0 или может это FF и есть?


Товарищ, такой ответ мог бы и не писать, но все равно спасибо :)


> Сдаётся мне, что call-вызов происходит посредством косвенной адресации, через регистры.

Это и есть call-вызов с относительной адресацией, но регистрами тут и не пахнет.
Машинный код E8 XX XX XX XX - это call-переход на адрес, посчитанный относительно
следущей после call команды. "fc ff ff ff" - это и есть относительный адрес, и равен
в данном случае -4 (минус 4, т.е. классический дополнительный код). И вот этот -4
как раз и указывает на середину этой же инструкции, потому как длина иструкции,
как нетрудно заметить, 5 байтов.


> А вот что за ff'ы. А машинный код NOP'а какой? 0 или может это FF и есть?

Про FF читай выше. А код NOP на x86 всю жизнь был 90h.


Таки есть тут народ, который может растолковать что реально кодируется
таким кодом? В поиске нахожу только что народ декомпилирует o-шники
через objdump, что-то там рассматривает, у многих тоже всречается
эта конструкция, но никто не обращает на нее внимания.
Спасибо сказали:
Аватара пользователя
Zeus
Сообщения: 694

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Zeus »

Цинтров писал(а):
21.05.2006 01:02
Товарищ, такой ответ мог бы и не писать, но все равно спасибо :)

Что знал - сказал :)

> Сдаётся мне, что call-вызов происходит посредством косвенной адресации, через регистры.
Это и есть call-вызов с относительной адресацией, но регистрами тут и не пахнет.

Косвенная и относительная адресация - разные вещи.

Машинный код E8 XX XX XX XX - это call-переход на адрес, посчитанный относительно
следущей после call команды. "fc ff ff ff" - это и есть относительный адрес, и равен
в данном случае -4 (минус 4, т.е. классический дополнительный код).

А вот это:
=====
Тогда какому asm-коду этоти команды call xxxx эквивалентны?
=====
тогда зачем спрашивал? Ума пытаешь?

> А вот что за ff'ы. А машинный код NOP'а какой? 0 или может это FF и есть?
Про FF читай выше. А код NOP на x86 всю жизнь был 90h.

В машинных кодах не программировал уже лет 8.
Подзабыл. Да и платформа не была указана, хоть и угадывалась :)

Таки есть тут народ, который может растолковать что реально кодируется
таким кодом?

Таки неужели такой большой код, что в голове не прокрутить его работу, раз такой гуру в машинных командах?
Ну вот выполнил он call, по твоей версии, фактически на FC FF.. и т.д.
Это код какой операции? Какие параметры?
Как он из этого call'а вернётся?
Спасибо сказали:
Andrew S
Сообщения: 225
Статус: экспериментатор
ОС: Conrad-Gentoo

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Andrew S »

Выполни эту команду в gdb (командой stepi) и посмотри куда перейдет
Спасибо сказали:
Цинтров
Сообщения: 4

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Цинтров »

Я написал тестову маленькую программку и посмотрел как она компилится.
В o-файле конструкции e8 fc ff ff ff - это затычки для вызовов функции.
В скопилированном бинарнике они преобразуются в e8 xxxx с реальным
адресом подпрограммы. А для то чтобы видеть куда эти затычки
показывают, надо декомпилить с опцией -r, т.е. objdump -d -r ./file.o

Еще вопрос - нигде пока не нашел ответа. Понимают ли последние
версии IDA формат gcc o-файлов? ELF-бинарники IDA давно умела понимать,
а как обстоит дело с ошниками - непонятно. На сайте вообще инфы
о поддерживаемых форматах файлов не нашел, только поддерживаемые
платформы.

Тут мне подсказывают что o-файлы это и есть ELF файлы, но это не совсем так,
по причине описаной выше (затычки вместо адресов). Да и древняя IDA 3.75
раздраконить o-файл не может. Кто нибудь пробовал дизассемблировать
ошники через IDA 4 или 5? Хочу это узнать перед тем как качать, т. к.
тырнет у нас в провинции дюже дорогой.
Спасибо сказали:
Цинтров
Сообщения: 4

Re: objdump-дизассемблирование, странные call-конструкции

Сообщение Цинтров »

Кстати, народ, нашел одну весч, она вам понравица!

Называется obj2asm. Декомпилит линуховые o-шники
в формат MASM, классическая Intel-нотация, никаких
AT&T извратов. Можно сразу засунуть полученый код
в ассемблер и скомпилить!

Описание здесь
http://www.digitalmars.com/ctg/obj2asm.html

Скачать здесь
http://ftp.digitalmars.com/dmd.zip (~4Mb).

НО! Есть одно НО которое портит все...
Эта штука вылетает с Segmentation Fault на середине
дизассемблирования крупных o-файлов. А крупные o-файлы
это файлы больше ~10Kb... Маленькие файлы 3-5Kb декомпилятся без
нареканий, а вот чуть больше - имеем сегфолт. Причем
запустив под gdb, вижу, что вылетает на функции strlen(),
библиотеки /lib/libc.so.6

Что теперь делать - незнаю.. Почему-то в комплекте нет
исходников для obj2asm, излазил весь сайт. Попробовал
под разными линухами AltMaster2.4, RedHat9 - та же песня.

Вот уткнулся в такую бяку. Кто чем может помоч?
Можеь есть у кого более старая версия этой проги, которая
не глючит?
Спасибо сказали: