Как определить начальные значения регистров, используемые в коде сборки Intel x86? - PullRequest
2 голосов
/ 02 августа 2020

Я работаю над подсчетом количества инструкций по сборке в дизассемблированном коде (add, sub, jmp, et c.). Я также должен учитывать условия, которые могут вызвать циклы / скачки, требующие от меня многократного подсчета набора инструкций. Следовательно, мне нужно записывать значения регистров, поэтому, когда я сталкиваюсь с таким условием, как «jne», я буду знать, перескочил ли код, или я могу просто продолжить синтаксический анализ дизассемблированного кода.

Я сейчас нахожусь запутался в начальных значениях регистров вроде (edx, eax, rbp, rsp, et c.). Я использовал objdump для сброса всего кода сборки, и я вижу, что в моей дизассемблированной функции <main> первая строка кода сборки:

push rbp

mov rbp, rsp

sub rsp, 0xdb0

Понятия не имею где инициализируется rbp. Когда я сделал контрольную F для «rbp», я увидел первое, что всплывает, это инструкция «rex.WRX pu sh rbp». Это инициализирует rbp равным 0?

Я также не понимаю, откуда начинается код сборки. Первоначально я думал, что это началось с <main>, но я также вижу другие функции, такие как <start> и <init>.

Любые пояснения приветствуются!

1 Ответ

4 голосов
/ 02 августа 2020

Objdump даст вам только c дизассемблер исполняемого файла. Чтобы получить трассировку времени выполнения вашей программы, вы можете использовать такие инструменты, как Intel Pin . В папке ManualExample с распределениями контактов есть инструмент itrace.so, который можно просто использовать для получения трассировки времени выполнения программы.

Путь к папке-контакту / pin -t pin- имя-инструмента-с-путем - двоичный-к-инструменту

Пин-фреймворк также позволяет регистрировать содержимое различных регистров, содержимое и адреса переменных программы. См. руководство по PIN для примеров и того, как писать свои собственные инструменты. Вы всегда можете изменить содержимое существующего примера, чтобы изменить его для своих нужд. Чтобы написать полностью новый инструмент для закрепления, вы должны использовать шаблон инструмента для закрепления в каталоге MyPinTool .

«pu sh rbp и другие инструкции при запуске функции». Во время выполнения программы вызывается ряд функций . Каждая функция разделяет регистры и стек. Каждая функция использует часть стека для своих локальных переменных. Когда функция освобождается, место стека может быть использовано другими последующими функциями. Освободить память просто, измените значение вершины стека (rbp). Использование стека гарантирует, что один и тот же набор ячеек памяти может использоваться локальными переменными многих функций, уменьшая потребность в памяти.

main () - первая написанная пользователем функция, которая вызывается во время выполнения программы. Набор дополнительных функций , которые не являются частью исходной программы, __start (), __fini и т. Д. Также присутствуют как часть исполняемого файла программы, которые обычно не определяются пользователями . Они специфичны для ОС c и добавляются компиляторами. Некоторые из них вызываются до, а некоторые после выполнения программы пользователя для инициализации и обслуживания.

...