Update udis86 to current version.

This commit is contained in:
Adrien Destugues 2014-11-12 11:25:41 +01:00
parent 735ca4068d
commit a358634d15
16 changed files with 11299 additions and 6308 deletions

View File

@ -1,33 +1,46 @@
/* udis86 - libudis86/decode.h
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UD_DECODE_H #ifndef UD_DECODE_H
#define UD_DECODE_H #define UD_DECODE_H
#define MAX_INSN_LENGTH 15 #include "types.h"
#include "itab.h"
/* register classes */ #define MAX_INSN_LENGTH 15
#define T_NONE 0
#define T_GPR 1
#define T_MMX 2
#define T_CRG 3
#define T_DBG 4
#define T_SEG 5
#define T_XMM 6
/* itab prefix bits */ /* itab prefix bits */
#define P_none ( 0 ) #define P_none ( 0 )
#define P_c1 ( 1 << 0 ) #define P_cast ( 1 << 0 )
#define P_C1(n) ( ( n >> 0 ) & 1 ) #define P_CAST(n) ( ( n >> 0 ) & 1 )
#define P_rexb ( 1 << 1 ) #define P_rexb ( 1 << 1 )
#define P_REXB(n) ( ( n >> 1 ) & 1 ) #define P_REXB(n) ( ( n >> 1 ) & 1 )
#define P_depM ( 1 << 2 )
#define P_DEPM(n) ( ( n >> 2 ) & 1 )
#define P_c3 ( 1 << 3 )
#define P_C3(n) ( ( n >> 3 ) & 1 )
#define P_inv64 ( 1 << 4 ) #define P_inv64 ( 1 << 4 )
#define P_INV64(n) ( ( n >> 4 ) & 1 ) #define P_INV64(n) ( ( n >> 4 ) & 1 )
#define P_rexw ( 1 << 5 ) #define P_rexw ( 1 << 5 )
#define P_REXW(n) ( ( n >> 5 ) & 1 ) #define P_REXW(n) ( ( n >> 5 ) & 1 )
#define P_c2 ( 1 << 6 )
#define P_C2(n) ( ( n >> 6 ) & 1 )
#define P_def64 ( 1 << 7 ) #define P_def64 ( 1 << 7 )
#define P_DEF64(n) ( ( n >> 7 ) & 1 ) #define P_DEF64(n) ( ( n >> 7 ) & 1 )
#define P_rexr ( 1 << 8 ) #define P_rexr ( 1 << 8 )
@ -40,27 +53,12 @@
#define P_REXX(n) ( ( n >> 11 ) & 1 ) #define P_REXX(n) ( ( n >> 11 ) & 1 )
#define P_ImpAddr ( 1 << 12 ) #define P_ImpAddr ( 1 << 12 )
#define P_IMPADDR(n) ( ( n >> 12 ) & 1 ) #define P_IMPADDR(n) ( ( n >> 12 ) & 1 )
#define P_seg ( 1 << 13 )
/* rex prefix bits */ #define P_SEG(n) ( ( n >> 13 ) & 1 )
#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 ) #define P_str ( 1 << 14 )
#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 ) #define P_STR(n) ( ( n >> 14 ) & 1 )
#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 ) #define P_strz ( 1 << 15 )
#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 ) #define P_STR_ZF(n) ( ( n >> 15 ) & 1 )
#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \
( P_REXR(n) << 2 ) | \
( P_REXX(n) << 1 ) | \
( P_REXB(n) << 0 ) )
/* scable-index-base bits */
#define SIB_S(b) ( ( b ) >> 6 )
#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 )
#define SIB_B(b) ( ( b ) & 7 )
/* modrm bits */
#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 )
#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 )
#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 )
#define MODRM_RM(b) ( ( b ) & 7 )
/* operand type constants -- order is important! */ /* operand type constants -- order is important! */
@ -68,25 +66,15 @@ enum ud_operand_code {
OP_NONE, OP_NONE,
OP_A, OP_E, OP_M, OP_G, OP_A, OP_E, OP_M, OP_G,
OP_I, OP_I, OP_F,
OP_AL, OP_CL, OP_DL, OP_BL, OP_R0, OP_R1, OP_R2, OP_R3,
OP_AH, OP_CH, OP_DH, OP_BH, OP_R4, OP_R5, OP_R6, OP_R7,
OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b, OP_AL, OP_CL, OP_DL,
OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b, OP_AX, OP_CX, OP_DX,
OP_eAX, OP_eCX, OP_eDX,
OP_AX, OP_CX, OP_DX, OP_BX, OP_rAX, OP_rCX, OP_rDX,
OP_SI, OP_DI, OP_SP, OP_BP,
OP_rAX, OP_rCX, OP_rDX, OP_rBX,
OP_rSP, OP_rBP, OP_rSI, OP_rDI,
OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11,
OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15,
OP_eAX, OP_eCX, OP_eDX, OP_eBX,
OP_eSP, OP_eBP, OP_eSI, OP_eDI,
OP_ES, OP_CS, OP_SS, OP_DS, OP_ES, OP_CS, OP_SS, OP_DS,
OP_FS, OP_GS, OP_FS, OP_GS,
@ -95,12 +83,15 @@ enum ud_operand_code {
OP_ST4, OP_ST5, OP_ST6, OP_ST7, OP_ST4, OP_ST5, OP_ST6, OP_ST7,
OP_J, OP_S, OP_O, OP_J, OP_S, OP_O,
OP_I1, OP_I3, OP_I1, OP_I3, OP_sI,
OP_V, OP_W, OP_Q, OP_P, OP_V, OP_W, OP_Q, OP_P,
OP_U, OP_N, OP_MU,
OP_R, OP_C, OP_D, OP_VR, OP_PR OP_R, OP_C, OP_D,
};
OP_MR
} UD_ATTR_PACKED;
/* operand size constants */ /* operand size constants */
@ -109,10 +100,6 @@ enum ud_operand_size {
SZ_NA = 0, SZ_NA = 0,
SZ_Z = 1, SZ_Z = 1,
SZ_V = 2, SZ_V = 2,
SZ_P = 3,
SZ_WP = 4,
SZ_DP = 5,
SZ_MDQ = 6,
SZ_RDQ = 7, SZ_RDQ = 7,
/* the following values are used as is, /* the following values are used as is,
@ -124,123 +111,41 @@ enum ud_operand_size {
SZ_D = 32, SZ_D = 32,
SZ_Q = 64, SZ_Q = 64,
SZ_T = 80, SZ_T = 80,
}; SZ_O = 128,
/* itab entry operand definitions */ SZ_Y = 17,
#define O_rSPr12 { OP_rSPr12, SZ_NA } /*
#define O_BL { OP_BL, SZ_NA } * complex size types, that encode sizes for operands
#define O_BH { OP_BH, SZ_NA } * of type MR (memory or register), for internal use
#define O_BP { OP_BP, SZ_NA } * only. Id space 256 and above.
#define O_AHr12b { OP_AHr12b, SZ_NA } */
#define O_BX { OP_BX, SZ_NA } SZ_BD = (SZ_B << 8) | SZ_D,
#define O_Jz { OP_J, SZ_Z } SZ_BV = (SZ_B << 8) | SZ_V,
#define O_Jv { OP_J, SZ_V } SZ_WD = (SZ_W << 8) | SZ_D,
#define O_Jb { OP_J, SZ_B } SZ_WV = (SZ_W << 8) | SZ_V,
#define O_rSIr14 { OP_rSIr14, SZ_NA } SZ_WY = (SZ_W << 8) | SZ_Y,
#define O_GS { OP_GS, SZ_NA } SZ_DY = (SZ_D << 8) | SZ_Y,
#define O_D { OP_D, SZ_NA } SZ_WO = (SZ_W << 8) | SZ_O,
#define O_rBPr13 { OP_rBPr13, SZ_NA } SZ_DO = (SZ_D << 8) | SZ_O,
#define O_Ob { OP_O, SZ_B } SZ_QO = (SZ_Q << 8) | SZ_O,
#define O_P { OP_P, SZ_NA }
#define O_Ow { OP_O, SZ_W }
#define O_Ov { OP_O, SZ_V }
#define O_Gw { OP_G, SZ_W }
#define O_Gv { OP_G, SZ_V }
#define O_rDX { OP_rDX, SZ_NA }
#define O_Gx { OP_G, SZ_MDQ }
#define O_Gd { OP_G, SZ_D }
#define O_Gb { OP_G, SZ_B }
#define O_rBXr11 { OP_rBXr11, SZ_NA }
#define O_rDI { OP_rDI, SZ_NA }
#define O_rSI { OP_rSI, SZ_NA }
#define O_ALr8b { OP_ALr8b, SZ_NA }
#define O_eDI { OP_eDI, SZ_NA }
#define O_Gz { OP_G, SZ_Z }
#define O_eDX { OP_eDX, SZ_NA }
#define O_DHr14b { OP_DHr14b, SZ_NA }
#define O_rSP { OP_rSP, SZ_NA }
#define O_PR { OP_PR, SZ_NA }
#define O_NONE { OP_NONE, SZ_NA }
#define O_rCX { OP_rCX, SZ_NA }
#define O_jWP { OP_J, SZ_WP }
#define O_rDXr10 { OP_rDXr10, SZ_NA }
#define O_Md { OP_M, SZ_D }
#define O_C { OP_C, SZ_NA }
#define O_G { OP_G, SZ_NA }
#define O_Mb { OP_M, SZ_B }
#define O_Mt { OP_M, SZ_T }
#define O_S { OP_S, SZ_NA }
#define O_Mq { OP_M, SZ_Q }
#define O_W { OP_W, SZ_NA }
#define O_ES { OP_ES, SZ_NA }
#define O_rBX { OP_rBX, SZ_NA }
#define O_Ed { OP_E, SZ_D }
#define O_DLr10b { OP_DLr10b, SZ_NA }
#define O_Mw { OP_M, SZ_W }
#define O_Eb { OP_E, SZ_B }
#define O_Ex { OP_E, SZ_MDQ }
#define O_Ez { OP_E, SZ_Z }
#define O_Ew { OP_E, SZ_W }
#define O_Ev { OP_E, SZ_V }
#define O_Ep { OP_E, SZ_P }
#define O_FS { OP_FS, SZ_NA }
#define O_Ms { OP_M, SZ_W }
#define O_rAXr8 { OP_rAXr8, SZ_NA }
#define O_eBP { OP_eBP, SZ_NA }
#define O_Isb { OP_I, SZ_SB }
#define O_eBX { OP_eBX, SZ_NA }
#define O_rCXr9 { OP_rCXr9, SZ_NA }
#define O_jDP { OP_J, SZ_DP }
#define O_CH { OP_CH, SZ_NA }
#define O_CL { OP_CL, SZ_NA }
#define O_R { OP_R, SZ_RDQ }
#define O_V { OP_V, SZ_NA }
#define O_CS { OP_CS, SZ_NA }
#define O_CHr13b { OP_CHr13b, SZ_NA }
#define O_eCX { OP_eCX, SZ_NA }
#define O_eSP { OP_eSP, SZ_NA }
#define O_SS { OP_SS, SZ_NA }
#define O_SP { OP_SP, SZ_NA }
#define O_BLr11b { OP_BLr11b, SZ_NA }
#define O_SI { OP_SI, SZ_NA }
#define O_eSI { OP_eSI, SZ_NA }
#define O_DL { OP_DL, SZ_NA }
#define O_DH { OP_DH, SZ_NA }
#define O_DI { OP_DI, SZ_NA }
#define O_DX { OP_DX, SZ_NA }
#define O_rBP { OP_rBP, SZ_NA }
#define O_Gvw { OP_G, SZ_MDQ }
#define O_I1 { OP_I1, SZ_NA }
#define O_I3 { OP_I3, SZ_NA }
#define O_DS { OP_DS, SZ_NA }
#define O_ST4 { OP_ST4, SZ_NA }
#define O_ST5 { OP_ST5, SZ_NA }
#define O_ST6 { OP_ST6, SZ_NA }
#define O_ST7 { OP_ST7, SZ_NA }
#define O_ST0 { OP_ST0, SZ_NA }
#define O_ST1 { OP_ST1, SZ_NA }
#define O_ST2 { OP_ST2, SZ_NA }
#define O_ST3 { OP_ST3, SZ_NA }
#define O_E { OP_E, SZ_NA }
#define O_AH { OP_AH, SZ_NA }
#define O_M { OP_M, SZ_NA }
#define O_AL { OP_AL, SZ_NA }
#define O_CLr9b { OP_CLr9b, SZ_NA }
#define O_Q { OP_Q, SZ_NA }
#define O_eAX { OP_eAX, SZ_NA }
#define O_VR { OP_VR, SZ_NA }
#define O_AX { OP_AX, SZ_NA }
#define O_rAX { OP_rAX, SZ_NA }
#define O_Iz { OP_I, SZ_Z }
#define O_rDIr15 { OP_rDIr15, SZ_NA }
#define O_Iw { OP_I, SZ_W }
#define O_Iv { OP_I, SZ_V }
#define O_Ap { OP_A, SZ_P }
#define O_CX { OP_CX, SZ_NA }
#define O_Ib { OP_I, SZ_B }
#define O_BHr15b { OP_BHr15b, SZ_NA }
} UD_ATTR_PACKED;
/* resolve complex size type.
*/
static inline enum ud_operand_size
Mx_mem_size(enum ud_operand_size size)
{
return (size >> 8) & 0xff;
}
static inline enum ud_operand_size
Mx_reg_size(enum ud_operand_size size)
{
return size & 0xff;
}
/* A single operand of an entry in the instruction table. /* A single operand of an entry in the instruction table.
* (internal use only) * (internal use only)
@ -264,7 +169,22 @@ struct ud_itab_entry
uint32_t prefix; uint32_t prefix;
}; };
extern const char * ud_lookup_mnemonic( enum ud_mnemonic_code c ); struct ud_lookup_table_list_entry {
const uint16_t *table;
enum ud_table_type type;
const char *meta;
};
static inline int
ud_opcode_field_sext(uint8_t primary_opcode)
{
return (primary_opcode & 0x02) != 0;
}
extern struct ud_itab_entry ud_itab[];
extern struct ud_lookup_table_list_entry ud_lookup_table_list[];
#endif /* UD_DECODE_H */ #endif /* UD_DECODE_H */

