#include #include #include #include #include #include #include #include #include "bfd.h" // apt install binutils binutils-dev // gcc test_bfd.c -o test_bfd -lopcodes && ./test_bfd // https://ftp.gnu.org/old-gnu/Manuals/bfd-2.9.1/html_chapter/bfd_1.html static bfd_boolean disassemble; struct data { char *data; }; static int dump_asm(void *stream, const char *fmt, ...){ struct data *sData = (struct data*)stream; va_list args; va_start(args, fmt); char str[64]; vsprintf(str, fmt, args); //vsnprintf(str, sizeof(str), fmt, args); //asprintf(str, "%s\n", args); va_end(args); char tmp[64]; memset(tmp, 0, 64); //printf("%d\n", sData->offset); if (strlen(sData->data) > 0){ memcpy(tmp, sData->data, 64); //printf("TMP: %s %d\n", tmp, strlen(tmp)); strcat(tmp, str); } else memcpy(tmp, str, strlen(str)); memcpy(sData->data, tmp, 64); } static int disas(unsigned char *code, size_t length){ struct disassemble_info disasm_info; struct data *sData = (struct data*)malloc(sizeof(struct data)); sData->data = (char*)malloc(64); disassemble = TRUE; bfd_init(); //set_default_bfd_target(); // Defined in https://github.com/redox-os/binutils-gdb/blob/master/include/dis-asm.h //init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf); init_disassemble_info (&disasm_info, sData, dump_asm); disasm_info.arch = bfd_arch_i386; disasm_info.mach = bfd_mach_x86_64; disasm_info.read_memory_func = buffer_read_memory; disasm_info.buffer = code; disasm_info.buffer_vma = 0; disasm_info.buffer_length = length; disassemble_init_for_target(&disasm_info); disassembler_ftype disas; disas = disassembler(bfd_arch_i386, false, bfd_mach_x86_64, NULL); if (!disas){ printf("Can't disassemble\n"); return -1; } size_t i = 0; while (i < length){ size_t octets = disas(i, &disasm_info); printf("%s\n", sData->data); i += octets; memset(sData->data, 0, 64); }; free(sData->data); free(sData); return 0; } int main(void){ unsigned char code[] = { 0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x20, 0x89, 0x7D, 0xEC, 0x48, 0x8D, 0x4D, 0xF4, 0x8B, 0x45, 0xEC, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x48, 0x89, 0xCE, 0x89, 0xC7, 0xE8, 0x42, 0xFC, 0xFF, 0xFF, 0x48, 0x89, 0x45, 0xF8, 0x48, 0x83, 0x7D, 0xF8, 0xFF, 0x75, 0x07, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0x2C, 0x0F, 0xB6, 0x45, 0xF4, 0x3C, 0x7F, 0x75, 0x1F, 0x0F, 0xB6, 0x45, 0xF5, 0x3C, 0x45, 0x75, 0x17, 0x0F, 0xB6, 0x45, 0xF6, 0x3C, 0x4C, 0x75, 0x0F, 0x0F, 0xB6, 0x45, 0xF7, 0x3C, 0x46, 0x75, 0x07, 0xB8, 0x01, 0x00, 0x00, 0x00, 0xEB, 0x05, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC9, 0xC3 }; size_t length = sizeof(code); disas(code, length); return 0; }