Определение значений регистров при использовании objdump

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

1 ответ

Решение

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

d: eb 04 jmp 13 

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

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

20: 75 Эд Джей Ф

То же самое касается и в обратном направлении. 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 байтов. Таким образом, к тому моменту, когда вы будете готовы выполнить компьютер, вы получите 0x400A81+6 = 0x400A87. Смещение составляет 0x107, поэтому, если условие выполнено, адрес назначения будет 0x400A87 + 0x107 = 0x400B8E.

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

  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 
Другие вопросы по тегам