View File

@ -1,9 +1,27 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/extern.h
* extern.h
* *
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2009, 2013 Vivek Thampi
* All rights reserved. See LICENSE * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef UD_EXTERN_H #ifndef UD_EXTERN_H
#define UD_EXTERN_H #define UD_EXTERN_H
@ -12,7 +30,6 @@
extern "C" { extern "C" {
#endif #endif
#include <stdio.h>
#include "types.h" #include "types.h"
/* ============================= PUBLIC API ================================= */ /* ============================= PUBLIC API ================================= */
@ -25,7 +42,7 @@ extern void ud_set_pc(struct ud*, uint64_t);
extern void ud_set_input_hook(struct ud*, int (*)(struct ud*)); extern void ud_set_input_hook(struct ud*, int (*)(struct ud*));
extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t); extern void ud_set_input_buffer(struct ud*, const uint8_t*, size_t);
#ifndef __UD_STANDALONE__ #ifndef __UD_STANDALONE__
extern void ud_set_input_file(struct ud*, FILE*); extern void ud_set_input_file(struct ud*, FILE*);
@ -37,7 +54,7 @@ extern void ud_set_syntax(struct ud*, void (*)(struct ud*));
extern void ud_input_skip(struct ud*, size_t); extern void ud_input_skip(struct ud*, size_t);
extern int ud_input_end(struct ud*); extern int ud_input_end(const struct ud*);
extern unsigned int ud_decode(struct ud*); extern unsigned int ud_decode(struct ud*);
@ -47,21 +64,42 @@ extern void ud_translate_intel(struct ud*);
extern void ud_translate_att(struct ud*); extern void ud_translate_att(struct ud*);
extern char* ud_insn_asm(struct ud* u); extern const char* ud_insn_asm(const struct ud* u);
extern uint8_t* ud_insn_ptr(struct ud* u); extern const uint8_t* ud_insn_ptr(const struct ud* u);
extern uint64_t ud_insn_off(struct ud*); extern uint64_t ud_insn_off(const struct ud*);
extern char* ud_insn_hex(struct ud*); extern const char* ud_insn_hex(struct ud*);
extern unsigned int ud_insn_len(struct ud* u); extern unsigned int ud_insn_len(const struct ud* u);
extern const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n);
extern int ud_opr_is_sreg(const struct ud_operand *opr);
extern int ud_opr_is_gpr(const struct ud_operand *opr);
extern enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u);
extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c); extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
extern void ud_set_user_opaque_data(struct ud*, void*);
extern void* ud_get_user_opaque_data(const struct ud*);
extern uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*);
extern void ud_set_asm_buffer(struct ud *u, char *buf, size_t size);
extern void ud_set_sym_resolver(struct ud *u,
const char* (*resolver)(struct ud*,
uint64_t addr,
int64_t *offset));
/* ========================================================================== */ /* ========================================================================== */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif /* UD_EXTERN_H */

View File

