2010-11-30 2 views
6

Так что я пытаюсь использовать служебную программу objdump для построения графика потока управления из сборки, и у меня возникает проблема. В принципе, всякий раз, когда возникает ветка и целевой адрес является относительным, я не уверен, как узнать, где начинается следующий базовый блок. Я не уверен, если я буду чист, поэтому я добавлю пример. Скажем, моя программа проходит через вывод objdump и записала начальный адрес для первого базового блока. Затем он обращается к команде перехода, которая использует относительную адресацию, чтобы указать на правильный адрес для перехода. Я знаю, что конец моего первого базового блока происходит прямо там, но как я могу получить правильный адрес для начала следующего базового блока? Любое руководство, которое может предоставить любой человек, будет оценено по достоинству, я, в лучшем случае, новичок x86, и на прошлой неделе я ударил головой об этом.Определение значений регистра при использовании objdump

ответ

4

Предполагая, что я понимаю вопрос, возможно, это поможет вам начать работу. Относительные прыжки основаны на pc.

 
d: eb 04 jmp 13 

0xEB - это код операции для относительного перехода на основе 8 бит. Адрес инструкции находится в выводе objdump, в данном случае d или 0xD. это двухбайтная команда (x86 - переменная длина). он сообщает вам на выходе, что такое адрес назначения, в данном случае jmp 13. Поэтому поиск строки в выводе objdump, который начинается с 13, и двоеточие - это начало следующего фрагмента кода.

Чтобы понять, как вычисляется этот адрес. ПК находится в 0xD, когда он начинает извлекать инструкцию, он принимает два байта, поэтому pc находится в 0xD + 2 = 0xF, когда он готов выполнить эту инструкцию. Смещение составляет 0x4, поэтому 0xF + ​​0x4 = 0x13 адрес назначения.

 
20: 75 ed jne f 

То же самое происходит для назад. pc плюс количество байтов = 0x20 + 2 = 0x22. 0xED - это число, подписанное и отрицательное, поэтому знак увеличивается до 0xED до 0xFFFFFFF ... FFFFED, однако большой адрес вашего регистра. Добавьте 0x22 + 0xFFFFFF ... FFFED, и вы получите 0x0F адрес назначения. Вы также можете взять 0xED, инвертировать и добавить 1, чтобы отменить его. ~ 0xED = 0x12, 0x12 + 1 = 0x13. Таким образом, 0xED означает вычитание 0x13. 0x22-0x13 = 0x0F.

Вот еще, в каждом случае он дает вам целевой адрес, который вы можете просто найти в выводе objdump.

Чтобы понять, как оно вычисляет это значение. В той же истории, начиная с кода операции 0x400A81, в этом случае требуется 6 байтов для инструкции переменной длины. Таким образом, к тому времени, когда вы будете готовы выполнить pc, на 0x400A81 + 6 = 0x400A87. Смещение равно 0x107, поэтому, если условие выполнено, адрес назначения 0x400A87 + 0x107 = 0x400B8E.

Обратите внимание, что это grepped из более крупной программы, а не последовательного кода, всего лишь набор изолированных примеров.

 
    400a81: 0f 8f 07 01 00 00  jg  400b8e 
    400a8f: 0f 8f e6 00 00 00  jg  400b7b 
    400a9d: 0f 8f c5 00 00 00  jg  400b68 
    400aab: 0f 8f a4 00 00 00  jg  400b55 
    400ab9: 0f 8f 83 00 00 00  jg  400b42 
    401d76: 0f 8f 31 01 00 00  jg  401ead 
+0

Большое вам спасибо, это проясняет мою проблему. По сути, похоже, что я просто не полностью понимаю вывод objdump, с которым я работаю. Кто-нибудь знает о хорошем ресурсе, чтобы узнать больше о выходе objdump? – Sam 2010-11-30 15:11:08