C библиотека х86/ х64 ассемблер
Существует ли библиотека C для сборки строки сборки x86/x64 в коды операций?
Пример кода:
/* size_t assemble(char *string, int asm_flavor, char *out, size_t max_size); */
unsigned char bytes[32];
size_t size = assemble("xor eax, eax\n"
"inc eax\n"
"ret",
asm_x64, &bytes, 32);
for(int i = 0; i < size; i++) {
printf("%02x ", bytes[i]);
}
/* Output: 31 C0 40 C3 */
Я посмотрел на asmpure, однако он нуждается в модификациях для запуска на машинах, отличных от Windows.
Мне на самом деле нужны ассемблер и дизассемблер, есть ли библиотека, которая обеспечивает оба?
6 ответов
Конечно, вы можете использовать llvm. Строго говоря, это C++, но есть интерфейсы C. Он также будет выполнять сборку и разборку, которую вы пытаетесь сделать.
Есть библиотека, которая, кажется, призрак; его существование широко неизвестно:
XED (декодер кодера X86)
Intel написала это: https://software.intel.com/sites/landingpage/pintool/docs/71313/Xed/html/
Его можно загрузить с помощью Pin: https://software.intel.com/en-us/articles/pintool-downloads
Ну вот:
http://www.gnu.org/software/lightning/manual/lightning.html
Gnu Lightning - это библиотека C, предназначенная для выполнения именно того, что вы хотите. Он использует переносимый язык ассемблера, а не специфичный для x86. Переносная сборка очень просто компилируется во время выполнения для конкретной машины.
В качестве дополнительного бонуса, он намного меньше и проще в использовании, чем LLVM (который довольно большой и громоздкий).
Возможно, вы захотите libyasm (бэкэнд YASM использует). Вы можете использовать внешние интерфейсы в качестве примеров (в частности, драйвер YASM).
Я использую fasm.dll: http://board.flatassembler.net/topic.php?t=6239 Не забудьте написать "use32" в начале кода, если он не в формате PE.
Теперь Keystone кажется отличным выбором, однако, когда я задал этот вопрос, его не существовало.
Запишите сборку в свой собственный файл, а затем вызовите ее из вашей программы на C, используя extern
, Вы должны сделать немного хитрости make-файла, но в остальном это не так плохо. Ваш ассемблерный код должен соответствовать соглашениям C, поэтому он должен выглядеть следующим образом
global _myfunc
_myfunc: push ebp ; create new stack frame for procedure
mov ebp,esp ;
sub esp,0x40 ; 64 bytes of local stack space
mov ebx,[ebp+8] ; first parameter to function
; some more code
leave ; return to C program's frame
ret ; exit
Чтобы получить содержимое переменных C или объявить переменные, к которым C может обращаться, вам нужно только объявить имена как GLOBAL или EXTERN. (Опять же, имена требуют начальных подчеркиваний.) Таким образом, переменная C, объявленная как int i, может быть доступна из ассемблера как
extern _i
mov eax,[_i]
И чтобы объявить вашу собственную целочисленную переменную, к которой программы на C могут обращаться как extern int j, вы делаете это (убедившись, что вы собираете в сегменте _DATA, если необходимо):
global _j
_j dd 0
Ваш код C должен выглядеть так
extern void myasmfunc(variable a);
int main(void)
{
myasmfunc(a);
}
Скомпилируйте файлы, затем свяжите их, используя
gcc mycfile.o myasmfile.o