Абсолютная адресация для замены кода во время выполнения в x86_64 - PullRequest
9 голосов
/ 02 ноября 2011

В настоящее время я использую некоторую схему замены кода в 32-битной системе, где код, который перемещается в другую позицию, читает переменные и указатель класса.Поскольку x86_64 не поддерживает абсолютную адресацию, у меня возникают проблемы с получением правильных адресов для переменных в новой позиции кода.Проблема в том, что из-за относительной адресации rip адрес указателя инструкции отличается от адреса во время компиляции.

Так есть ли способ использовать абсолютную адресацию в x86_64 или другой способ получить адреса переменных, а не относительный указатель инструкции?

Что-то вроде: leaq variable(%%rax), %%rbx также поможет.Я только хочу не зависеть от указателя инструкций.

Ответы [ 2 ]

7 голосов
/ 02 ноября 2011

Попробуйте использовать модель кода large для x86_64. В gcc это можно выбрать с помощью -mcmodel = large . Компилятор будет использовать 64-битную абсолютную адресацию для кода и данных.

Вы также можете добавить -fno-pic , чтобы запретить генерацию независимого от позиции кода.

Редактировать: я создал небольшое тестовое приложение с -mcmodel = large , а полученный бинарный файл содержит последовательности, подобные

400b81:       48 b9 f0 30 60 00 00    movabs $0x6030f0,%rcx
400b88:       00 00 00 
400b8b:       49 b9 d0 09 40 00 00    movabs $0x4009d0,%r9
400b92:       00 00 00 
400b95:       48 8b 39                mov    (%rcx),%rdi
400b98:       41 ff d1                callq  *%r9

, который представляет собой немедленную загрузку с абсолютной 64-битной скоростью (в данном случае адрес), за которой следует косвенный вызов или косвенная загрузка. Последовательность инструкций

moveabs $variable, %rbx
addq %rax, %rbx

является эквивалентом "leaq offset64bit (% rax),% rbx" (которого не существует) с некоторыми побочными эффектами, такими как изменение флага и т. Д.

2 голосов
/ 02 ноября 2011

То, о чем вы спрашиваете, выполнимо, но не очень просто.

Один из способов сделать это - компенсировать перемещение кода в его инструкциях.Вам нужно найти все инструкции, которые используют относительную RIP-адресацию (они имеют байт ModRM 05h, 0dh, 15h, 1dh, 25h, 2dh, 35h или 3dh) и откорректировать их поле disp32 на величинуmove (поэтому перемещение ограничено до +/- 2 ГБ в виртуальном адресном пространстве, что не может быть гарантировано, если 64-разрядное адресное пространство превышает 4 ГБ).

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

; These replace the original instruction and occupy exactly as many bytes as the original instruction:
  JMP Equivalent1
  NOP
  NOP
Equivalent1End:

; This is the code equivalent to the original instruction:
Equivalent1:
  Equivalent subinstruction 1
  Equivalent subinstruction 2
  ...
  JMP Equivalent1End

Оба метода потребуют как минимум несколько элементарных процедур разборки x86.

В первом случае может потребоваться использованиеVirtualAlloc() в Windows (или некотором аналоге в Linux), чтобы гарантировать, что память, содержащая исправленную копию исходного кода, находится в пределах +/- 2 ГБ этого исходного кода.И выделение по определенным адресам все еще может потерпеть неудачу.

Последнее потребует не только примитивной разборки, но также полного декодирования и генерации команд.

Могут существовать и другие причуды, которые можно обойти.

Границы команд также можно найти, установив флаг TF в регистре RFLAGS, чтобы ЦП генерировал прерывание отладки single-step в конце выполнения каждой инструкции.Обработчик исключений отладки должен будет перехватить их и записать значение RIP следующей инструкции.Я полагаю, что это можно сделать с помощью Structured Exception Handling (SEH) в Windows (никогда не пробовал с прерываниями отладки), не уверен насчет Linux.Чтобы это работало, вам нужно будет выполнить весь код, каждую инструкцию.

Кстати, в 64-битном режиме есть абсолютная адресация, см., Например, инструкции MOV к / от аккумулятора с кодами операций изС 0A0h по 0A3h.

...