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
Другие вопросы по тегам