1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #include "libdis.h" 5 6 #ifdef _MSC_VER 7 #define snprintf _snprintf 8 #define inline __inline 9 #endif 10 11 int x86_insn_is_valid( x86_insn_t *insn ) { 12 if ( insn && insn->type != insn_invalid && insn->size > 0 ) { 13 return 1; 14 } 15 16 return 0; 17 } 18 19 uint32_t x86_get_address( x86_insn_t *insn ) { 20 x86_oplist_t *op_lst; 21 if (! insn || ! insn->operands ) { 22 return 0; 23 } 24 25 for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 26 if ( op_lst->op.type == op_offset ) { 27 return op_lst->op.data.offset; 28 } else if ( op_lst->op.type == op_absolute ) { 29 if ( op_lst->op.datatype == op_descr16 ) { 30 return (uint32_t) 31 op_lst->op.data.absolute.offset.off16; 32 } 33 return op_lst->op.data.absolute.offset.off32; 34 } 35 } 36 37 return 0; 38 } 39 40 int32_t x86_get_rel_offset( x86_insn_t *insn ) { 41 x86_oplist_t *op_lst; 42 if (! insn || ! insn->operands ) { 43 return 0; 44 } 45 46 for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 47 if ( op_lst->op.type == op_relative_near ) { 48 return (int32_t) op_lst->op.data.relative_near; 49 } else if ( op_lst->op.type == op_relative_far ) { 50 return op_lst->op.data.relative_far; 51 } 52 } 53 54 return 0; 55 } 56 57 x86_op_t * x86_get_branch_target( x86_insn_t *insn ) { 58 x86_oplist_t *op_lst; 59 if (! insn || ! insn->operands ) { 60 return NULL; 61 } 62 63 for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 64 if ( op_lst->op.access & op_execute ) { 65 return &(op_lst->op); 66 } 67 } 68 69 return NULL; 70 } 71 x86_op_t * x86_get_imm( x86_insn_t *insn ) { 72 x86_oplist_t *op_lst; 73 if (! insn || ! insn->operands ) { 74 return NULL; 75 } 76 77 for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) { 78 if ( op_lst->op.type == op_immediate ) { 79 return &(op_lst->op); 80 } 81 } 82 83 return NULL; 84 } 85 86 #define IS_PROPER_IMM( x ) \ 87 x->op.type == op_immediate && ! (x->op.flags & op_hardcode) 88 89 90 /* if there is an immediate value in the instruction, return a pointer to 91 * it */ 92 unsigned char * x86_get_raw_imm( x86_insn_t *insn ) { 93 int size, offset; 94 x86_op_t *op = NULL; 95 96 if (! insn || ! insn->operands ) { 97 return(NULL); 98 } 99 100 /* a bit inelegant, but oh well... */ 101 if ( IS_PROPER_IMM( insn->operands ) ) { 102 op = &insn->operands->op; 103 } else if ( insn->operands->next ) { 104 if ( IS_PROPER_IMM( insn->operands->next ) ) { 105 op = &insn->operands->next->op; 106 } else if ( insn->operands->next->next && 107 IS_PROPER_IMM( insn->operands->next->next ) ) { 108 op = &insn->operands->next->next->op; 109 } 110 } 111 112 if (! op ) { 113 return( NULL ); 114 } 115 116 /* immediate data is at the end of the insn */ 117 size = x86_operand_size( op ); 118 offset = insn->size - size; 119 return( &insn->bytes[offset] ); 120 } 121 122 123 unsigned int x86_operand_size( x86_op_t *op ) { 124 switch (op->datatype ) { 125 case op_byte: return 1; 126 case op_word: return 2; 127 case op_dword: return 4; 128 case op_qword: return 8; 129 case op_dqword: return 16; 130 case op_sreal: return 4; 131 case op_dreal: return 8; 132 case op_extreal: return 10; 133 case op_bcd: return 10; 134 case op_ssimd: return 16; 135 case op_dsimd: return 16; 136 case op_sssimd: return 4; 137 case op_sdsimd: return 8; 138 case op_descr32: return 6; 139 case op_descr16: return 4; 140 case op_pdescr32: return 6; 141 case op_pdescr16: return 6; 142 case op_bounds16: return 4; 143 case op_bounds32: return 8; 144 case op_fpuenv16: return 14; 145 case op_fpuenv32: return 28; 146 case op_fpustate16: return 94; 147 case op_fpustate32: return 108; 148 case op_fpregset: return 512; 149 case op_fpreg: return 10; 150 case op_none: return 0; 151 } 152 return(4); /* default size */ 153 } 154 155 void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) { 156 if ( insn ) insn->addr = addr; 157 } 158 159 void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){ 160 if ( insn ) insn->offset = offset; 161 } 162 163 void x86_set_insn_function( x86_insn_t *insn, void * func ){ 164 if ( insn ) insn->function = func; 165 } 166 167 void x86_set_insn_block( x86_insn_t *insn, void * block ){ 168 if ( insn ) insn->block = block; 169 } 170 171 void x86_tag_insn( x86_insn_t *insn ){ 172 if ( insn ) insn->tag = 1; 173 } 174 175 void x86_untag_insn( x86_insn_t *insn ){ 176 if ( insn ) insn->tag = 0; 177 } 178 179 int x86_insn_is_tagged( x86_insn_t *insn ){ 180 return insn->tag; 181 } 182 183