libdis.h 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. #ifndef LIBDISASM_H
  2. #define LIBDISASM_H
  3. #ifdef WIN32
  4. #include <windows.h>
  5. #endif
  6. #include <cstring>
  7. #include <cstdlib>
  8. #include <cassert>
  9. #include <stdint.h>
  10. /* 'NEW" types
  11. * __________________________________________________________________________*/
  12. #ifndef LIBDISASM_QWORD_H /* do not interfere with qword.h */
  13. #define LIBDISASM_QWORD_H
  14. #ifdef _MSC_VER
  15. typedef __int64 qword_t;
  16. #else
  17. typedef int64_t qword_t;
  18. #endif
  19. #endif
  20. #include <sys/types.h>
  21. #ifdef __cplusplus
  22. //extern "C" {
  23. #endif
  24. /* 'NEW" x86 API
  25. * __________________________________________________________________________*/
  26. /* ========================================= Error Reporting */
  27. /* REPORT CODES
  28. * These are passed to a reporter function passed at initialization.
  29. * Each code determines the type of the argument passed to the reporter;
  30. * this allows the report to recover from errors, or just log them.
  31. */
  32. enum x86_report_codes {
  33. report_disasm_bounds, /* RVA OUT OF BOUNDS : The disassembler could
  34. not disassemble the supplied RVA as it is
  35. out of the range of the buffer. The
  36. application should store the address and
  37. attempt to determine what section of the
  38. binary it is in, then disassemble the
  39. address from the bytes in that section.
  40. data: uint32_t rva */
  41. report_insn_bounds, /* INSTRUCTION OUT OF BOUNDS: The disassembler
  42. could not disassemble the instruction as
  43. the instruction would require bytes beyond
  44. the end of the current buffer. This usually
  45. indicated garbage bytes at the end of a
  46. buffer, or an incorrectly-sized buffer.
  47. data: uint32_t rva */
  48. report_invalid_insn, /* INVALID INSTRUCTION: The disassembler could
  49. not disassemble the instruction as it has an
  50. invalid combination of opcodes and operands.
  51. This will stop automated disassembly; the
  52. application can restart the disassembly
  53. after the invalid instruction.
  54. data: uint32_t rva */
  55. report_unknown
  56. };
  57. /* Disassembly formats:
  58. * AT&T is standard AS/GAS-style: "mnemonic\tsrc, dest, imm"
  59. * Intel is standard MASM/NASM/TASM: "mnemonic\tdest,src, imm"
  60. * Native is tab-delimited: "RVA\tbytes\tmnemonic\tdest\tsrc\timm"
  61. * XML is your typical <insn> ... </insn>
  62. * Raw is addr|offset|size|bytes|prefix... see libdisasm_formats.7
  63. */
  64. enum x86_asm_format {
  65. unknown_syntax = 0, /* never use! */
  66. native_syntax, /* header: 35 bytes */
  67. intel_syntax, /* header: 23 bytes */
  68. att_syntax, /* header: 23 bytes */
  69. xml_syntax, /* header: 679 bytes */
  70. raw_syntax /* header: 172 bytes */
  71. };
  72. /* 'arg' is optional arbitrary data provided by the code passing the
  73. * callback -- for example, it could be 'this' or 'self' in OOP code.
  74. * 'code' is provided by libdisasm, it is one of the above
  75. * 'data' is provided by libdisasm and is context-specific, per the enums */
  76. typedef void (*DISASM_REPORTER)( enum x86_report_codes code,
  77. void *data, void *arg );
  78. /* ========================================= Libdisasm Management Routines */
  79. enum x86_options { /* these can be ORed together */
  80. opt_none= 0,
  81. opt_ignore_nulls=1, /* ignore sequences of > 4 NULL bytes */
  82. opt_16_bit=2, /* 16-bit/DOS disassembly */
  83. opt_att_mnemonics=4 /* use AT&T syntax names for alternate opcode mnemonics */
  84. };
  85. /* ========================================= Instruction Representation */
  86. /* these defines are only intended for use in the array decl's */
  87. #define MAX_REGNAME 8
  88. #define MAX_PREFIX_STR 32
  89. #define MAX_MNEM_STR 16
  90. #define MAX_INSN_SIZE 20 /* same as in i386.h */
  91. #define MAX_OP_STRING 32 /* max possible operand size in string form */
  92. #define MAX_OP_RAW_STRING 64 /* max possible operand size in raw form */
  93. #define MAX_OP_XML_STRING 256 /* max possible operand size in xml form */
  94. #define MAX_NUM_OPERANDS 8 /* max # implicit and explicit operands */
  95. /* in these, the '2 *' is arbitrary: the max # of operands should require
  96. * more space than the rest of the insn */
  97. #define MAX_INSN_STRING 512 /* 2 * 8 * MAX_OP_STRING */
  98. #define MAX_INSN_RAW_STRING 1024 /* 2 * 8 * MAX_OP_RAW_STRING */
  99. #define MAX_INSN_XML_STRING 4096 /* 2 * 8 * MAX_OP_XML_STRING */
  100. enum x86_reg_type { /* NOTE: these may be ORed together */
  101. reg_undef = 0x00000, // used only in ia32_reg_table initializater
  102. reg_gen = 0x00001, /* general purpose */
  103. reg_in = 0x00002, /* incoming args, ala RISC */
  104. reg_out = 0x00004, /* args to calls, ala RISC */
  105. reg_local = 0x00008, /* local vars, ala RISC */
  106. reg_fpu = 0x00010, /* FPU data register */
  107. reg_seg = 0x00020, /* segment register */
  108. reg_simd = 0x00040, /* SIMD/MMX reg */
  109. reg_sys = 0x00080, /* restricted/system register */
  110. reg_sp = 0x00100, /* stack pointer */
  111. reg_fp = 0x00200, /* frame pointer */
  112. reg_pc = 0x00400, /* program counter */
  113. reg_retaddr = 0x00800, /* return addr for func */
  114. reg_cond = 0x01000, /* condition code / flags */
  115. reg_zero = 0x02000, /* zero register, ala RISC */
  116. reg_ret = 0x04000, /* return value */
  117. reg_src = 0x10000, /* array/rep source */
  118. reg_dest = 0x20000, /* array/rep destination */
  119. reg_count = 0x40000 /* array/rep/loop counter */
  120. };
  121. /* x86_reg_t : an X86 CPU register */
  122. struct x86_reg_t {
  123. char name[MAX_REGNAME];
  124. enum x86_reg_type type; /* what register is used for */
  125. unsigned int size; /* size of register in bytes */
  126. unsigned int id; /* register ID #, for quick compares */
  127. unsigned int alias; /* ID of reg this is an alias for */
  128. unsigned int shift; /* amount to shift aliased reg by */
  129. x86_reg_t * aliased_reg( ) {
  130. x86_reg_t * reg = (x86_reg_t * )calloc( sizeof(x86_reg_t), 1 );
  131. reg->x86_reg_from_id( id );
  132. return reg;
  133. }
  134. void x86_reg_from_id( unsigned int _id);
  135. };
  136. /* x86_ea_t : an X86 effective address (address expression) */
  137. typedef struct {
  138. unsigned int scale; /* scale factor */
  139. x86_reg_t index, base; /* index, base registers */
  140. int32_t disp; /* displacement */
  141. char disp_sign; /* is negative? 1/0 */
  142. char disp_size; /* 0, 1, 2, 4 */
  143. } x86_ea_t;
  144. /* x86_absolute_t : an X86 segment:offset address (descriptor) */
  145. typedef struct {
  146. unsigned short segment; /* loaded directly into CS */
  147. union {
  148. unsigned short off16; /* loaded directly into IP */
  149. uint32_t off32; /* loaded directly into EIP */
  150. } offset;
  151. } x86_absolute_t;
  152. enum x86_op_type { /* mutually exclusive */
  153. op_unused = 0, /* empty/unused operand: should never occur */
  154. op_register = 1, /* CPU register */
  155. op_immediate = 2, /* Immediate Value */
  156. op_relative_near = 3, /* Relative offset from IP */
  157. op_relative_far = 4, /* Relative offset from IP */
  158. op_absolute = 5, /* Absolute address (ptr16:32) */
  159. op_expression = 6, /* Address expression (scale/index/base/disp) */
  160. op_offset = 7, /* Offset from start of segment (m32) */
  161. op_unknown
  162. };
  163. #define x86_optype_is_address( optype ) \
  164. ( optype == op_absolute || optype == op_offset )
  165. #define x86_optype_is_relative( optype ) \
  166. ( optype == op_relative_near || optype == op_relative_far )
  167. #define x86_optype_is_memory( optype ) \
  168. ( optype > op_immediate && optype < op_unknown )
  169. enum x86_op_datatype { /* these use Intel's lame terminology */
  170. op_byte = 1, /* 1 byte integer */
  171. op_word = 2, /* 2 byte integer */
  172. op_dword = 3, /* 4 byte integer */
  173. op_qword = 4, /* 8 byte integer */
  174. op_dqword = 5, /* 16 byte integer */
  175. op_sreal = 6, /* 4 byte real (single real) */
  176. op_dreal = 7, /* 8 byte real (double real) */
  177. op_extreal = 8, /* 10 byte real (extended real) */
  178. op_bcd = 9, /* 10 byte binary-coded decimal */
  179. op_ssimd = 10, /* 16 byte : 4 packed single FP (SIMD, MMX) */
  180. op_dsimd = 11, /* 16 byte : 2 packed double FP (SIMD, MMX) */
  181. op_sssimd = 12, /* 4 byte : scalar single FP (SIMD, MMX) */
  182. op_sdsimd = 13, /* 8 byte : scalar double FP (SIMD, MMX) */
  183. op_descr32 = 14, /* 6 byte Intel descriptor 2:4 */
  184. op_descr16 = 15, /* 4 byte Intel descriptor 2:2 */
  185. op_pdescr32 = 16, /* 6 byte Intel pseudo-descriptor 32:16 */
  186. op_pdescr16 = 17, /* 6 byte Intel pseudo-descriptor 8:24:16 */
  187. op_bounds16 = 18, /* signed 16:16 lower:upper bounds */
  188. op_bounds32 = 19, /* signed 32:32 lower:upper bounds */
  189. op_fpuenv16 = 20, /* 14 byte FPU control/environment data */
  190. op_fpuenv32 = 21, /* 28 byte FPU control/environment data */
  191. op_fpustate16 = 22, /* 94 byte FPU state (env & reg stack) */
  192. op_fpustate32 = 23, /* 108 byte FPU state (env & reg stack) */
  193. op_fpregset = 24, /* 512 bytes: register set */
  194. op_fpreg = 25, /* FPU register */
  195. op_none = 0xFF /* operand without a datatype (INVLPG) */
  196. };
  197. enum x86_op_access { /* ORed together */
  198. op_read = 1,
  199. op_write = 2,
  200. op_execute = 4
  201. };
  202. struct x86_op_flags { /* ORed together, but segs are mutually exclusive */
  203. union {
  204. unsigned int op_signed:1, /* signed integer */
  205. op_string:1,// = 2, /* possible string or array */
  206. op_constant:1,// = 4, /* symbolic constant */
  207. op_pointer:1,// = 8, /* operand points to a memory address */
  208. op_sysref:1,// = 0x010, /* operand is a syscall number */
  209. op_implied:1,// = 0x020, /* operand is implicit in the insn */
  210. op_hardcode:1,// = 0x40, /* operand is hardcoded in insn definition */
  211. /* NOTE: an 'implied' operand is one which can be considered a side
  212. * effect of the insn, e.g. %esp being modified by PUSH or POP. A
  213. * 'hard-coded' operand is one which is specified in the instruction
  214. * definition, e.g. %es:%edi in MOVSB or 1 in ROL Eb, 1. The difference
  215. * is that hard-coded operands are printed by disassemblers and are
  216. * required to re-assemble, while implicit operands are invisible. */
  217. op_seg : 3;
  218. unsigned int whole;
  219. };
  220. enum {
  221. op_es_seg = 0x100, /* ES segment override */
  222. op_cs_seg = 0x200, /* CS segment override */
  223. op_ss_seg = 0x300, /* SS segment override */
  224. op_ds_seg = 0x400, /* DS segment override */
  225. op_fs_seg = 0x500, /* FS segment override */
  226. op_gs_seg = 0x600 /* GS segment override */
  227. };
  228. };
  229. /* x86_op_t : an X86 instruction operand */
  230. struct x86_op_t{
  231. friend struct x86_insn_t;
  232. enum x86_op_type type; /* operand type */
  233. enum x86_op_datatype datatype; /* operand size */
  234. enum x86_op_access access; /* operand access [RWX] */
  235. x86_op_flags flags; /* misc flags */
  236. union {
  237. /* sizeof will have to work on these union members! */
  238. /* immediate values */
  239. char sbyte;
  240. short sword;
  241. int32_t sdword;
  242. qword_t sqword;
  243. unsigned char byte;
  244. unsigned short word;
  245. uint32_t dword;
  246. qword_t qword;
  247. float sreal;
  248. double dreal;
  249. /* misc large/non-native types */
  250. unsigned char extreal[10];
  251. unsigned char bcd[10];
  252. qword_t dqword[2];
  253. unsigned char simd[16];
  254. unsigned char fpuenv[28];
  255. /* offset from segment */
  256. uint32_t offset;
  257. /* ID of CPU register */
  258. x86_reg_t reg;
  259. /* offsets from current insn */
  260. char relative_near;
  261. int32_t relative_far;
  262. /* segment:offset */
  263. x86_absolute_t absolute;
  264. /* effective address [expression] */
  265. x86_ea_t expression;
  266. } data;
  267. /* this is needed to make formatting operands more sane */
  268. void * insn; /* pointer to x86_insn_t owning operand */
  269. size_t size()
  270. {
  271. return operand_size();
  272. }
  273. /* get size of operand data in bytes */
  274. size_t operand_size();
  275. /* format (sprintf) an operand into 'buf' using specified syntax */
  276. int x86_format_operand(char *buf, int len, enum x86_asm_format format );
  277. bool is_address( ) {
  278. return ( type == op_absolute || type == op_offset );
  279. }
  280. bool is_relative( ) {
  281. return ( type == op_relative_near || type == op_relative_far );
  282. }
  283. int32_t getAddress()
  284. {
  285. assert(is_address()||is_relative());
  286. switch(type)
  287. {
  288. case op_absolute:
  289. {
  290. if(datatype==op_descr16)
  291. return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off16;
  292. else
  293. return (int32_t(data.absolute.segment)<<4) + data.absolute.offset.off32;
  294. }
  295. case op_offset:
  296. return data.offset;
  297. case op_relative_near:
  298. return data.relative_near;
  299. case op_relative_far:
  300. return data.relative_far;
  301. default:
  302. assert(false);
  303. return ~0;
  304. }
  305. }
  306. char * format( enum x86_asm_format format );
  307. x86_op_t * copy()
  308. {
  309. x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
  310. if ( op ) {
  311. memcpy( op, this, sizeof(x86_op_t) );
  312. }
  313. return op;
  314. }
  315. int32_t long_from_operand();
  316. private:
  317. };
  318. /* Linked list of x86_op_t; provided for manual traversal of the operand
  319. * list in an insn. Users wishing to add operands to this list, e.g. to add
  320. * implicit operands, should use x86_operand_new in x86_operand_list.h */
  321. struct x86_oplist_t {
  322. x86_op_t op;
  323. struct x86_oplist_t *next;
  324. };
  325. enum x86_insn_type {
  326. insn_invalid = 0, /* invalid instruction */
  327. /* insn_controlflow */
  328. insn_jmp = 0x1001,
  329. insn_jcc = 0x1002,
  330. insn_call = 0x1003,
  331. insn_callcc = 0x1004,
  332. insn_return = 0x1005,
  333. /* insn_arithmetic */
  334. insn_add = 0x2001,
  335. insn_sub = 0x2002,
  336. insn_mul = 0x2003,
  337. insn_div = 0x2004,
  338. insn_inc = 0x2005,
  339. insn_dec = 0x2006,
  340. insn_shl = 0x2007,
  341. insn_shr = 0x2008,
  342. insn_rol = 0x2009,
  343. insn_ror = 0x200A,
  344. /* insn_logic */
  345. insn_and = 0x3001,
  346. insn_or = 0x3002,
  347. insn_xor = 0x3003,
  348. insn_not = 0x3004,
  349. insn_neg = 0x3005,
  350. /* insn_stack */
  351. insn_push = 0x4001,
  352. insn_pop = 0x4002,
  353. insn_pushregs = 0x4003,
  354. insn_popregs = 0x4004,
  355. insn_pushflags = 0x4005,
  356. insn_popflags = 0x4006,
  357. insn_enter = 0x4007,
  358. insn_leave = 0x4008,
  359. /* insn_comparison */
  360. insn_test = 0x5001,
  361. insn_cmp = 0x5002,
  362. /* insn_move */
  363. insn_mov = 0x6001, /* move */
  364. insn_movcc = 0x6002, /* conditional move */
  365. insn_xchg = 0x6003, /* exchange */
  366. insn_xchgcc = 0x6004, /* conditional exchange */
  367. /* insn_string */
  368. insn_strcmp = 0x7001,
  369. insn_strload = 0x7002,
  370. insn_strmov = 0x7003,
  371. insn_strstore = 0x7004,
  372. insn_translate = 0x7005, /* xlat */
  373. /* insn_bit_manip */
  374. insn_bittest = 0x8001,
  375. insn_bitset = 0x8002,
  376. insn_bitclear = 0x8003,
  377. /* insn_flag_manip */
  378. insn_clear_carry = 0x9001,
  379. insn_clear_zero = 0x9002,
  380. insn_clear_oflow = 0x9003,
  381. insn_clear_dir = 0x9004,
  382. insn_clear_sign = 0x9005,
  383. insn_clear_parity = 0x9006,
  384. insn_set_carry = 0x9007,
  385. insn_set_zero = 0x9008,
  386. insn_set_oflow = 0x9009,
  387. insn_set_dir = 0x900A,
  388. insn_set_sign = 0x900B,
  389. insn_set_parity = 0x900C,
  390. insn_tog_carry = 0x9010,
  391. insn_tog_zero = 0x9020,
  392. insn_tog_oflow = 0x9030,
  393. insn_tog_dir = 0x9040,
  394. insn_tog_sign = 0x9050,
  395. insn_tog_parity = 0x9060,
  396. /* insn_fpu */
  397. insn_fmov = 0xA001,
  398. insn_fmovcc = 0xA002,
  399. insn_fneg = 0xA003,
  400. insn_fabs = 0xA004,
  401. insn_fadd = 0xA005,
  402. insn_fsub = 0xA006,
  403. insn_fmul = 0xA007,
  404. insn_fdiv = 0xA008,
  405. insn_fsqrt = 0xA009,
  406. insn_fcmp = 0xA00A,
  407. insn_fcos = 0xA00C,
  408. insn_fldpi = 0xA00D,
  409. insn_fldz = 0xA00E,
  410. insn_ftan = 0xA00F,
  411. insn_fsine = 0xA010,
  412. insn_fsys = 0xA020,
  413. /* insn_interrupt */
  414. insn_int = 0xD001,
  415. insn_intcc = 0xD002, /* not present in x86 ISA */
  416. insn_iret = 0xD003,
  417. insn_bound = 0xD004,
  418. insn_debug = 0xD005,
  419. insn_trace = 0xD006,
  420. insn_invalid_op = 0xD007,
  421. insn_oflow = 0xD008,
  422. /* insn_system */
  423. insn_halt = 0xE001,
  424. insn_in = 0xE002, /* input from port/bus */
  425. insn_out = 0xE003, /* output to port/bus */
  426. insn_cpuid = 0xE004,
  427. insn_lmsw = 0xE005,
  428. insn_smsw = 0xE006,
  429. insn_clts = 0xE007,
  430. /* insn_other */
  431. insn_nop = 0xF001,
  432. insn_bcdconv = 0xF002, /* convert to or from BCD */
  433. insn_szconv = 0xF003 /* change size of operand */
  434. };
  435. /* These flags specify special characteristics of the instruction, such as
  436. * whether the inatruction is privileged or whether it serializes the
  437. * pipeline.
  438. * NOTE : These may not be accurate for all instructions; updates to the
  439. * opcode tables have not been completed. */
  440. enum x86_insn_note {
  441. insn_note_ring0 = 1, /* Only available in ring 0 */
  442. insn_note_smm = 2, /* "" in System Management Mode */
  443. insn_note_serial = 4, /* Serializing instruction */
  444. insn_note_nonswap = 8, /* Does not swap arguments in att-style formatting */
  445. insn_note_nosuffix = 16 /* Does not have size suffix in att-style formatting */
  446. };
  447. /* This specifies what effects the instruction has on the %eflags register */
  448. enum x86_eflags
  449. {
  450. insn_eflag_carry,
  451. insn_eflag_zero,
  452. insn_eflag_overflow,
  453. insn_eflag_direction,
  454. insn_eflag_sign,
  455. insn_eflag_parity
  456. };
  457. enum x86_flag_status {
  458. insn_carry_set = 0x1, /* CF */
  459. insn_zero_set = 0x2, /* ZF */
  460. insn_oflow_set = 0x4, /* OF */
  461. insn_dir_set = 0x8, /* DF */
  462. insn_sign_set = 0x10, /* SF */
  463. insn_parity_set = 0x20, /* PF */
  464. insn_carry_or_zero_set = 0x40,
  465. insn_zero_set_or_sign_ne_oflow = 0x80,
  466. insn_carry_clear = 0x100,
  467. insn_zero_clear = 0x200,
  468. insn_oflow_clear = 0x400,
  469. insn_dir_clear = 0x800,
  470. insn_sign_clear = 0x1000,
  471. insn_parity_clear = 0x2000,
  472. insn_sign_eq_oflow = 0x4000,
  473. insn_sign_ne_oflow = 0x8000
  474. };
  475. /* The CPU model in which the insturction first appeared; this can be used
  476. * to mask out instructions appearing in earlier or later models or to
  477. * check the portability of a binary.
  478. * NOTE : These may not be accurate for all instructions; updates to the
  479. * opcode tables have not been completed. */
  480. enum x86_insn_cpu {
  481. cpu_8086 = 1, /* Intel */
  482. cpu_80286 = 2,
  483. cpu_80386 = 3,
  484. cpu_80387 = 4,
  485. cpu_80486 = 5,
  486. cpu_pentium = 6,
  487. cpu_pentiumpro = 7,
  488. cpu_pentium2 = 8,
  489. cpu_pentium3 = 9,
  490. cpu_pentium4 = 10,
  491. cpu_k6 = 16, /* AMD */
  492. cpu_k7 = 32,
  493. cpu_athlon = 48
  494. };
  495. /* CPU ISA subsets: These are derived from the Instruction Groups in
  496. * Intel Vol 1 Chapter 5; they represent subsets of the IA32 ISA but
  497. * do not reflect the 'type' of the instruction in the same way that
  498. * x86_insn_group does. In short, these are AMD/Intel's somewhat useless
  499. * designations.
  500. * NOTE : These may not be accurate for all instructions; updates to the
  501. * opcode tables have not been completed. */
  502. enum x86_insn_isa {
  503. isa_gp = 1, /* general purpose */
  504. isa_fp = 2, /* floating point */
  505. isa_fpumgt = 3, /* FPU/SIMD management */
  506. isa_mmx = 4, /* Intel MMX */
  507. isa_sse1 = 5, /* Intel SSE SIMD */
  508. isa_sse2 = 6, /* Intel SSE2 SIMD */
  509. isa_sse3 = 7, /* Intel SSE3 SIMD */
  510. isa_3dnow = 8, /* AMD 3DNow! SIMD */
  511. isa_sys = 9 /* system instructions */
  512. };
  513. enum x86_insn_prefix {
  514. insn_no_prefix = 0,
  515. insn_rep_zero = 1, /* REPZ and REPE */
  516. insn_rep_notzero = 2, /* REPNZ and REPNZ */
  517. insn_lock = 4 /* LOCK: */
  518. };
  519. /* TODO: maybe provide insn_new/free(), and have disasm return new insn_t */
  520. /* FOREACH types: these are used to limit the foreach results to
  521. * operands which match a certain "type" (implicit or explicit)
  522. * or which are accessed in certain ways (e.g. read or write). Note
  523. * that this operates on the operand list of single instruction, so
  524. * specifying the 'real' operand type (register, memory, etc) is not
  525. * useful. Note also that by definition Execute Access implies Read
  526. * Access and implies Not Write Access.
  527. * The "type" (implicit or explicit) and the access method can
  528. * be ORed together, e.g. op_wo | op_explicit */
  529. enum x86_op_foreach_type {
  530. op_any = 0, /* ALL operands (explicit, implicit, rwx) */
  531. op_dest = 1, /* operands with Write access */
  532. op_src = 2, /* operands with Read access */
  533. op_ro = 3, /* operands with Read but not Write access */
  534. op_wo = 4, /* operands with Write but not Read access */
  535. op_xo = 5, /* operands with Execute access */
  536. op_rw = 6, /* operands with Read AND Write access */
  537. op_implicit = 0x10, /* operands that are implied by the opcode */
  538. op_explicit = 0x20 /* operands that are not side-effects */
  539. };
  540. /* Operand FOREACH callback: 'arg' is an abritrary parameter passed to the
  541. * foreach routine, 'insn' is the x86_insn_t whose operands are being
  542. * iterated over, and 'op' is the current x86_op_t */
  543. struct x86_insn_t;
  544. struct ia32_insn_t;
  545. typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg);
  546. /* x86_insn_t : an X86 instruction */
  547. struct x86_insn_t {
  548. enum x86_insn_group {
  549. insn_none = 0, /* invalid instruction */
  550. insn_controlflow = 1,
  551. insn_arithmetic = 2,
  552. insn_logic = 3,
  553. insn_stack = 4,
  554. insn_comparison = 5,
  555. insn_move = 6,
  556. insn_string = 7,
  557. insn_bit_manip = 8,
  558. insn_flag_manip = 9,
  559. insn_fpu = 10,
  560. insn_interrupt = 13,
  561. insn_system = 14,
  562. insn_other = 15
  563. };
  564. private:
  565. void x86_oplist_append(x86_oplist_t *op);
  566. public:
  567. /* information about the instruction */
  568. uint32_t addr; /* load address */
  569. uint32_t offset; /* offset into file/buffer */
  570. x86_insn_group group; /* meta-type, e.g. INS_EXEC */
  571. x86_insn_type type; /* type, e.g. INS_BRANCH */
  572. x86_insn_note note; /* note, e.g. RING0 */
  573. unsigned char bytes[MAX_INSN_SIZE];
  574. unsigned char size; /* size of insn in bytes */
  575. /* 16/32-bit mode settings */
  576. unsigned char addr_size; /* default address size : 2 or 4 */
  577. unsigned char op_size; /* default operand size : 2 or 4 */
  578. /* CPU/instruction set */
  579. enum x86_insn_cpu cpu;
  580. enum x86_insn_isa isa;
  581. /* flags */
  582. enum x86_flag_status flags_set; /* flags set or tested by insn */
  583. enum x86_flag_status flags_tested;
  584. bool containsFlag(x86_eflags flg,x86_flag_status in);
  585. /* stack */
  586. unsigned char stack_mod; /* 0 or 1 : is the stack modified? */
  587. int32_t stack_mod_val; /* val stack is modified by if known */
  588. /* the instruction proper */
  589. enum x86_insn_prefix prefix; /* prefixes ORed together */
  590. char prefix_string[MAX_PREFIX_STR]; /* prefixes [might be truncated] */
  591. char mnemonic[MAX_MNEM_STR];
  592. x86_oplist_t *operands; /* list of explicit/implicit operands */
  593. size_t operand_count; /* total number of operands */
  594. size_t explicit_count; /* number of explicit operands */
  595. /* convenience fields for user */
  596. void *block; /* code block containing this insn */
  597. void *function; /* function containing this insn */
  598. int tag; /* tag the insn as seen/processed */
  599. x86_op_t *x86_operand_new();
  600. /* convenience routine: returns count of operands matching 'type' */
  601. size_t x86_operand_count( enum x86_op_foreach_type type );
  602. /* accessor functions for the operands */
  603. x86_op_t * x86_operand_1st( );
  604. x86_op_t * x86_operand_2nd( );
  605. x86_op_t * x86_operand_3rd( );
  606. x86_op_t * get_dest();
  607. int32_t x86_get_rel_offset( );
  608. x86_op_t * x86_get_branch_target( );
  609. x86_op_t * x86_get_imm( );
  610. /* More accessor fuctions, this time for user-defined info... */
  611. uint8_t * x86_get_raw_imm( );
  612. /* set the address (usually RVA) of the insn */
  613. void x86_set_insn_addr( uint32_t addr );
  614. /* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
  615. int x86_format_mnemonic( char *buf, int len, enum x86_asm_format format);
  616. int x86_format_insn( char *buf, int len, enum x86_asm_format);
  617. void x86_oplist_free( );
  618. /* returns 0 if an instruction is invalid, 1 if valid */
  619. bool is_valid( );
  620. uint32_t x86_get_address( );
  621. void make_invalid(unsigned char *buf);
  622. /* instruction tagging: these routines allow the programmer to mark
  623. * instructions as "seen" in a DFS, for example. libdisasm does not use
  624. * the tag field.*/
  625. /* set insn->tag to 1 */
  626. void x86_tag_insn( );
  627. /* return insn->tag */
  628. int x86_insn_is_tagged();
  629. /* set insn->tag to 0 */
  630. void x86_untag_insn();
  631. /* Operand foreach: invokes 'func' with 'insn' and 'arg' as arguments. The
  632. * 'type' parameter is used to select only operands matching specific
  633. * criteria. */
  634. int x86_operand_foreach( x86_operand_fn func, void *arg, enum x86_op_foreach_type type );
  635. /* set the offset (usually offset into file) of the insn */
  636. void x86_set_insn_offset( unsigned int offset );
  637. /* set a pointer to the function owning the instruction. The
  638. * type of 'func' is user-defined; libdisasm does not use the func field. */
  639. void x86_set_insn_function( void * func );
  640. /* set a pointer to the block of code owning the instruction. The
  641. * type of 'block' is user-defined; libdisasm does not use the block field. */
  642. void x86_set_insn_block( void * block );
  643. private:
  644. };
  645. class Ia32_Decoder
  646. {
  647. x86_insn_t *m_decoded;
  648. void handle_insn_metadata( ia32_insn_t *raw_insn );
  649. void ia32_stack_mod();
  650. void ia32_handle_cpu( unsigned int cpu );
  651. void ia32_handle_mnemtype(unsigned int mnemtype);
  652. void ia32_handle_notes(unsigned int notes);
  653. void ia32_handle_eflags( unsigned int eflags);
  654. void ia32_handle_prefix( unsigned int prefixes );
  655. size_t ia32_decode_insn( unsigned char *buf, size_t buf_len, ia32_insn_t *raw_insn, unsigned int prefixes );
  656. size_t ia32_decode_operand( unsigned char *buf, size_t buf_len, unsigned int raw_op, unsigned int raw_flags, unsigned int prefixes, unsigned char modrm );
  657. size_t decode_operand_size( unsigned int op_type, x86_op_t *op );
  658. size_t decode_operand_value( unsigned char *buf, size_t buf_len, x86_op_t *op, unsigned int addr_meth, size_t op_size, unsigned int op_value, unsigned char modrm, size_t gen_regs );
  659. size_t ia32_modrm_decode( unsigned char *buf, unsigned int buf_len, x86_op_t *op, size_t gen_regs );
  660. unsigned int ia32_insn_implicit_ops( unsigned int impl_idx );
  661. size_t handle_insn_suffix( unsigned char *buf, size_t buf_len, ia32_insn_t *raw_insn );
  662. public:
  663. size_t ia32_disasm_addr( unsigned char * buf, size_t buf_len);
  664. void decode_into(x86_insn_t *ins) {m_decoded=ins;}
  665. };
  666. /* DISASSEMBLY ROUTINES
  667. * Canonical order of arguments is
  668. * (buf, buf_len, buf_rva, offset, len, insn, func, arg, resolve_func)
  669. * ...but of course all of these are not used at the same time.
  670. */
  671. class X86_Disasm
  672. {
  673. public:
  674. /* Function prototype for caller-supplied callback routine
  675. * These callbacks are intended to process 'insn' further, e.g. by
  676. * adding it to a linked list, database, etc */
  677. typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg );
  678. /* Function prototype for caller-supplied address resolver.
  679. * This routine is used to determine the rva to disassemble next, given
  680. * the 'dest' operand of a jump/call. This allows the caller to resolve
  681. * jump/call targets stored in a register or on the stack, and also allows
  682. * the caller to prevent endless loops by checking if an address has
  683. * already been disassembled. If an address cannot be resolved from the
  684. * operand, or if the address has already been disassembled, this routine
  685. * should return -1; in all other cases the RVA to be disassembled next
  686. * should be returned. */
  687. typedef int32_t (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn,
  688. void *arg );
  689. protected:
  690. DISASM_REPORTER __x86_reporter_func;
  691. void * __x86_reporter_arg;
  692. Ia32_Decoder m_decoder;
  693. public:
  694. X86_Disasm( x86_options options=opt_none,DISASM_REPORTER reporter=0, void *arg=0 ) :
  695. __x86_reporter_func(reporter),
  696. __x86_reporter_arg(arg) {
  697. x86_init( options,reporter,arg);
  698. }
  699. /* management routines */
  700. /* 'arg' is caller-specific data which is passed as the first argument
  701. * to the reporter callback routine */
  702. int x86_init( x86_options options, DISASM_REPORTER reporter, void *arg);
  703. void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
  704. void x86_set_options( x86_options options );
  705. x86_options x86_get_options( void );
  706. int x86_cleanup(void);
  707. /* x86_disasm: Disassemble a single instruction from a buffer of bytes.
  708. * Returns size of instruction in bytes.
  709. * Caller is responsible for calling x86_oplist_free() on
  710. * a reused "insn" to avoid leaking memory when calling this
  711. * function repeatedly.
  712. * buf : Buffer of bytes to disassemble
  713. * buf_len : Length of the buffer
  714. * buf_rva : Load address of the start of the buffer
  715. * offset : Offset in buffer to disassemble
  716. * insn : Structure to fill with disassembled instruction
  717. */
  718. unsigned int x86_disasm(const unsigned char *buf, unsigned int buf_len,
  719. uint32_t buf_rva, unsigned int offset,
  720. x86_insn_t * insn );
  721. /* x86_disasm_range: Sequential disassembly of a range of bytes in a buffer,
  722. * invoking a callback function each time an instruction
  723. * is successfully disassembled. The 'range' refers to the
  724. * bytes between 'offset' and 'offset + len' in the buffer;
  725. * 'len' is assumed to be less than the length of the buffer.
  726. * Returns number of instructions processed.
  727. * buf : Buffer of bytes to disassemble (e.g. .text section)
  728. * buf_rva : Load address of buffer (e.g. ELF Virtual Address)
  729. * offset : Offset in buffer to start disassembly at
  730. * len : Number of bytes to disassemble
  731. * func : Callback function to invoke (may be NULL)
  732. * arg : Arbitrary data to pass to callback (may be NULL)
  733. */
  734. unsigned int x86_disasm_range( unsigned char *buf, uint32_t buf_rva,
  735. unsigned int offset, unsigned int len,
  736. DISASM_CALLBACK func, void *arg );
  737. /* x86_disasm_forward: Flow-of-execution disassembly of the bytes in a buffer,
  738. * invoking a callback function each time an instruction
  739. * is successfully disassembled.
  740. * buf : Buffer to disassemble (e.g. .text section)
  741. * buf_len : Number of bytes in buffer
  742. * buf_rva : Load address of buffer (e.g. ELF Virtual Address)
  743. * offset : Offset in buffer to start disassembly at (e.g. entry point)
  744. * func : Callback function to invoke (may be NULL)
  745. * arg : Arbitrary data to pass to callback (may be NULL)
  746. * resolver: Caller-supplied address resolver. If no resolver is
  747. * supplied, a default internal one is used -- however the
  748. * internal resolver does NOT catch loops and could end up
  749. * disassembling forever..
  750. * r_arg : Arbitrary data to pass to resolver (may be NULL)
  751. */
  752. unsigned int x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
  753. uint32_t buf_rva, unsigned int offset,
  754. DISASM_CALLBACK func, void *arg,
  755. DISASM_RESOLVER resolver, void *r_arg );
  756. /* Call the register reporter to report an error */
  757. void x86_report_error( enum x86_report_codes code, void *data );
  758. /* fill 'buf' with a description of the format's syntax */
  759. int x86_format_header( char *buf, int len, enum x86_asm_format format);
  760. /* Endianness of an x86 CPU : 0 is big, 1 is little; always returns 1 */
  761. unsigned int x86_endian(void);
  762. /* Default address and operand size in bytes */
  763. unsigned int x86_addr_size(void);
  764. unsigned int x86_op_size(void);
  765. /* Size of a machine word in bytes */
  766. unsigned int x86_word_size(void);
  767. /* maximum size of a code instruction */
  768. unsigned int x86_max_insn_size(void);
  769. /* register IDs of Stack, Frame, Instruction pointer and Flags register */
  770. unsigned int x86_sp_reg(void);
  771. unsigned int x86_fp_reg(void);
  772. unsigned int x86_ip_reg(void);
  773. unsigned int x86_flag_reg(void);
  774. };
  775. /* Instruction operands: these are stored as a list of explicit and
  776. * implicit operands. It is recommended that the 'foreach' routines
  777. * be used to when examining operands for purposes of data flow analysis */
  778. /* Operand Convenience Routines: the following three routines are common
  779. * operations on operands, intended to ease the burden of the programmer. */
  780. /* format (sprintf) an instruction mnemonic into 'buf' using specified syntax */
  781. //int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
  782. // enum x86_asm_format format);
  783. /* fill 'reg' struct with details of register 'id' */
  784. //void x86_reg_from_id( unsigned int id, x86_reg_t * reg );
  785. /* convenience macro demonstrating how to get an aliased register; proto is
  786. * void x86_get_aliased_reg( x86_reg_t *alias_reg, x86_reg_t *output_reg )
  787. * where 'alias_reg' is a reg operand and 'output_reg' is filled with the
  788. * register that the operand is an alias for */
  789. //#define x86_get_aliased_reg( alias_reg, output_reg )
  790. // x86_reg_from_id( alias_reg->alias, output_reg )
  791. /* ================================== Invariant Instruction Representation */
  792. /* Invariant instructions are used for generating binary signatures;
  793. * the instruction is modified so that all variant bytes in an instruction
  794. * are replaced with a wildcard byte.
  795. *
  796. * A 'variant byte' is one that is expected to be modified by either the
  797. * static or the dynamic linker: for example, an address encoded in an
  798. * instruction.
  799. *
  800. * By comparing the invariant representation of one instruction [or of a
  801. * sequence of instructions] with the invariant representation of another,
  802. * one determine whether the two invariant representations are from the same
  803. * relocatable object [.o] file. Thus one can use binary signatures [which
  804. * are just sequences of invariant instruction representations] to look for
  805. * library routines which have been statically-linked into a binary.
  806. *
  807. * The invariant routines are faster and smaller than the disassembly
  808. * routines; they can be used to determine the size of an instruction
  809. * without all of the overhead of a full instruction disassembly.
  810. */
  811. /* This byte is used to replace variant bytes */
  812. #define X86_WILDCARD_BYTE 0xF4
  813. struct x86_invariant_op_t{
  814. enum x86_op_type type; /* operand type */
  815. enum x86_op_datatype datatype; /* operand size */
  816. enum x86_op_access access; /* operand access [RWX] */
  817. x86_op_flags flags; /* misc flags */
  818. };
  819. struct x86_invariant_t {
  820. unsigned char bytes[64]; /* invariant representation */
  821. unsigned int size; /* number of bytes in insn */
  822. x86_insn_t::x86_insn_group group; /* meta-type, e.g. INS_EXEC */
  823. enum x86_insn_type type; /* type, e.g. INS_BRANCH */
  824. x86_invariant_op_t operands[3]; /* operands: dest, src, imm */
  825. } ;
  826. /* return a version of the instruction with the variant bytes masked out */
  827. size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
  828. x86_invariant_t *inv );
  829. /* return the size in bytes of the intruction pointed to by 'buf';
  830. * this used x86_invariant_disasm since it faster than x86_disasm */
  831. size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );
  832. #ifdef __cplusplus
  833. //}
  834. #endif
  835. #endif