@ -1,155 +1,32 @@
/* itab.h -- auto generated by opgen.py, do not edit. */
#ifndef UD_ITAB_H #ifndef UD_ITAB_H
#define UD_ITAB_H #define UD_ITAB_H
/* itab.h -- generated by udis86:scripts/ud_itab.py, do no edit */
/* ud_table_type -- lookup table types (see decode.c) */
enum ud_itab_vendor_index { enum ud_table_type {
ITAB__VENDOR_INDX__AMD, UD_TAB__OPC_TABLE,
ITAB__VENDOR_INDX__INTEL, UD_TAB__OPC_X87,
UD_TAB__OPC_MOD,
UD_TAB__OPC_VEX_M,
UD_TAB__OPC_VEX_P,
UD_TAB__OPC_RM,
UD_TAB__OPC_VENDOR,
UD_TAB__OPC_OSIZE,
UD_TAB__OPC_MODE,
UD_TAB__OPC_3DNOW,
UD_TAB__OPC_REG,
UD_TAB__OPC_ASIZE,
UD_TAB__OPC_SSE
}; };
/* ud_mnemonic -- mnemonic constants */
enum ud_itab_mode_index {
ITAB__MODE_INDX__16,
ITAB__MODE_INDX__32,
ITAB__MODE_INDX__64
};
enum ud_itab_mod_index {
ITAB__MOD_INDX__NOT_11,
ITAB__MOD_INDX__11
};
enum ud_itab_index {
ITAB__0F,
ITAB__0F__OP_00__REG,
ITAB__0F__OP_01__REG,
ITAB__0F__OP_01__REG__OP_00__MOD,
ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM,
ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_01__VENDOR,
ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_03__VENDOR,
ITAB__0F__OP_01__REG__OP_00__MOD__OP_01__RM__OP_04__VENDOR,
ITAB__0F__OP_01__REG__OP_01__MOD,
ITAB__0F__OP_01__REG__OP_01__MOD__OP_01__RM,
ITAB__0F__OP_01__REG__OP_02__MOD,
ITAB__0F__OP_01__REG__OP_03__MOD,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_00__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_01__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_02__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_03__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_04__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_05__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_06__VENDOR,
ITAB__0F__OP_01__REG__OP_03__MOD__OP_01__RM__OP_07__VENDOR,
ITAB__0F__OP_01__REG__OP_04__MOD,
ITAB__0F__OP_01__REG__OP_06__MOD,
ITAB__0F__OP_01__REG__OP_07__MOD,
ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM,
ITAB__0F__OP_01__REG__OP_07__MOD__OP_01__RM__OP_01__VENDOR,
ITAB__0F__OP_0D__REG,
ITAB__0F__OP_18__REG,
ITAB__0F__OP_71__REG,
ITAB__0F__OP_72__REG,
ITAB__0F__OP_73__REG,
ITAB__0F__OP_AE__REG,
ITAB__0F__OP_AE__REG__OP_05__MOD,
ITAB__0F__OP_AE__REG__OP_05__MOD__OP_01__RM,
ITAB__0F__OP_AE__REG__OP_06__MOD,
ITAB__0F__OP_AE__REG__OP_06__MOD__OP_01__RM,
ITAB__0F__OP_AE__REG__OP_07__MOD,
ITAB__0F__OP_AE__REG__OP_07__MOD__OP_01__RM,
ITAB__0F__OP_BA__REG,
ITAB__0F__OP_C7__REG,
ITAB__0F__OP_C7__REG__OP_00__VENDOR,
ITAB__0F__OP_C7__REG__OP_07__VENDOR,
ITAB__0F__OP_D9__MOD,
ITAB__0F__OP_D9__MOD__OP_01__X87,
ITAB__1BYTE,
ITAB__1BYTE__OP_60__OSIZE,
ITAB__1BYTE__OP_61__OSIZE,
ITAB__1BYTE__OP_63__MODE,
ITAB__1BYTE__OP_6D__OSIZE,
ITAB__1BYTE__OP_6F__OSIZE,
ITAB__1BYTE__OP_80__REG,
ITAB__1BYTE__OP_81__REG,
ITAB__1BYTE__OP_82__REG,
ITAB__1BYTE__OP_83__REG,
ITAB__1BYTE__OP_8F__REG,
ITAB__1BYTE__OP_98__OSIZE,
ITAB__1BYTE__OP_99__OSIZE,
ITAB__1BYTE__OP_9C__MODE,
ITAB__1BYTE__OP_9C__MODE__OP_00__OSIZE,
ITAB__1BYTE__OP_9C__MODE__OP_01__OSIZE,
ITAB__1BYTE__OP_9D__MODE,
ITAB__1BYTE__OP_9D__MODE__OP_00__OSIZE,
ITAB__1BYTE__OP_9D__MODE__OP_01__OSIZE,
ITAB__1BYTE__OP_A5__OSIZE,
ITAB__1BYTE__OP_A7__OSIZE,
ITAB__1BYTE__OP_AB__OSIZE,
ITAB__1BYTE__OP_AD__OSIZE,
ITAB__1BYTE__OP_AE__MOD,
ITAB__1BYTE__OP_AE__MOD__OP_00__REG,
ITAB__1BYTE__OP_AF__OSIZE,
ITAB__1BYTE__OP_C0__REG,
ITAB__1BYTE__OP_C1__REG,
ITAB__1BYTE__OP_C6__REG,
ITAB__1BYTE__OP_C7__REG,
ITAB__1BYTE__OP_CF__OSIZE,
ITAB__1BYTE__OP_D0__REG,
ITAB__1BYTE__OP_D1__REG,
ITAB__1BYTE__OP_D2__REG,
ITAB__1BYTE__OP_D3__REG,
ITAB__1BYTE__OP_D8__MOD,
ITAB__1BYTE__OP_D8__MOD__OP_00__REG,
ITAB__1BYTE__OP_D8__MOD__OP_01__X87,
ITAB__1BYTE__OP_D9__MOD,
ITAB__1BYTE__OP_D9__MOD__OP_00__REG,
ITAB__1BYTE__OP_D9__MOD__OP_01__X87,
ITAB__1BYTE__OP_DA__MOD,
ITAB__1BYTE__OP_DA__MOD__OP_00__REG,
ITAB__1BYTE__OP_DA__MOD__OP_01__X87,
ITAB__1BYTE__OP_DB__MOD,
ITAB__1BYTE__OP_DB__MOD__OP_00__REG,
ITAB__1BYTE__OP_DB__MOD__OP_01__X87,
ITAB__1BYTE__OP_DC__MOD,
ITAB__1BYTE__OP_DC__MOD__OP_00__REG,
ITAB__1BYTE__OP_DC__MOD__OP_01__X87,
ITAB__1BYTE__OP_DD__MOD,
ITAB__1BYTE__OP_DD__MOD__OP_00__REG,
ITAB__1BYTE__OP_DD__MOD__OP_01__X87,
ITAB__1BYTE__OP_DE__MOD,
ITAB__1BYTE__OP_DE__MOD__OP_00__REG,
ITAB__1BYTE__OP_DE__MOD__OP_01__X87,
ITAB__1BYTE__OP_DF__MOD,
ITAB__1BYTE__OP_DF__MOD__OP_00__REG,
ITAB__1BYTE__OP_DF__MOD__OP_01__X87,
ITAB__1BYTE__OP_E3__ASIZE,
ITAB__1BYTE__OP_F6__REG,
ITAB__1BYTE__OP_F7__REG,
ITAB__1BYTE__OP_FE__REG,
ITAB__1BYTE__OP_FF__REG,
ITAB__3DNOW,
ITAB__PFX_SSE66__0F,
ITAB__PFX_SSE66__0F__OP_71__REG,
ITAB__PFX_SSE66__0F__OP_72__REG,
ITAB__PFX_SSE66__0F__OP_73__REG,
ITAB__PFX_SSE66__0F__OP_C7__REG,
ITAB__PFX_SSE66__0F__OP_C7__REG__OP_00__VENDOR,
ITAB__PFX_SSEF2__0F,
ITAB__PFX_SSEF3__0F,
ITAB__PFX_SSEF3__0F__OP_C7__REG,
ITAB__PFX_SSEF3__0F__OP_C7__REG__OP_07__VENDOR,
};
enum ud_mnemonic_code { enum ud_mnemonic_code {
UD_Iinvalid,
UD_I3dnow, UD_I3dnow,
UD_Inone,
UD_Idb,
UD_Ipause,
UD_Iaaa, UD_Iaaa,
UD_Iaad, UD_Iaad,
UD_Iaam, UD_Iaam,
@ -160,8 +37,6 @@ enum ud_mnemonic_code {
UD_Iaddps, UD_Iaddps,
UD_Iaddsd, UD_Iaddsd,
UD_Iaddss, UD_Iaddss,
UD_Iaddsubpd,
UD_Iaddsubps,
UD_Iand, UD_Iand,
UD_Iandpd, UD_Iandpd,
UD_Iandps, UD_Iandps,
@ -214,6 +89,7 @@ enum ud_mnemonic_code {
UD_Icmpss, UD_Icmpss,
UD_Icmpxchg, UD_Icmpxchg,
UD_Icmpxchg8b, UD_Icmpxchg8b,
UD_Icmpxchg16b,
UD_Icomisd, UD_Icomisd,
UD_Icomiss, UD_Icomiss,
UD_Icpuid, UD_Icpuid,
@ -290,7 +166,7 @@ enum ud_mnemonic_code {
UD_Ificom, UD_Ificom,
UD_Ificomp, UD_Ificomp,
UD_Ifild, UD_Ifild,
UD_Ifncstp, UD_Ifincstp,
UD_Ifninit, UD_Ifninit,
UD_Ifiadd, UD_Ifiadd,
UD_Ifidivr, UD_Ifidivr,
@ -304,7 +180,7 @@ enum ud_mnemonic_code {
UD_Ifld1, UD_Ifld1,
UD_Ifldl2t, UD_Ifldl2t,
UD_Ifldl2e, UD_Ifldl2e,
UD_Ifldlpi, UD_Ifldpi,
UD_Ifldlg2, UD_Ifldlg2,
UD_Ifldln2, UD_Ifldln2,
UD_Ifldz, UD_Ifldz,
@ -347,14 +223,10 @@ enum ud_mnemonic_code {
UD_Ifxch7, UD_Ifxch7,
UD_Ifxrstor, UD_Ifxrstor,
UD_Ifxsave, UD_Ifxsave,
UD_Ifpxtract, UD_Ifxtract,
UD_Ifyl2x, UD_Ifyl2x,
UD_Ifyl2xp1, UD_Ifyl2xp1,
UD_Ihaddpd,
UD_Ihaddps,
UD_Ihlt, UD_Ihlt,
UD_Ihsubpd,
UD_Ihsubps,
UD_Iidiv, UD_Iidiv,
UD_Iin, UD_Iin,
UD_Iimul, UD_Iimul,
@ -367,8 +239,10 @@ enum ud_mnemonic_code {
UD_Iint, UD_Iint,
UD_Iinto, UD_Iinto,
UD_Iinvd, UD_Iinvd,
UD_Iinvept,
UD_Iinvlpg, UD_Iinvlpg,
UD_Iinvlpga, UD_Iinvlpga,
UD_Iinvvpid,
UD_Iiretw, UD_Iiretw,
UD_Iiretd, UD_Iiretd,
UD_Iiretq, UD_Iiretq,
@ -413,7 +287,7 @@ enum ud_mnemonic_code {
UD_Ilodsw, UD_Ilodsw,
UD_Ilodsd, UD_Ilodsd,
UD_Ilodsq, UD_Ilodsq,
UD_Iloopnz, UD_Iloopne,
UD_Iloope, UD_Iloope,
UD_Iloop, UD_Iloop,
UD_Ilsl, UD_Ilsl,
@ -429,14 +303,11 @@ enum ud_mnemonic_code {
UD_Iminsd, UD_Iminsd,
UD_Iminss, UD_Iminss,
UD_Imonitor, UD_Imonitor,
UD_Imontmul,
UD_Imov, UD_Imov,
UD_Imovapd, UD_Imovapd,
UD_Imovaps, UD_Imovaps,
UD_Imovd, UD_Imovd,
UD_Imovddup,
UD_Imovdqa,
UD_Imovdqu,
UD_Imovdq2q,
UD_Imovhpd, UD_Imovhpd,
UD_Imovhps, UD_Imovhps,
UD_Imovlhps, UD_Imovlhps,
@ -451,14 +322,10 @@ enum ud_mnemonic_code {
UD_Imovntps, UD_Imovntps,
UD_Imovntq, UD_Imovntq,
UD_Imovq, UD_Imovq,
UD_Imovqa,
UD_Imovq2dq,
UD_Imovsb, UD_Imovsb,
UD_Imovsw, UD_Imovsw,
UD_Imovsd, UD_Imovsd,
UD_Imovsq, UD_Imovsq,
UD_Imovsldup,
UD_Imovshdup,
UD_Imovss, UD_Imovss,
UD_Imovsx, UD_Imovsx,
UD_Imovupd, UD_Imovupd,
@ -480,20 +347,18 @@ enum ud_mnemonic_code {
UD_Ioutsb, UD_Ioutsb,
UD_Ioutsw, UD_Ioutsw,
UD_Ioutsd, UD_Ioutsd,
UD_Ioutsq,
UD_Ipacksswb, UD_Ipacksswb,
UD_Ipackssdw, UD_Ipackssdw,
UD_Ipackuswb, UD_Ipackuswb,
UD_Ipaddb, UD_Ipaddb,
UD_Ipaddw, UD_Ipaddw,
UD_Ipaddq, UD_Ipaddd,
UD_Ipaddsb, UD_Ipaddsb,
UD_Ipaddsw, UD_Ipaddsw,
UD_Ipaddusb, UD_Ipaddusb,
UD_Ipaddusw, UD_Ipaddusw,
UD_Ipand, UD_Ipand,
UD_Ipandn, UD_Ipandn,
UD_Ipause,
UD_Ipavgb, UD_Ipavgb,
UD_Ipavgw, UD_Ipavgw,
UD_Ipcmpeqb, UD_Ipcmpeqb,
@ -502,8 +367,14 @@ enum ud_mnemonic_code {
UD_Ipcmpgtb, UD_Ipcmpgtb,
UD_Ipcmpgtw, UD_Ipcmpgtw,
UD_Ipcmpgtd, UD_Ipcmpgtd,
UD_Ipextrb,
UD_Ipextrd,
UD_Ipextrq,
UD_Ipextrw, UD_Ipextrw,
UD_Ipinsrb,
UD_Ipinsrw, UD_Ipinsrw,
UD_Ipinsrd,
UD_Ipinsrq,
UD_Ipmaddwd, UD_Ipmaddwd,
UD_Ipmaxsw, UD_Ipmaxsw,
UD_Ipmaxub, UD_Ipmaxub,
@ -513,7 +384,6 @@ enum ud_mnemonic_code {
UD_Ipmulhuw, UD_Ipmulhuw,
UD_Ipmulhw, UD_Ipmulhw,
UD_Ipmullw, UD_Ipmullw,
UD_Ipmuludq,
UD_Ipop, UD_Ipop,
UD_Ipopa, UD_Ipopa,
UD_Ipopad, UD_Ipopad,
@ -527,11 +397,7 @@ enum ud_mnemonic_code {
UD_Iprefetcht1, UD_Iprefetcht1,
UD_Iprefetcht2, UD_Iprefetcht2,
UD_Ipsadbw, UD_Ipsadbw,
UD_Ipshufd,
UD_Ipshufhw,
UD_Ipshuflw,
UD_Ipshufw, UD_Ipshufw,
UD_Ipslldq,
UD_Ipsllw, UD_Ipsllw,
UD_Ipslld, UD_Ipslld,
UD_Ipsllq, UD_Ipsllq,
@ -540,11 +406,9 @@ enum ud_mnemonic_code {
UD_Ipsrlw, UD_Ipsrlw,
UD_Ipsrld, UD_Ipsrld,
UD_Ipsrlq, UD_Ipsrlq,
UD_Ipsrldq,
UD_Ipsubb, UD_Ipsubb,
UD_Ipsubw, UD_Ipsubw,
UD_Ipsubd, UD_Ipsubd,
UD_Ipsubq,
UD_Ipsubsb, UD_Ipsubsb,
UD_Ipsubsw, UD_Ipsubsw,
UD_Ipsubusb, UD_Ipsubusb,
@ -552,11 +416,9 @@ enum ud_mnemonic_code {
UD_Ipunpckhbw, UD_Ipunpckhbw,
UD_Ipunpckhwd, UD_Ipunpckhwd,
UD_Ipunpckhdq, UD_Ipunpckhdq,
UD_Ipunpckhqdq,
UD_Ipunpcklbw, UD_Ipunpcklbw,
UD_Ipunpcklwd, UD_Ipunpcklwd,
UD_Ipunpckldq, UD_Ipunpckldq,
UD_Ipunpcklqdq,
UD_Ipi2fw, UD_Ipi2fw,
UD_Ipi2fd, UD_Ipi2fd,
UD_Ipf2iw, UD_Ipf2iw,
@ -572,7 +434,7 @@ enum ud_mnemonic_code {
UD_Ipfcmpgt, UD_Ipfcmpgt,
UD_Ipfmax, UD_Ipfmax,
UD_Ipfrcpit1, UD_Ipfrcpit1,
UD_Ipfrspit1, UD_Ipfrsqit1,
UD_Ipfsubr, UD_Ipfsubr,
UD_Ipfacc, UD_Ipfacc,
UD_Ipfcmpeq, UD_Ipfcmpeq,
@ -606,7 +468,6 @@ enum ud_mnemonic_code {
UD_Irsqrtps, UD_Irsqrtps,
UD_Irsqrtss, UD_Irsqrtss,
UD_Isahf, UD_Isahf,
UD_Isal,
UD_Isalc, UD_Isalc,
UD_Isar, UD_Isar,
UD_Ishl, UD_Ishl,
@ -619,7 +480,7 @@ enum ud_mnemonic_code {
UD_Iseto, UD_Iseto,
UD_Isetno, UD_Isetno,
UD_Isetb, UD_Isetb,
UD_Isetnb, UD_Isetae,
UD_Isetz, UD_Isetz,
UD_Isetnz, UD_Isetnz,
UD_Isetbe, UD_Isetbe,
@ -681,8 +542,11 @@ enum ud_mnemonic_code {
UD_Ivmxon, UD_Ivmxon,
UD_Ivmptrld, UD_Ivmptrld,
UD_Ivmptrst, UD_Ivmptrst,
UD_Ivmlaunch,
UD_Ivmresume, UD_Ivmresume,
UD_Ivmxoff, UD_Ivmxoff,
UD_Ivmread,
UD_Ivmwrite,
UD_Ivmrun, UD_Ivmrun,
UD_Ivmmcall, UD_Ivmmcall,
UD_Ivmload, UD_Ivmload,
@ -692,28 +556,123 @@ enum ud_mnemonic_code {
UD_Iwrmsr, UD_Iwrmsr,
UD_Ixadd, UD_Ixadd,
UD_Ixchg, UD_Ixchg,
UD_Ixgetbv,
UD_Ixlatb, UD_Ixlatb,
UD_Ixor, UD_Ixor,
UD_Ixorpd, UD_Ixorpd,
UD_Ixorps, UD_Ixorps,
UD_Idb, UD_Ixcryptecb,
UD_Iinvalid, UD_Ixcryptcbc,
UD_Id3vil, UD_Ixcryptctr,
UD_Ina, UD_Ixcryptcfb,
UD_Igrp_reg, UD_Ixcryptofb,
UD_Igrp_rm, UD_Ixrstor,
UD_Igrp_vendor, UD_Ixsave,
UD_Igrp_x87, UD_Ixsetbv,
UD_Igrp_mode, UD_Ixsha1,
UD_Igrp_osize, UD_Ixsha256,
UD_Igrp_asize, UD_Ixstore,
UD_Igrp_mod, UD_Iaesdec,
UD_Inone, UD_Iaesdeclast,
}; UD_Iaesenc,
UD_Iaesenclast,
UD_Iaesimc,
UD_Iaeskeygenassist,
UD_Ipclmulqdq,
UD_Igetsec,
UD_Imovdqa,
UD_Imaskmovdqu,
UD_Imovdq2q,
UD_Imovdqu,
UD_Imovq2dq,
UD_Ipaddq,
UD_Ipsubq,
UD_Ipmuludq,
UD_Ipshufhw,
UD_Ipshuflw,
UD_Ipshufd,
UD_Ipslldq,
UD_Ipsrldq,
UD_Ipunpckhqdq,
UD_Ipunpcklqdq,
UD_Iaddsubpd,
UD_Iaddsubps,
UD_Ihaddpd,
UD_Ihaddps,
UD_Ihsubpd,
UD_Ihsubps,
UD_Imovddup,
UD_Imovshdup,
UD_Imovsldup,
UD_Ipabsb,
UD_Ipabsw,
UD_Ipabsd,
UD_Ipshufb,
UD_Iphaddw,
UD_Iphaddd,
UD_Iphaddsw,
UD_Ipmaddubsw,
UD_Iphsubw,
UD_Iphsubd,
UD_Iphsubsw,
UD_Ipsignb,
UD_Ipsignd,
UD_Ipsignw,
UD_Ipmulhrsw,
UD_Ipalignr,
UD_Ipblendvb,
UD_Ipmuldq,
UD_Ipminsb,
UD_Ipminsd,
UD_Ipminuw,
UD_Ipminud,
UD_Ipmaxsb,
UD_Ipmaxsd,
UD_Ipmaxud,
UD_Ipmaxuw,
UD_Ipmulld,
UD_Iphminposuw,
UD_Iroundps,
UD_Iroundpd,
UD_Iroundss,
UD_Iroundsd,
UD_Iblendpd,
UD_Ipblendw,
UD_Iblendps,
UD_Iblendvpd,
UD_Iblendvps,
UD_Idpps,
UD_Idppd,
UD_Impsadbw,
UD_Iextractps,
UD_Iinsertps,
UD_Imovntdqa,
UD_Ipackusdw,
UD_Ipmovsxbw,
UD_Ipmovsxbd,
UD_Ipmovsxbq,
UD_Ipmovsxwd,
UD_Ipmovsxwq,
UD_Ipmovsxdq,
UD_Ipmovzxbw,
UD_Ipmovzxbd,
UD_Ipmovzxbq,
UD_Ipmovzxwd,
UD_Ipmovzxwq,
UD_Ipmovzxdq,
UD_Ipcmpeqq,
UD_Ipopcnt,
UD_Iptest,
UD_Ipcmpestri,
UD_Ipcmpestrm,
UD_Ipcmpgtq,
UD_Ipcmpistri,
UD_Ipcmpistrm,
UD_Imovbe,
UD_Icrc32,
UD_MAX_MNEMONIC_CODE
} UD_ATTR_PACKED;
extern const char * ud_mnemonics_str[];
#endif /* UD_ITAB_H */
extern const char* ud_mnemonics_str[];;
extern struct ud_itab_entry* ud_itab_list[];
#endif

View File

@ -1,25 +1,53 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/syn.h
* syn.h
* *
* Copyright (c) 2006, Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2009
* All rights reserved. See LICENSE * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef UD_SYN_H #ifndef UD_SYN_H
#define UD_SYN_H #define UD_SYN_H
#include <stdio.h>
#include <stdarg.h>
#include "types.h" #include "types.h"
#ifndef __UD_STANDALONE__
# include <stdarg.h>
#endif /* __UD_STANDALONE__ */
extern const char* ud_reg_tab[]; extern const char* ud_reg_tab[];
static void mkasm(struct ud* u, const char* fmt, ...) uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*);
{
va_list ap;
va_start(ap, fmt);
u->insn_fill += vsprintf((char*) u->insn_buffer + u->insn_fill, fmt, ap);
va_end(ap);
}
#ifdef __GNUC__
int ud_asmprintf(struct ud *u, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
#else
int ud_asmprintf(struct ud *u, const char *fmt, ...);
#endif #endif
void ud_syn_print_addr(struct ud *u, uint64_t addr);
void ud_syn_print_imm(struct ud* u, const struct ud_operand *op);
void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign);
#endif /* UD_SYN_H */
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -1,31 +1,58 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/types.h
* types.h
* *
* Copyright (c) 2006, Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved. See LICENSE * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef UD_TYPES_H #ifndef UD_TYPES_H
#define UD_TYPES_H #define UD_TYPES_H
#include <stdio.h> #ifdef __KERNEL__
/* -D__KERNEL__ is automatically passed on the command line when
#ifdef _MSC_VER building something as part of the Linux kernel */
# define FMT64 "%I64" # include <linux/kernel.h>
typedef unsigned __int8 uint8_t; # include <linux/string.h>
typedef unsigned __int16 uint16_t; # ifndef __UD_STANDALONE__
typedef unsigned __int32 uint32_t; # define __UD_STANDALONE__ 1
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
#else
# define FMT64 "%ll"
# include <inttypes.h>
#endif #endif
#endif /* __KERNEL__ */
#if defined(_MSC_VER) || defined(__BORLANDC__)
# include <stdint.h>
# include <stdio.h>
# define inline __inline /* MS Visual Studio requires __inline
instead of inline for C code */
#elif !defined(__UD_STANDALONE__) || defined(__HAIKU__)
# include <stdio.h>
# include <inttypes.h>
#endif /* !__UD_STANDALONE__ */
/* gcc specific extensions */
#if defined(__GNUC__) && __GNUC__ > 2
# define UD_ATTR_PACKED __attribute__((packed))
#else
# define UD_ATTR_PACKED
#endif /* UD_ATTR_PACKED */
#include "itab.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* All possible "types" of objects in udis86. Order is Important! * All possible "types" of objects in udis86. Order is Important!
@ -97,15 +124,9 @@ enum ud_type
UD_OP_JIMM, UD_OP_CONST UD_OP_JIMM, UD_OP_CONST
}; };
/* ----------------------------------------------------------------------------- #include "itab.h"
* struct ud_operand - Disassembled instruction Operand.
* ----------------------------------------------------------------------------- union ud_lval {
*/
struct ud_operand
{
enum ud_type type;
uint8_t size;
union {
int8_t sbyte; int8_t sbyte;
uint8_t ubyte; uint8_t ubyte;
int16_t sword; int16_t sword;
@ -114,17 +135,29 @@ struct ud_operand
uint32_t udword; uint32_t udword;
int64_t sqword; int64_t sqword;
uint64_t uqword; uint64_t uqword;
struct { struct {
uint16_t seg; uint16_t seg;
uint32_t off; uint32_t off;
} ptr; } ptr;
} lval; };
/* -----------------------------------------------------------------------------
* struct ud_operand - Disassembled instruction Operand.
* -----------------------------------------------------------------------------
*/
struct ud_operand {
enum ud_type type;
uint8_t size;
enum ud_type base; enum ud_type base;
enum ud_type index; enum ud_type index;
uint8_t offset;
uint8_t scale; uint8_t scale;
uint8_t offset;
union ud_lval lval;
/*
* internal use only
*/
uint64_t _legacy; /* this will be removed in 1.8 */
uint8_t _oprcode;
}; };
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -133,23 +166,41 @@ struct ud_operand
*/ */
struct ud struct ud
{ {
/*
* input buffering
*/
int (*inp_hook) (struct ud*); int (*inp_hook) (struct ud*);
uint8_t inp_curr; #ifndef __UD_STANDALONE__
uint8_t inp_fill;
FILE* inp_file; FILE* inp_file;
uint8_t inp_ctr; #endif
uint8_t* inp_buff; const uint8_t* inp_buf;
uint8_t* inp_buff_end; size_t inp_buf_size;
uint8_t inp_end; size_t inp_buf_index;
uint8_t inp_curr;
size_t inp_ctr;
uint8_t inp_sess[64];
int inp_end;
void (*translator)(struct ud*); void (*translator)(struct ud*);
uint64_t insn_offset; uint64_t insn_offset;
char insn_hexcode[32]; char insn_hexcode[64];
char insn_buffer[64];
unsigned int insn_fill; /*
* Assembly output buffer
*/
char *asm_buf;
size_t asm_buf_size;
size_t asm_buf_fill;
char asm_buf_int[128];
/*
* Symbol resolver for use in the translation phase.
*/
const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset);
uint8_t dis_mode; uint8_t dis_mode;
uint64_t pc; uint64_t pc;
uint8_t vendor; uint8_t vendor;
struct map_entry* mapen;
enum ud_mnemonic_code mnemonic; enum ud_mnemonic_code mnemonic;
struct ud_operand operand[3]; struct ud_operand operand[3];
uint8_t error; uint8_t error;
@ -158,22 +209,20 @@ struct ud
uint8_t pfx_opr; uint8_t pfx_opr;
uint8_t pfx_adr; uint8_t pfx_adr;
uint8_t pfx_lock; uint8_t pfx_lock;
uint8_t pfx_str;
uint8_t pfx_rep; uint8_t pfx_rep;
uint8_t pfx_repe; uint8_t pfx_repe;
uint8_t pfx_repne; uint8_t pfx_repne;
uint8_t pfx_insn;
uint8_t default64;
uint8_t opr_mode; uint8_t opr_mode;
uint8_t adr_mode; uint8_t adr_mode;
uint8_t br_far; uint8_t br_far;
uint8_t br_near; uint8_t br_near;
uint8_t implicit_addr; uint8_t have_modrm;
uint8_t c1; uint8_t modrm;
uint8_t c2; uint8_t primary_opcode;
uint8_t c3; void * user_opaque_data;
uint8_t inp_cache[256];
uint8_t inp_sess[64];
struct ud_itab_entry * itab_entry; struct ud_itab_entry * itab_entry;
struct ud_lookup_table_list_entry *le;
}; };
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -188,13 +237,14 @@ typedef struct ud_operand ud_operand_t;
#define UD_SYN_INTEL ud_translate_intel #define UD_SYN_INTEL ud_translate_intel
#define UD_SYN_ATT ud_translate_att #define UD_SYN_ATT ud_translate_att
#define UD_EOI -1 #define UD_EOI (-1)
#define UD_INP_CACHE_SZ 32 #define UD_INP_CACHE_SZ 32
#define UD_VENDOR_AMD 0 #define UD_VENDOR_AMD 0
#define UD_VENDOR_INTEL 1 #define UD_VENDOR_INTEL 1
#define UD_VENDOR_ANY 2
#define bail_out(ud,error_code) longjmp( (ud)->bailout, error_code )
#define try_decode(ud) if ( setjmp( (ud)->bailout ) == 0 )
#define catch_error() else
#endif #endif
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -0,0 +1,89 @@
/* udis86 - libudis86/udint.h -- definitions for internal use only
*
* Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _UDINT_H_
#define _UDINT_H_
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#if defined(UD_DEBUG) && HAVE_ASSERT_H
# include <assert.h>
# define UD_ASSERT(_x) assert(_x)
#else
# define UD_ASSERT(_x)
#endif /* !HAVE_ASSERT_H */
#if defined(UD_DEBUG)
#define UDERR(u, msg) \
do { \
(u)->error = 1; \
fprintf(stderr, "decode-error: %s:%d: %s", \
__FILE__, __LINE__, (msg)); \
} while (0)
#else
#define UDERR(u, m) \
do { \
(u)->error = 1; \
} while (0)
#endif /* !LOGERR */
#define UD_RETURN_ON_ERROR(u) \
do { \
if ((u)->error != 0) { \
return (u)->error; \
} \
} while (0)
#define UD_RETURN_WITH_ERROR(u, m) \
do { \
UDERR(u, m); \
return (u)->error; \
} while (0)
#ifndef __UD_STANDALONE__
# define UD_NON_STANDALONE(x) x
#else
# define UD_NON_STANDALONE(x)
#endif
/* printf formatting int64 specifier */
#ifdef FMT64
# undef FMT64
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
# define FMT64 "I64"
#else
# if defined(__APPLE__)
# define FMT64 "ll"
# elif defined(__amd64__) || defined(__x86_64__)
# define FMT64 "l"
# else
# define FMT64 "ll"
# endif /* !x64 */
#endif
#endif /* _UDINT_H_ */

View File

@ -1,11 +1,28 @@
/* ----------------------------------------------------------------------------- /* udis86 - udis86.h
* udis86.h
* *
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved. See (LICENSE) * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef UDIS86_H #ifndef UDIS86_H
#define UDIS86_H #define UDIS86_H

View File

@ -11,7 +11,6 @@ DEFINES += __assert_fail=disasm_arch_assert ;
local libUdis86Sources = local libUdis86Sources =
decode.c decode.c
input.c
itab.c itab.c
syn-att.c syn-att.c
syn.c syn.c

View File

@ -7,7 +7,6 @@ UseHeaders [ LibraryHeaders [ FDirName udis86 libudis86 ] ] ;
StaticLibrary libudis86.a : StaticLibrary libudis86.a :
decode.c decode.c
input.c
itab.c itab.c
syn-att.c syn-att.c
syn.c syn.c

File diff suppressed because it is too large Load Diff

View File

@ -1,226 +0,0 @@
/* -----------------------------------------------------------------------------
* input.c
*
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
* All rights reserved. See LICENSE
* -----------------------------------------------------------------------------
*/
#include "extern.h"
#include "types.h"
#include "input.h"
/* -----------------------------------------------------------------------------
* inp_buff_hook() - Hook for buffered inputs.
* -----------------------------------------------------------------------------
*/
static int
inp_buff_hook(struct ud* u)
{
if (u->inp_buff < u->inp_buff_end)
return *u->inp_buff++;
else return -1;
}
#ifndef __UD_STANDALONE__
/* -----------------------------------------------------------------------------
* inp_file_hook() - Hook for FILE inputs.
* -----------------------------------------------------------------------------
*/
static int
inp_file_hook(struct ud* u)
{
return fgetc(u->inp_file);
}
#endif /* __UD_STANDALONE__*/
/* =============================================================================
* ud_inp_set_hook() - Sets input hook.
* =============================================================================
*/
extern void
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
{
u->inp_hook = hook;
inp_init(u);
}
/* =============================================================================
* ud_inp_set_buffer() - Set buffer as input.
* =============================================================================
*/
extern void
ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len)
{
u->inp_hook = inp_buff_hook;
u->inp_buff = buf;
u->inp_buff_end = buf + len;
inp_init(u);
}
#ifndef __UD_STANDALONE__
/* =============================================================================
* ud_input_set_file() - Set buffer as input.
* =============================================================================
*/
extern void
ud_set_input_file(register struct ud* u, FILE* f)
{
u->inp_hook = inp_file_hook;
u->inp_file = f;
inp_init(u);
}
#endif /* __UD_STANDALONE__ */
/* =============================================================================
* ud_input_skip() - Skip n input bytes.
* =============================================================================
*/
extern void
ud_input_skip(struct ud* u, size_t n)
{
while (n--) {
u->inp_hook(u);
}
}
/* =============================================================================
* ud_input_end() - Test for end of input.
* =============================================================================
*/
extern int
ud_input_end(struct ud* u)
{
return (u->inp_curr == u->inp_fill) && u->inp_end;
}
/* -----------------------------------------------------------------------------
* inp_next() - Loads and returns the next byte from input.
*
* inp_curr and inp_fill are pointers to the cache. The program is written based
* on the property that they are 8-bits in size, and will eventually wrap around
* forming a circular buffer. So, the size of the cache is 256 in size, kind of
* unnecessary yet optimized.
*
* A buffer inp_sess stores the bytes disassembled for a single session.
* -----------------------------------------------------------------------------
*/
extern uint8_t inp_next(struct ud* u)
{
int c = -1;
/* if current pointer is not upto the fill point in the
* input cache.
*/
if ( u->inp_curr != u->inp_fill ) {
c = u->inp_cache[ ++u->inp_curr ];
/* if !end-of-input, call the input hook and get a byte */
} else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) {
/* end-of-input, mark it as an error, since the decoder,
* expected a byte more.
*/
u->error = 1;
/* flag end of input */
u->inp_end = 1;
return 0;
} else {
/* increment pointers, we have a new byte. */
u->inp_curr = ++u->inp_fill;
/* add the byte to the cache */
u->inp_cache[ u->inp_fill ] = c;
}
/* record bytes input per decode-session. */
u->inp_sess[ u->inp_ctr++ ] = c;
/* return byte */
return ( uint8_t ) c;
}
/* -----------------------------------------------------------------------------
* inp_back() - Move back a single byte in the stream.
* -----------------------------------------------------------------------------
*/
extern void
inp_back(struct ud* u)
{
if ( u->inp_ctr > 0 ) {
--u->inp_curr;
--u->inp_ctr;
}
}
/* -----------------------------------------------------------------------------
* inp_peek() - Peek into the next byte in source.
* -----------------------------------------------------------------------------
*/
extern uint8_t
inp_peek(struct ud* u)
{
uint8_t r = inp_next(u);
if ( !u->error ) inp_back(u); /* Don't backup if there was an error */
return r;
}
/* -----------------------------------------------------------------------------
* inp_move() - Move ahead n input bytes.
* -----------------------------------------------------------------------------
*/
extern void
inp_move(struct ud* u, size_t n)
{
while (n--)
inp_next(u);
}
/*------------------------------------------------------------------------------
* inp_uintN() - return uintN from source.
*------------------------------------------------------------------------------
*/
extern uint8_t
inp_uint8(struct ud* u)
{
return inp_next(u);
}
extern uint16_t
inp_uint16(struct ud* u)
{
uint16_t r, ret;
ret = inp_next(u);
r = inp_next(u);
return ret | (r << 8);
}
extern uint32_t
inp_uint32(struct ud* u)
{
uint32_t r, ret;
ret = inp_next(u);
r = inp_next(u);
ret = ret | (r << 8);
r = inp_next(u);
ret = ret | (r << 16);
r = inp_next(u);
return ret | (r << 24);
}
extern uint64_t
inp_uint64(struct ud* u)
{
uint64_t r, ret;
ret = inp_next(u);
r = inp_next(u);
ret = ret | (r << 8);
r = inp_next(u);
ret = ret | (r << 16);
r = inp_next(u);
ret = ret | (r << 24);
r = inp_next(u);
ret = ret | (r << 32);
r = inp_next(u);
ret = ret | (r << 40);
r = inp_next(u);
ret = ret | (r << 48);
r = inp_next(u);
return ret | (r << 56);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,34 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/syn-att.c
* syn-att.c
* *
* Copyright (c) 2004, 2005, 2006 Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2009 Vivek Thampi
* All rights reserved. See (LICENSE) * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "types.h" #include "types.h"
#include "extern.h" #include "extern.h"
#include "decode.h" #include "decode.h"
#include "itab.h" #include "itab.h"
#include "syn.h" #include "syn.h"
#include "udint.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* opr_cast() - Prints an operand cast. * opr_cast() - Prints an operand cast.
@ -21,7 +39,7 @@ opr_cast(struct ud* u, struct ud_operand* op)
{ {
switch(op->size) { switch(op->size) {
case 16 : case 32 : case 16 : case 32 :
mkasm(u, "*"); break; ud_asmprintf(u, "*"); break;
default: break; default: break;
} }
} }
@ -34,73 +52,60 @@ static void
gen_operand(struct ud* u, struct ud_operand* op) gen_operand(struct ud* u, struct ud_operand* op)
{ {
switch(op->type) { switch(op->type) {
case UD_OP_CONST:
ud_asmprintf(u, "$0x%x", op->lval.udword);
break;
case UD_OP_REG: case UD_OP_REG:
mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
break; break;
case UD_OP_MEM: case UD_OP_MEM:
if (u->br_far) opr_cast(u, op); if (u->br_far) {
if (u->pfx_seg) opr_cast(u, op);
mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); }
if (op->offset == 8) { if (u->pfx_seg) {
if (op->lval.sbyte < 0) ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff); }
else mkasm(u, "0x%x", op->lval.sbyte); if (op->offset != 0) {
ud_syn_print_mem_disp(u, op, 0);
}
if (op->base) {
ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
} }
else if (op->offset == 16)
mkasm(u, "0x%x", op->lval.uword);
else if (op->offset == 32)
mkasm(u, "0x%lx", op->lval.udword);
else if (op->offset == 64)
mkasm(u, "0x" FMT64 "x", op->lval.uqword);
if (op->base)
mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
if (op->index) { if (op->index) {
if (op->base) if (op->base) {
mkasm(u, ","); ud_asmprintf(u, ",");
else mkasm(u, "("); } else {
mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); ud_asmprintf(u, "(");
}
ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
}
if (op->scale) {
ud_asmprintf(u, ",%d", op->scale);
}
if (op->base || op->index) {
ud_asmprintf(u, ")");
} }
if (op->scale)
mkasm(u, ",%d", op->scale);
if (op->base || op->index)
mkasm(u, ")");
break; break;
case UD_OP_IMM: case UD_OP_IMM:
switch (op->size) { ud_asmprintf(u, "$");
case 8: mkasm(u, "$0x%x", op->lval.ubyte); break; ud_syn_print_imm(u, op);
case 16: mkasm(u, "$0x%x", op->lval.uword); break;
case 32: mkasm(u, "$0x%lx", op->lval.udword); break;
case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break;
default: break;
}
break; break;
case UD_OP_JIMM: case UD_OP_JIMM:
switch (op->size) { ud_syn_print_addr(u, ud_syn_rel_target(u, op));
case 8:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
break;
case 16:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
break;
case 32:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
break;
default:break;
}
break; break;
case UD_OP_PTR: case UD_OP_PTR:
switch (op->size) { switch (op->size) {
case 32: case 32:
mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg, ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
op->lval.ptr.off & 0xFFFF); op->lval.ptr.off & 0xFFFF);
break; break;
case 48: case 48:
mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg, ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
op->lval.ptr.off); op->lval.ptr.off);
break; break;
} }
@ -118,16 +123,17 @@ extern void
ud_translate_att(struct ud *u) ud_translate_att(struct ud *u)
{ {
int size = 0; int size = 0;
int star = 0;
/* check if P_OSO prefix is used */ /* check if P_OSO prefix is used */
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
switch (u->dis_mode) { switch (u->dis_mode) {
case 16: case 16:
mkasm(u, "o32 "); ud_asmprintf(u, "o32 ");
break; break;
case 32: case 32:
case 64: case 64:
mkasm(u, "o16 "); ud_asmprintf(u, "o16 ");
break; break;
} }
} }
@ -136,76 +142,83 @@ ud_translate_att(struct ud *u)
if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
switch (u->dis_mode) { switch (u->dis_mode) {
case 16: case 16:
mkasm(u, "a32 "); ud_asmprintf(u, "a32 ");
break; break;
case 32: case 32:
mkasm(u, "a16 "); ud_asmprintf(u, "a16 ");
break; break;
case 64: case 64:
mkasm(u, "a32 "); ud_asmprintf(u, "a32 ");
break; break;
} }
} }
if (u->pfx_lock) if (u->pfx_lock)
mkasm(u, "lock "); ud_asmprintf(u, "lock ");
if (u->pfx_rep) if (u->pfx_rep) {
mkasm(u, "rep "); ud_asmprintf(u, "rep ");
if (u->pfx_repne) } else if (u->pfx_rep) {
mkasm(u, "repne "); ud_asmprintf(u, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
}
/* special instructions */ /* special instructions */
switch (u->mnemonic) { switch (u->mnemonic) {
case UD_Iretf: case UD_Iretf:
mkasm(u, "lret "); ud_asmprintf(u, "lret ");
break; break;
case UD_Idb: case UD_Idb:
mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte); ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
return; return;
case UD_Ijmp: case UD_Ijmp:
case UD_Icall: case UD_Icall:
if (u->br_far) mkasm(u, "l"); if (u->br_far) ud_asmprintf(u, "l");
mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); if (u->operand[0].type == UD_OP_REG) {
star = 1;
}
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
break; break;
case UD_Ibound: case UD_Ibound:
case UD_Ienter: case UD_Ienter:
if (u->operand[0].type != UD_NONE) if (u->operand[0].type != UD_NONE)
gen_operand(u, &u->operand[0]); gen_operand(u, &u->operand[0]);
if (u->operand[1].type != UD_NONE) { if (u->operand[1].type != UD_NONE) {
mkasm(u, ","); ud_asmprintf(u, ",");
gen_operand(u, &u->operand[1]); gen_operand(u, &u->operand[1]);
} }
return; return;
default: default:
mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
} }
if (u->c1)
size = u->operand[0].size;
else if (u->c2)
size = u->operand[1].size;
else if (u->c3)
size = u->operand[2].size;
if (size == 8) if (size == 8)
mkasm(u, "b"); ud_asmprintf(u, "b");
else if (size == 16) else if (size == 16)
mkasm(u, "w"); ud_asmprintf(u, "w");
else if (size == 64) else if (size == 64)
mkasm(u, "q"); ud_asmprintf(u, "q");
mkasm(u, " "); if (star) {
ud_asmprintf(u, " *");
} else {
ud_asmprintf(u, " ");
}
if (u->operand[2].type != UD_NONE) { if (u->operand[2].type != UD_NONE) {
gen_operand(u, &u->operand[2]); gen_operand(u, &u->operand[2]);
mkasm(u, ", "); ud_asmprintf(u, ", ");
} }
if (u->operand[1].type != UD_NONE) { if (u->operand[1].type != UD_NONE) {
gen_operand(u, &u->operand[1]); gen_operand(u, &u->operand[1]);
mkasm(u, ", "); ud_asmprintf(u, ", ");
} }
if (u->operand[0].type != UD_NONE) if (u->operand[0].type != UD_NONE)
gen_operand(u, &u->operand[0]); gen_operand(u, &u->operand[0]);
} }
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -1,16 +1,34 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/syn-intel.c
* syn-intel.c
* *
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved. See (LICENSE) * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "types.h" #include "types.h"
#include "extern.h" #include "extern.h"
#include "decode.h" #include "decode.h"
#include "itab.h" #include "itab.h"
#include "syn.h" #include "syn.h"
#include "udint.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* opr_cast() - Prints an operand cast. * opr_cast() - Prints an operand cast.
@ -19,18 +37,17 @@
static void static void
opr_cast(struct ud* u, struct ud_operand* op) opr_cast(struct ud* u, struct ud_operand* op)
{ {
if (u->br_far) {
ud_asmprintf(u, "far ");
}
switch(op->size) { switch(op->size) {
case 8: mkasm(u, "byte " ); break; case 8: ud_asmprintf(u, "byte " ); break;
case 16: mkasm(u, "word " ); break; case 16: ud_asmprintf(u, "word " ); break;
case 32: mkasm(u, "dword "); break; case 32: ud_asmprintf(u, "dword "); break;
case 64: mkasm(u, "qword "); break; case 64: ud_asmprintf(u, "qword "); break;
case 80: mkasm(u, "tword "); break; case 80: ud_asmprintf(u, "tword "); break;
default: break; default: break;
} }
if (u->br_far)
mkasm(u, "far ");
else if (u->br_near)
mkasm(u, "near ");
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -41,93 +58,51 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
{ {
switch(op->type) { switch(op->type) {
case UD_OP_REG: case UD_OP_REG:
mkasm(u, ud_reg_tab[op->base - UD_R_AL]); ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
break; break;
case UD_OP_MEM: { case UD_OP_MEM:
if (syn_cast) {
int op_f = 0;
if (syn_cast)
opr_cast(u, op); opr_cast(u, op);
}
mkasm(u, "["); ud_asmprintf(u, "[");
if (u->pfx_seg) {
if (u->pfx_seg) ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); }
if (op->base) { if (op->base) {
mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]); ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
op_f = 1;
} }
if (op->index) { if (op->index) {
if (op_f) ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
mkasm(u, "+"); ud_reg_tab[op->index - UD_R_AL]);
mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]); if (op->scale) {
op_f = 1; ud_asmprintf(u, "*%d", op->scale);
} }
if (op->scale)
mkasm(u, "*%d", op->scale);
if (op->offset == 8) {
if (op->lval.sbyte < 0)
mkasm(u, "-0x%x", -op->lval.sbyte);
else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
} }
else if (op->offset == 16) if (op->offset != 0) {
mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword); ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
else if (op->offset == 32) { op->index != UD_NONE) ? 1 : 0);
if (u->adr_mode == 64) {
if (op->lval.sdword < 0)
mkasm(u, "-0x%x", -op->lval.sdword);
else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
} }
else mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword); ud_asmprintf(u, "]");
}
else if (op->offset == 64)
mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
mkasm(u, "]");
break; break;
}
case UD_OP_IMM: case UD_OP_IMM:
if (syn_cast) opr_cast(u, op); ud_syn_print_imm(u, op);
switch (op->size) {
case 8: mkasm(u, "0x%x", op->lval.ubyte); break;
case 16: mkasm(u, "0x%x", op->lval.uword); break;
case 32: mkasm(u, "0x%lx", op->lval.udword); break;
case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
default: break;
}
break; break;
case UD_OP_JIMM: case UD_OP_JIMM:
if (syn_cast) opr_cast(u, op); ud_syn_print_addr(u, ud_syn_rel_target(u, op));
switch (op->size) {
case 8:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
break;
case 16:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
break;
case 32:
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
break;
default:break;
}
break; break;
case UD_OP_PTR: case UD_OP_PTR:
switch (op->size) { switch (op->size) {
case 32: case 32:
mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg, ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
op->lval.ptr.off & 0xFFFF); op->lval.ptr.off & 0xFFFF);
break; break;
case 48: case 48:
mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg, ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
op->lval.ptr.off); op->lval.ptr.off);
break; break;
} }
@ -135,7 +110,7 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
case UD_OP_CONST: case UD_OP_CONST:
if (syn_cast) opr_cast(u, op); if (syn_cast) opr_cast(u, op);
mkasm(u, "%d", op->lval.udword); ud_asmprintf(u, "%d", op->lval.udword);
break; break;
default: return; default: return;
@ -146,63 +121,93 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
* translates to intel syntax * translates to intel syntax
* ============================================================================= * =============================================================================
*/ */
extern void ud_translate_intel(struct ud* u) extern void
ud_translate_intel(struct ud* u)
{ {
/* -- prefixes -- */
/* check if P_OSO prefix is used */ /* check if P_OSO prefix is used */
if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) { if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
switch (u->dis_mode) { switch (u->dis_mode) {
case 16: case 16: ud_asmprintf(u, "o32 "); break;
mkasm(u, "o32 ");
break;
case 32: case 32:
case 64: case 64: ud_asmprintf(u, "o16 "); break;
mkasm(u, "o16 ");
break;
} }
} }
/* check if P_ASO prefix was used */ /* check if P_ASO prefix was used */
if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) { if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
switch (u->dis_mode) { switch (u->dis_mode) {
case 16: case 16: ud_asmprintf(u, "a32 "); break;
mkasm(u, "a32 "); case 32: ud_asmprintf(u, "a16 "); break;
break; case 64: ud_asmprintf(u, "a32 "); break;
case 32:
mkasm(u, "a16 ");
break;
case 64:
mkasm(u, "a32 ");
break;
} }
} }
if (u->pfx_lock) if (u->pfx_seg &&
mkasm(u, "lock "); u->operand[0].type != UD_OP_MEM &&
if (u->pfx_rep) u->operand[1].type != UD_OP_MEM ) {
mkasm(u, "rep "); ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
if (u->pfx_repne) }
mkasm(u, "repne ");
if (u->implicit_addr && u->pfx_seg) if (u->pfx_lock) {
mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]); ud_asmprintf(u, "lock ");
}
if (u->pfx_rep) {
ud_asmprintf(u, "rep ");
} else if (u->pfx_repe) {
ud_asmprintf(u, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
}
/* print the instruction mnemonic */ /* print the instruction mnemonic */
mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic)); ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
/* operand 1 */
if (u->operand[0].type != UD_NONE) { if (u->operand[0].type != UD_NONE) {
gen_operand(u, &u->operand[0], u->c1); int cast = 0;
ud_asmprintf(u, " ");
if (u->operand[0].type == UD_OP_MEM) {
if (u->operand[1].type == UD_OP_IMM ||
u->operand[1].type == UD_OP_CONST ||
u->operand[1].type == UD_NONE ||
(u->operand[0].size != u->operand[1].size &&
u->operand[1].type != UD_OP_REG)) {
cast = 1;
} else if (u->operand[1].type == UD_OP_REG &&
u->operand[1].base == UD_R_CL) {
switch (u->mnemonic) {
case UD_Ircl:
case UD_Irol:
case UD_Iror:
case UD_Ircr:
case UD_Ishl:
case UD_Ishr:
case UD_Isar:
cast = 1;
break;
default: break;
} }
/* operand 2 */ }
if (u->operand[1].type != UD_NONE) { }
mkasm(u, ", "); gen_operand(u, &u->operand[0], cast);
gen_operand(u, &u->operand[1], u->c2); }
if (u->operand[1].type != UD_NONE) {
int cast = 0;
ud_asmprintf(u, ", ");
if (u->operand[1].type == UD_OP_MEM &&
u->operand[0].size != u->operand[1].size &&
!ud_opr_is_sreg(&u->operand[0])) {
cast = 1;
}
gen_operand(u, &u->operand[1], cast);
} }
/* operand 3 */
if (u->operand[2].type != UD_NONE) { if (u->operand[2].type != UD_NONE) {
mkasm(u, ", "); ud_asmprintf(u, ", ");
gen_operand(u, &u->operand[2], u->c3); gen_operand(u, &u->operand[2], 0);
} }
} }
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -1,10 +1,32 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/syn.c
* syn.c
* *
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved. See (LICENSE) * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "types.h"
#include "decode.h"
#include "syn.h"
#include "udint.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Intel Register Table - Order Matters (types.h)! * Intel Register Table - Order Matters (types.h)!
@ -21,7 +43,7 @@ const char* ud_reg_tab[] =
"ax", "cx", "dx", "bx", "ax", "cx", "dx", "bx",
"sp", "bp", "si", "di", "sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w", "r8w", "r9w", "r10w", "r11w",
"r12w", "r13W" , "r14w", "r15w", "r12w", "r13w" , "r14w", "r15w",
"eax", "ecx", "edx", "ebx", "eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi", "esp", "ebp", "esi", "edi",
@ -59,3 +81,127 @@ const char* ud_reg_tab[] =
"rip" "rip"
}; };
uint64_t
ud_syn_rel_target(struct ud *u, struct ud_operand *opr)
{
const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode);
switch (opr->size) {
case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask;
case 16: return (u->pc + opr->lval.sword) & trunc_mask;
case 32: return (u->pc + opr->lval.sdword) & trunc_mask;
default: UD_ASSERT(!"invalid relative offset size.");
return 0ull;
}
}
/*
* asmprintf
* Printf style function for printing translated assembly
* output. Returns the number of characters written and
* moves the buffer pointer forward. On an overflow,
* returns a negative number and truncates the output.
*/
int
ud_asmprintf(struct ud *u, const char *fmt, ...)
{
int ret;
int avail;
va_list ap;
va_start(ap, fmt);
avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */;
ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap);
if (ret < 0 || ret > avail) {
u->asm_buf_fill = u->asm_buf_size - 1;
} else {
u->asm_buf_fill += ret;
}
va_end(ap);
return ret;
}
void
ud_syn_print_addr(struct ud *u, uint64_t addr)
{
const char *name = NULL;
if (u->sym_resolver) {
int64_t offset = 0;
name = u->sym_resolver(u, addr, &offset);
if (name) {
if (offset) {
ud_asmprintf(u, "%s%+" FMT64 "d", name, offset);
} else {
ud_asmprintf(u, "%s", name);
}
return;
}
}
ud_asmprintf(u, "0x%" FMT64 "x", addr);
}
void
ud_syn_print_imm(struct ud* u, const struct ud_operand *op)
{
uint64_t v;
if (op->_oprcode == OP_sI && op->size != u->opr_mode) {
if (op->size == 8) {
v = (int64_t)op->lval.sbyte;
} else {
UD_ASSERT(op->size == 32);
v = (int64_t)op->lval.sdword;
}
if (u->opr_mode < 64) {
v = v & ((1ull << u->opr_mode) - 1ull);
}
} else {
switch (op->size) {
case 8 : v = op->lval.ubyte; break;
case 16: v = op->lval.uword; break;
case 32: v = op->lval.udword; break;
case 64: v = op->lval.uqword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
}
ud_asmprintf(u, "0x%" FMT64 "x", v);
}
void
ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign)
{
UD_ASSERT(op->offset != 0);
if (op->base == UD_NONE && op->index == UD_NONE) {
uint64_t v;
UD_ASSERT(op->scale == UD_NONE && op->offset != 8);
/* unsigned mem-offset */
switch (op->offset) {
case 16: v = op->lval.uword; break;
case 32: v = op->lval.udword; break;
case 64: v = op->lval.uqword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
ud_asmprintf(u, "0x%" FMT64 "x", v);
} else {
int64_t v;
UD_ASSERT(op->offset != 64);
switch (op->offset) {
case 8 : v = op->lval.sbyte; break;
case 16: v = op->lval.sword; break;
case 32: v = op->lval.sdword; break;
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
}
if (v < 0) {
ud_asmprintf(u, "-0x%" FMT64 "x", -v);
} else if (v > 0) {
ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v);
}
}
}
/*
vim: set ts=2 sw=2 expandtab
*/

