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 |