| OLD | NEW |
| (Empty) |
| 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 | |
| OLD | NEW |