понимание операнда вызова x86-64 - PullRequest
0 голосов
/ 02 ноября 2019

Я смотрю на некоторый тестовый код в radare2, и у меня возникают проблемы с пониманием того, как дизассемблеры вычисляют, как происходит переход инструкции вызова. Учтите это:

r2

при 0x00001090 вызывает () метод. Я хотел разобрать двоичный файл (e89bffffff), связанный с этой инструкцией, поэтому я запустил его через lib capstone и получил следующее:

capstone

, чтобы мы моглиувидеть фактический операнд 0xfb0. И тогда в rasm2 мы имеем:

# rasm2 -a x86 -b 64 -d e8a1ffffff
call 0xffffffffffffffa6

, что отличается. Я ожидал, что libcapstone и rasm2 будут иметь одинаковые выходные данные.

Мой главный вопрос: как мне интерпретировать 0xfb0 (или 0xffffffffffffffa6), чтобы получить следующий адрес инструкции? В моем случае sym.imp.puts находится в 0x00001030 в соответствии с radare.

1 Ответ

4 голосов
/ 02 ноября 2019

Как показано на https://www.felixcloutier.com/x86/call,, код операции e8 выполняет вызов с относительным смещением . Операндом является 32-битное смещение со знаком, которое добавляется к адресу следующей инструкции для получения абсолютного целевого адреса. Это облегчает написание независимого от позиции кода, который будет работать одинаково независимо от того, где он загружен в память.

Операнд смещения здесь 9bffffff. Это порядковый номер (как и все в x86), так что это число 0xffffff9b или -0x65.

При первой разборке инструкция, следующая за инструкцией call, находится по адресу 0x00001095,таким образом, звонок перейдет на 0x00001095 - 0x65 = 0x00001030. Дизассемблер проверил таблицу символов и увидел, что этот адрес соответствует sym.imp.puts, поэтому он показывает вам, что вместо числового адреса.

Во время вашей второй разборки, кажется, код был загружен с другойадрес, а адрес следующей инструкции - 0x1015, поэтому вызов перейдет на 0x1015 - 0x65 = 0x0fb0. Дизассемблер выполнил этот расчет за вас и показывает фактический целевой адрес, а не смещение.

rasm2 только что получил инструкцию без информации об адресе, где он был найден, поэтому он не может выполнить этот расчет. Таким образом, это просто говорит вам о смещении. По какой-то причине он решил расширить его до 64 бит. Также вы, кажется, сделали опечатку, указав e8a1ffffff вместо действительной инструкции e89bffffff, поэтому вы видите другое смещение.

...