12b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <stdio.h> 22b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include <stdlib.h> 32b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 42b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#include "libdis.h" 52b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 62b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#ifdef _MSC_VER 72b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org #define snprintf _snprintf 82b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org #define inline __inline 92b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#endif 102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_insn_is_valid( x86_insn_t *insn ) { 122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn && insn->type != insn_invalid && insn->size > 0 ) { 132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 1; 142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orguint32_t x86_get_address( x86_insn_t *insn ) { 202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_oplist_t *op_lst; 212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! insn || ! insn->operands ) { 222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_lst->op.type == op_offset ) { 272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return op_lst->op.data.offset; 282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else if ( op_lst->op.type == op_absolute ) { 292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_lst->op.datatype == op_descr16 ) { 302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return (uint32_t) 312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op_lst->op.data.absolute.offset.off16; 322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return op_lst->op.data.absolute.offset.off32; 342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint32_t x86_get_rel_offset( x86_insn_t *insn ) { 412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_oplist_t *op_lst; 422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! insn || ! insn->operands ) { 432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_lst->op.type == op_relative_near ) { 482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return (int32_t) op_lst->op.data.relative_near; 492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else if ( op_lst->op.type == op_relative_far ) { 502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return op_lst->op.data.relative_far; 512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return 0; 552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_get_branch_target( x86_insn_t *insn ) { 582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_oplist_t *op_lst; 592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! insn || ! insn->operands ) { 602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return NULL; 612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_lst->op.access & op_execute ) { 652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return &(op_lst->op); 662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return NULL; 702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgx86_op_t * x86_get_imm( x86_insn_t *insn ) { 722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_oplist_t *op_lst; 732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! insn || ! insn->operands ) { 742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return NULL; 752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( op_lst->op.type == op_immediate ) { 792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return &(op_lst->op); 802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 832b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return NULL; 842b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 852b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 862b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org#define IS_PROPER_IMM( x ) \ 872b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x->op.type == op_immediate && ! (x->op.flags & op_hardcode) 882b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 892b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 902b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org/* if there is an immediate value in the instruction, return a pointer to 912b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org * it */ 922b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned char * x86_get_raw_imm( x86_insn_t *insn ) { 932b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org int size, offset; 942b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org x86_op_t *op = NULL; 952b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 962b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! insn || ! insn->operands ) { 972b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return(NULL); 982b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 992b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1002b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* a bit inelegant, but oh well... */ 1012b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( IS_PROPER_IMM( insn->operands ) ) { 1022b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op = &insn->operands->op; 1032b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else if ( insn->operands->next ) { 1042b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( IS_PROPER_IMM( insn->operands->next ) ) { 1052b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op = &insn->operands->next->op; 1062b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } else if ( insn->operands->next->next && 1072b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org IS_PROPER_IMM( insn->operands->next->next ) ) { 1082b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org op = &insn->operands->next->next->op; 1092b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1102b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1112b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1122b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if (! op ) { 1132b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return( NULL ); 1142b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1152b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1162b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org /* immediate data is at the end of the insn */ 1172b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org size = x86_operand_size( op ); 1182b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org offset = insn->size - size; 1192b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return( &insn->bytes[offset] ); 1202b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1212b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1222b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1232b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgunsigned int x86_operand_size( x86_op_t *op ) { 1242b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org switch (op->datatype ) { 1252b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_byte: return 1; 1262b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_word: return 2; 1272b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_dword: return 4; 1282b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_qword: return 8; 1292b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_dqword: return 16; 1302b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_sreal: return 4; 1312b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_dreal: return 8; 1322b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_extreal: return 10; 1332b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_bcd: return 10; 1342b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_ssimd: return 16; 1352b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_dsimd: return 16; 1362b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_sssimd: return 4; 1372b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_sdsimd: return 8; 1382b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_descr32: return 6; 1392b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_descr16: return 4; 1402b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_pdescr32: return 6; 1412b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_pdescr16: return 6; 1422b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_bounds16: return 4; 1432b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_bounds32: return 8; 1442b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpuenv16: return 14; 1452b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpuenv32: return 28; 1462b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpustate16: return 94; 1472b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpustate32: return 108; 1482b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpregset: return 512; 1492b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_fpreg: return 10; 1502b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org case op_none: return 0; 1512b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org } 1522b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return(4); /* default size */ 1532b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1542b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1552b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) { 1562b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->addr = addr; 1572b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1582b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1592b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){ 1602b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->offset = offset; 1612b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1622b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1632b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_function( x86_insn_t *insn, void * func ){ 1642b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->function = func; 1652b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1662b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1672b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_set_insn_block( x86_insn_t *insn, void * block ){ 1682b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->block = block; 1692b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1702b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1712b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_tag_insn( x86_insn_t *insn ){ 1722b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->tag = 1; 1732b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1742b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1752b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgvoid x86_untag_insn( x86_insn_t *insn ){ 1762b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org if ( insn ) insn->tag = 0; 1772b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1782b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 1792b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.orgint x86_insn_is_tagged( x86_insn_t *insn ){ 1802b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org return insn->tag; 1812b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org} 1822b4274afc4fae883d1251a7a420e24fd526a9f16cdn@chromium.org 183