x86_insn.cpp 4.5 KB

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