Ответ 1
Теперь Keystone кажется отличным выбором, однако, когда я задал этот вопрос, его не было.
Есть ли библиотека 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, однако для его работы требуются модификации для не-оконных машин.
На самом деле мне нужен ассемблер и дизассемблер, есть ли библиотека, которая предоставляет оба?
Теперь Keystone кажется отличным выбором, однако, когда я задал этот вопрос, его не было.
Существует библиотека, которая, по-видимому, призрак; его существование широко неизвестно:
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). Вы можете использовать frontends в качестве примеров (в частности, Драйвер YASM).
Конечно - вы можете использовать llvm. Строго говоря, это С++, но есть C-интерфейсы. Он будет обрабатывать как сборку, так и разборку, которую вы пытаетесь сделать.
Я использую fasm.dll: http://board.flatassembler.net/topic.php?t=6239 Не забудьте написать "use32" в начале кода, если он не в формате PE.
Запишите сборку в свой собственный файл, а затем вызовите ее из своей программы на C с помощью extern
. Вы должны сделать немного обманки makefile, но в противном случае это не так уж плохо.
Ваш код сборки должен следовать правилам 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 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