u1 *disassinstr(u1 *code) { s4 seqlen; s4 i; if (!disass_initialized) { INIT_DISASSEMBLE_INFO(info, NULL, disass_printf); /* setting the struct members must be done after INIT_DISASSEMBLE_INFO */ info.mach = bfd_mach_x86_64; info.read_memory_func = &disass_buffer_read_memory; disass_initialized = true; } printf("0x%016lx: ", (s8) code); disass_len = 0; seqlen = print_insn_i386((bfd_vma) code, &info); for (i = 0; i < seqlen; i++, code++) { printf("%02x ", *code); } for (; i < 10; i++) { printf(" "); } printf(" %s\n", disass_buf); return code; }
Mnemonic::Mnemonic(pword buffer, bool att) : opcodeLength(0), assemblyString("") { //NULL the opcode: memset(this->opcode, 0, MAX_INSTRUCTION_BYTES); //Open a memory stream: char stringBuffer[256]; FILE* memStream = fmemopen(stringBuffer, 256, "w"); if (!memStream) { throw runtime_error("Failed to open memory stream."); } //Prepare disassembly info (bfd): struct disassemble_info info; init_disassemble_info(&info, memStream, (fprintf_ftype)fprintf); //This is the same for all architectures: info.buffer = (bfd_byte*)buffer; info.buffer_length = MAX_INSTRUCTION_BYTES; //Discriminate between architectures: #ifdef __i386__ info.arch = bfd_arch_i386; info.mach = att ? bfd_mach_i386_i386 : bfd_mach_i386_i386_intel_syntax; info.endian = BFD_ENDIAN_LITTLE; this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info); #elif __amd64__ info.arch = bfd_arch_i386; info.mach = att ? bfd_mach_x86_64 : bfd_mach_x86_64_intel_syntax; info.endian = BFD_ENDIAN_LITTLE; this->opcodeLength = att ? print_insn_i386(0, &info) : print_insn_i386_intel(0, &info); #endif //Close the stream: fclose(memStream); //Assign: this->assemblyString = stringBuffer; //Build the raw opcode buffer from the length: memcpy(this->opcode, buffer, this->opcodeLength); }
void print_instruction(void *buf, unsigned long size) { struct disassemble_info info; init_disassemble_info (&info, stdout, (fprintf_ftype)fprintf); info.mach = bfd_mach_x86_64; info.endian = BFD_ENDIAN_LITTLE; info.buffer = buf; info.buffer_length = size; printf("\033[35m"); print_insn_i386(0, &info); printf("\033[0m"); printf("\n"); }
/** * Get length of instruction at the current PC. * * @param value the PC value. * * @return length of instruction at PC address. * * @ingroup RuntimeAPI */ int CBTF_GetInstrLength(uint64_t pcvalue) { //fprintf(stderr, "ENTERED CBTF_GetInstrLength\n"); #if defined(__linux) && (defined(__i386) || defined(__x86_64)) disassemble_info disinfo; disassembler_ftype disassemble_fn; initdisassembler(); //fprintf(stderr, "CBTF_GetInstrLength CALLS INIT_DISASSEMBLE_INFO\n"); INIT_DISASSEMBLE_INFO(disinfo, stdout, fprintf); disinfo.flavour = bfd_get_flavour (abfd); disinfo.arch = bfd_get_arch (abfd); //disinfo.mach = bfd_get_mach (abfd); disinfo.mach = bfd_mach_i386_i386; disinfo.octets_per_byte = bfd_octets_per_byte (abfd); if (bfd_big_endian (abfd)) disinfo.display_endian = disinfo.endian = BFD_ENDIAN_BIG; else if (bfd_little_endian (abfd)) disinfo.display_endian = disinfo.endian = BFD_ENDIAN_LITTLE; else disinfo.endian = BFD_ENDIAN_UNKNOWN; disinfo.buffer_length = 8; unsigned char* ptr = (unsigned char*) pcvalue; disinfo.buffer_vma = pcvalue; disinfo.buffer = ptr; disinfo.fprintf_func=(fprintf_ftype) dummyprint; //fprintf(stderr, "CBTF_GetInstrLength CALLS print_insn_i386 with addr %#lx\n",pcvalue); int insbytes = print_insn_i386(pcvalue, &disinfo); //fprintf(stderr,"CBTF_GetInstrLength returns length %d\n",insbytes); return insbytes; #elif defined(__linux) && defined(__powerpc__) /* FROM: http://www.ibm.com/developerworks/library/l-ppc/ All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__powerpc64__) /* FROM: http://www.ibm.com/developerworks/library/l-ppc/ All PowerPCs (including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__ia64) /* IA64 bundles are 128 bits. The caller must find the address of the bundle that contains the exception address and add this return value to it prior to updating the context PC. */ return 0x10; #elif defined(__linux) && defined(__aarch64__) /* FROM: Arm architecture wiki page Armv8 (and also including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #elif defined(__linux) && defined(__arm__) /* FROM: Arm architecture wiki page Armv7 (and also including 64-bit implementations) use fixed-length 32-bit instructions */ return 0x4; #else #error "Platform/OS Combination Unsupported!" #endif }