Определение значений регистров при использовании objdump - PullRequest
6 голосов
/ 30 ноября 2010

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

1 Ответ

4 голосов
/ 30 ноября 2010

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

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 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 байтов.Таким образом, к тому моменту, когда вы будете готовы выполнить компьютер, вы получите 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 
...