View File

@ -1,20 +1,44 @@
/* ----------------------------------------------------------------------------- /* udis86 - libudis86/udis86.c
* udis86.c
* *
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com> * Copyright (c) 2002-2013 Vivek Thampi
* All rights reserved. See LICENSE * All rights reserved.
* ----------------------------------------------------------------------------- *
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdlib.h> #include "udint.h"
#include <stdio.h>
#include <string.h>
#include "input.h"
#include "extern.h" #include "extern.h"
#include "decode.h"
#if !defined(__UD_STANDALONE__)
# if HAVE_STRING_H
# include <string.h>
# endif
#endif /* !__UD_STANDALONE__ */
static void ud_inp_init(struct ud *u);
/* ============================================================================= /* =============================================================================
* ud_init() - Initializes ud_t object. * ud_init
* Initializes ud_t object.
* ============================================================================= * =============================================================================
*/ */
extern void extern void
@ -27,29 +51,33 @@ ud_init(struct ud* u)
#ifndef __UD_STANDALONE__ #ifndef __UD_STANDALONE__
ud_set_input_file(u, stdin); ud_set_input_file(u, stdin);
#endif /* __UD_STANDALONE__ */ #endif /* __UD_STANDALONE__ */
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
} }
/* ============================================================================= /* =============================================================================
* ud_disassemble() - disassembles one instruction and returns the number of * ud_disassemble
* Disassembles one instruction and returns the number of
* bytes disassembled. A zero means end of disassembly. * bytes disassembled. A zero means end of disassembly.
* ============================================================================= * =============================================================================
*/ */
extern unsigned int extern unsigned int
ud_disassemble(struct ud* u) ud_disassemble(struct ud* u)
{ {
if (ud_input_end(u)) int len;
if (u->inp_end) {
return 0; return 0;
u->insn_buffer[0] = u->insn_hexcode[0] = 0;
if (ud_decode(u) == 0)
return 0;
if (u->translator)
u->translator(u);
return ud_insn_len(u);
} }
if ((len = ud_decode(u)) > 0) {
if (u->translator != NULL) {
u->asm_buf[0] = '\0';
u->translator(u);
}
}
return len;
}
/* ============================================================================= /* =============================================================================
* ud_set_mode() - Set Disassemly Mode. * ud_set_mode() - Set Disassemly Mode.
@ -77,6 +105,9 @@ ud_set_vendor(struct ud* u, unsigned v)
case UD_VENDOR_INTEL: case UD_VENDOR_INTEL:
u->vendor = v; u->vendor = v;
break; break;
case UD_VENDOR_ANY:
u->vendor = v;
break;
default: default:
u->vendor = UD_VENDOR_AMD; u->vendor = UD_VENDOR_AMD;
} }
@ -106,18 +137,18 @@ ud_set_syntax(struct ud* u, void (*t)(struct ud*))
* ud_insn() - returns the disassembled instruction * ud_insn() - returns the disassembled instruction
* ============================================================================= * =============================================================================
*/ */
extern char* const char*
ud_insn_asm(struct ud* u) ud_insn_asm(const struct ud* u)
{ {
return u->insn_buffer; return u->asm_buf;
} }
/* ============================================================================= /* =============================================================================
* ud_insn_offset() - Returns the offset. * ud_insn_offset() - Returns the offset.
* ============================================================================= * =============================================================================
*/ */
extern uint64_t uint64_t
ud_insn_off(struct ud* u) ud_insn_off(const struct ud* u)
{ {
return u->insn_offset; return u->insn_offset;
} }
@ -127,28 +158,300 @@ ud_insn_off(struct ud* u)
* ud_insn_hex() - Returns hex form of disassembled instruction. * ud_insn_hex() - Returns hex form of disassembled instruction.
* ============================================================================= * =============================================================================
*/ */
extern char* const char*
ud_insn_hex(struct ud* u) ud_insn_hex(struct ud* u)
{ {
u->insn_hexcode[0] = 0;
if (!u->error) {
unsigned int i;
const unsigned char *src_ptr = ud_insn_ptr(u);
char* src_hex;
src_hex = (char*) u->insn_hexcode;
/* for each byte used to decode instruction */
for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
++i, ++src_ptr) {
sprintf(src_hex, "%02x", *src_ptr & 0xFF);
src_hex += 2;
}
}
return u->insn_hexcode; return u->insn_hexcode;
} }
/* =============================================================================
* ud_insn_ptr() - Returns code disassembled.
* =============================================================================
*/
extern uint8_t*
ud_insn_ptr(struct ud* u)
{
return u->inp_sess;
}
/* ============================================================================= /* =============================================================================
* ud_insn_len() - Returns the count of bytes disassembled. * ud_insn_ptr
* Returns a pointer to buffer containing the bytes that were
* disassembled.
* =============================================================================
*/
extern const uint8_t*
ud_insn_ptr(const struct ud* u)
{
return (u->inp_buf == NULL) ?
u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
}
/* =============================================================================
* ud_insn_len
* Returns the count of bytes disassembled.
* ============================================================================= * =============================================================================
*/ */
extern unsigned int extern unsigned int
ud_insn_len(struct ud* u) ud_insn_len(const struct ud* u)
{ {
return u->inp_ctr; return u->inp_ctr;
} }
/* =============================================================================
* ud_insn_get_opr
* Return the operand struct representing the nth operand of
* the currently disassembled instruction. Returns NULL if
* there's no such operand.
* =============================================================================
*/
const struct ud_operand*
ud_insn_opr(const struct ud *u, unsigned int n)
{
if (n > 2 || u->operand[n].type == UD_NONE) {
return NULL;
} else {
return &u->operand[n];
}
}
/* =============================================================================
* ud_opr_is_sreg
* Returns non-zero if the given operand is of a segment register type.
* =============================================================================
*/
int
ud_opr_is_sreg(const struct ud_operand *opr)
{
return opr->type == UD_OP_REG &&
opr->base >= UD_R_ES &&
opr->base <= UD_R_GS;
}
/* =============================================================================
* ud_opr_is_sreg
* Returns non-zero if the given operand is of a general purpose
* register type.
* =============================================================================
*/
int
ud_opr_is_gpr(const struct ud_operand *opr)
{
return opr->type == UD_OP_REG &&
opr->base >= UD_R_AL &&
opr->base <= UD_R_R15;
}
/* =============================================================================
* ud_set_user_opaque_data
* ud_get_user_opaque_data
* Get/set user opaqute data pointer
* =============================================================================
*/
void
ud_set_user_opaque_data(struct ud * u, void* opaque)
{
u->user_opaque_data = opaque;
}
void*
ud_get_user_opaque_data(const struct ud *u)
{
return u->user_opaque_data;
}
/* =============================================================================
* ud_set_asm_buffer
* Allow the user to set an assembler output buffer. If `buf` is NULL,
* we switch back to the internal buffer.
* =============================================================================
*/
void
ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
{
if (buf == NULL) {
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
} else {
u->asm_buf = buf;
u->asm_buf_size = size;
}
}
/* =============================================================================
* ud_set_sym_resolver
* Set symbol resolver for relative targets used in the translation
* phase.
*
* The resolver is a function that takes a uint64_t address and returns a
* symbolic name for the that address. The function also takes a second
* argument pointing to an integer that the client can optionally set to a
* non-zero value for offsetted targets. (symbol+offset) The function may
* also return NULL, in which case the translator only prints the target
* address.
*
* The function pointer maybe NULL which resets symbol resolution.
* =============================================================================
*/
void
ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
uint64_t addr,
int64_t *offset))
{
u->sym_resolver = resolver;
}
/* =============================================================================
* ud_insn_mnemonic
* Return the current instruction mnemonic.
* =============================================================================
*/
enum ud_mnemonic_code
ud_insn_mnemonic(const struct ud *u)
{
return u->mnemonic;
}
/* =============================================================================
* ud_lookup_mnemonic
* Looks up mnemonic code in the mnemonic string table.
* Returns NULL if the mnemonic code is invalid.
* =============================================================================
*/
const char*
ud_lookup_mnemonic(enum ud_mnemonic_code c)
{
if (c < UD_MAX_MNEMONIC_CODE) {
return ud_mnemonics_str[c];
} else {
return NULL;
}
}
/*
* ud_inp_init
* Initializes the input system.
*/
static void
ud_inp_init(struct ud *u)
{
u->inp_hook = NULL;
u->inp_buf = NULL;
u->inp_buf_size = 0;
u->inp_buf_index = 0;
u->inp_curr = 0;
u->inp_ctr = 0;
u->inp_end = 0;
UD_NON_STANDALONE(u->inp_file = NULL);
}
/* =============================================================================
* ud_inp_set_hook
* Sets input hook.
* =============================================================================
*/
void
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
{
ud_inp_init(u);
u->inp_hook = hook;
}
/* =============================================================================
* ud_inp_set_buffer
* Set buffer as input.
* =============================================================================
*/
void
ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
{
ud_inp_init(u);
u->inp_buf = buf;
u->inp_buf_size = len;
u->inp_buf_index = 0;
}
#ifndef __UD_STANDALONE__
/* =============================================================================
* ud_input_set_file
* Set FILE as input.
* =============================================================================
*/
static int
inp_file_hook(struct ud* u)
{
return fgetc(u->inp_file);
}
void
ud_set_input_file(register struct ud* u, FILE* f)
{
ud_inp_init(u);
u->inp_hook = inp_file_hook;
u->inp_file = f;
}
#endif /* __UD_STANDALONE__ */
/* =============================================================================
* ud_input_skip
* Skip n input bytes.
* ============================================================================
*/
void
ud_input_skip(struct ud* u, size_t n)
{
if (u->inp_end) {
return;
}
if (u->inp_buf == NULL) {
while (n--) {
int c = u->inp_hook(u);
if (c == UD_EOI) {
goto eoi;
}
}
return;
} else {
if (n > u->inp_buf_size ||
u->inp_buf_index > u->inp_buf_size - n) {
u->inp_buf_index = u->inp_buf_size;
goto eoi;
}
u->inp_buf_index += n;
return;
}
eoi:
u->inp_end = 1;
UDERR(u, "cannot skip, eoi received\b");
return;
}
/* =============================================================================
* ud_input_end
* Returns non-zero on end-of-input.
* =============================================================================
*/
int
ud_input_end(const struct ud *u)
{
return u->inp_end;
}
/* vim:set ts=2 sw=2 expandtab */