/usr/include/fcml/fcml_disassembler.h is in libfcml-dev 1.1.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | /*
* FCML - Free Code Manipulation Library.
* Copyright (C) 2010-2015 Slawomir Wojtasiak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/** @file fcml_disassembler.h
* Structures and functions declarations related to FCML disassembler.
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
* This project is released under the GNU Lesser General Public License.
*/
#ifndef FCML_DISASSEMBLER_H_
#define FCML_DISASSEMBLER_H_
#include "fcml_lib_export.h"
#include "fcml_instructions.h"
#include "fcml_types.h"
#include "fcml_errors.h"
#include "fcml_common.h"
#include "fcml_dialect.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Maximal number of instruction prefixes. */
#define FCML_DASM_PREFIXES_COUNT 12
/** First group of conditional suffixes (See FCML manual). */
#define FCML_DASM_CONDITIONAL_GROUP_1 0x00
/** Second group of conditional suffixes (See FCML manual). */
#define FCML_DASM_CONDITIONAL_GROUP_2 0x01
/** This structure and type declaration represents an abstract disassembler. */
typedef struct fcml_st_disassembler fcml_st_disassembler;
/** Disassembler configuration. */
typedef struct fcml_st_disassembler_conf {
/** Set to true in order to make disassembler to increment IP address by length of the disassembled instruction. */
fcml_bool increment_ip;
/** True if optional error and warning messages should be collected during processing. */
fcml_bool enable_error_messages;
/** True if suffixes for carry flag has to be used by disassembler.*/
fcml_bool carry_flag_conditional_suffix;
/** There are two groups of suffixes for conditional instructions, you can choose which one should be used. */
fcml_uint8_t conditional_group;
/** Set to true in order to use short forms.
* For instance 'cmpsb' will be used instead of 'cmps byte ptr [si],byte ptr [di]'
*/
fcml_bool short_forms;
/** True if displacement should be sign extended to effective address size; otherwise false. */
fcml_bool extend_disp_to_asa;
/** If set to true assembler will return FCML_CEH_GEC_UNKNOWN_INSTRUCTION
* error code if instruction is not known.
*/
fcml_bool fail_if_unknown_instruction;
} fcml_st_disassembler_conf;
/** Disassembler context. */
typedef struct fcml_st_disassembler_context {
/** Disassembler used to decode instructions. */
fcml_st_disassembler *disassembler;
/** Disassembler configuration. */
fcml_st_disassembler_conf configuration;
/** Instruction entry point configuration. */
fcml_st_entry_point entry_point;
/** Pointer to the encoded instruction. */
fcml_ptr code;
/** Size of the code in the buffer above. */
fcml_usize code_length;
} fcml_st_disassembler_context;
/* Prefixes */
/** Available types of instruction prefixes. For more information see Intel/AMD Architecture Manual. */
typedef enum fcml_en_prefix_types {
FCML_PT_GROUP_UNKNOWN = 0,
FCML_PT_GROUP_1 = 1,
FCML_PT_GROUP_2,
FCML_PT_GROUP_3,
FCML_PT_GROUP_4,
FCML_PT_REX,
FCML_PT_VEX,
FCML_PT_XOP,
} fcml_en_prefix_types;
/** Describes one decoded prefix. */
typedef struct fcml_st_instruction_prefix {
/** Prefix itself as raw byte. */
fcml_uint8_t prefix;
/** Type of the prefix. */
fcml_en_prefix_types prefix_type;
/** FCML_TRUE if prefix is treated as mandatory one. */
fcml_bool mandatory_prefix;
/** Place for additional bytes of VEX/XOP prefix. */
fcml_uint8_t vex_xop_bytes[2];
} fcml_st_instruction_prefix;
/** Contains some additional information about all decoded instruction prefixes. */
typedef struct fcml_st_prefixes_details {
/** Array with decoded prefixes. */
fcml_st_instruction_prefix prefixes[FCML_DASM_PREFIXES_COUNT];
/** Number of decoded prefixes. */
fcml_int prefixes_count;
/** Number of bytes used by all decoded prefixes. */
fcml_int prefixes_bytes_count;
/** FCML_TRUE if branch prefix exists. */
fcml_bool is_branch;
/** FCML_TRUE if nobranch prefix exists. */
fcml_bool is_nobranch;
/** FCML_TRUE if lock explicit prefix exists. */
fcml_bool is_lock;
/** FCML_TRUE if rep explicit prefix exists. */
fcml_bool is_rep;
/** FCML_TRUE if repne explicit prefix exists. */
fcml_bool is_repne;
/** FCML_TRUE if xrelease explicit prefix exists. */
fcml_bool is_xrelease;
/** FCML_TRUE if xacquire explicit prefix exists. */
fcml_bool is_xacquire;
/** FCML_TRUE if VEX prefix exists. */
fcml_bool is_vex;
/** FCML_TRUE if XOP prefix exists. */
fcml_bool is_xop;
/** FCML_TRUE if REX prefix exists. */
fcml_bool is_rex;
/** Various fields encoded inside decoded prefixes.*/
fcml_uint8_t vex_xop_first_byte;
/** R field of REX,XOP or VEX prefix. */
fcml_uint8_t r;
/** X field of REX,XOP or VEX prefix. */
fcml_uint8_t x;
/** B field of REX,XOP or VEX prefix. */
fcml_uint8_t b;
/** W field of REX,XOP or VEX prefix. */
fcml_uint8_t w;
/** L field of XOP or VEX prefix. */
fcml_uint8_t l;
/** m-mmmm field of XOP or VEX prefix. */
fcml_uint8_t mmmm;
/** vvvv field of XOP or VEX prefix. */
fcml_uint8_t vvvv;
/** pp field of XOP or VEX prefix. */
fcml_uint8_t pp;
} fcml_st_prefixes_details;
/** Some additional disassembler specific information about decoded operands. */
typedef struct fcml_st_operand_details {
/** Instruction operand access mode READ, WRITE or both. */
fcml_en_access_mode access_mode;
} fcml_st_operand_details;
/** Some basic information about decoded ModR/M and SIB bytes. */
typedef struct fcml_st_decoded_modrm_details {
/** ModR/M byte if exists.*/
fcml_uint8_t modrm;
/** SIB byte if exists.*/
fcml_nuint8_t sib;
/** True if RIP encoding is used by decoded instruction. This flag is used only in 64 bit mode. */
fcml_bool is_rip;
/** True if ModR/M exists. */
fcml_bool is_modrm;
} fcml_st_decoded_modrm_details;
/** Additional instruction details provided by disassembler. */
typedef struct fcml_st_instruction_details {
/** True if this is a shortcut.
* A good example of such instruction is 'cmpsb' as opposed to 'cmps byte ptr [si],byte ptr [di]'.
* It is very important to take this information into consideration when instruction
* models are analyzed because there is no operands in the GIM for shortcuts.
*/
fcml_bool is_shortcut;
/** True if given instruction is a short form of pseudo-ops instructions. See 'vcmpunordsd' for instance. */
fcml_bool is_pseudo_op;
/** Code of the disassembled instruction. */
fcml_uint8_t instruction_code[FCML_INSTRUCTION_SIZE];
/** Instruction size in bytes. */
fcml_usize instruction_size;
/** Some additional information about decoded instruction prefixes. */
fcml_st_prefixes_details prefixes_details;
/** All disassembler specific information about operands going there. */
fcml_st_operand_details operand_details[FCML_OPERANDS_COUNT];
/** Details about decoded ModR/M and SIB bytes. */
fcml_st_decoded_modrm_details modrm_details;
/** Opcode field 's'.
* This is set only for informational purpose only and you should not use it for any critical functionality.
*/
fcml_bool opcode_field_s_bit;
/** Opcode field 'w'.
* This is set only for informational purpose only and you should not use it for any critical functionality.
*/
fcml_bool opcode_field_w_bit;
/** Instruction code/number. @see fcml_instructions.h header file. */
fcml_en_instruction instruction;
/** Pseudo operation code. */
fcml_en_pseudo_operations pseudo_op;
/** Code of the instruction form/addressing mode of the instruction above. */
fcml_uint16_t addr_mode;
/** Instruction group. */
fcml_uint64_t instruction_group;
} fcml_st_instruction_details;
/** Reusable disassembler result holder. */
typedef struct fcml_st_disassembler_result {
/** All errors and warnings messages going here. */
fcml_st_ceh_error_container errors;
/** Additional disassembler specific information about decoded instruction. */
fcml_st_instruction_details instruction_details;
/** Decoded instruction in its generic form.*/
fcml_st_instruction instruction;
} fcml_st_disassembler_result;
/**
* Initializes disassembler instance.
* Initializes disassembler instance for given dialect. Disassembler initialized in
* such a way is dialect dependent and generates generic instruction models compliant
* to the syntax supported by the dialect (Intel, AT&T). Every disassembler instance has
* to be freed using fcml_fn_disassembler_free() function as soon as it is not needed anymore.
*
* @param dialect Dialect for newly created disassembler.
* @param[out] disassembler Initialized disassembler instance.
* @return Error code or FCML_CEH_GEC_NO_ERROR.
* @see fcml_fn_disassembler_free
*/
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassembler_init( const fcml_st_dialect *dialect, fcml_st_disassembler **disassembler );
/**
* Disassembles one instruction from provided code buffer.
* Disassembles the first instruction available in the provided code buffer
* using disassembler instance, configuration and entry point accessible through
* the disassembler context. Disassembled instruction model as well as potential
* errors are returned in reusable result holder given in the second parameter.
* Result holder has to be allocated by the user and appropriately prepared
* using fcml_fn_disassembler_result_prepare() function. As long as the
* instruction context and the result holder are not shared across multiple
* function calls disassembling process is thread safe.
*
* @param context Disassembler context.
* @param result Appropriately prepared result holder.
* @return Error code or FCML_CEH_GEC_NO_ERROR.
* @see fcml_fn_disassembler_result_free
*/
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_disassemble( fcml_st_disassembler_context *context, fcml_st_disassembler_result *result );
/**
* Prepares reusable result holder for disassembler.
* Every instance of fcml_st_disassembler_result structure is reusable from the disassembler's
* point of view, so it has to be prepared in the right way in order to allow disassembler to
* reuse it correctly. It is up to the library user to allocate space for the holder itself.
* This function is only responsible for cleaning the structure correctly and preparing it
* for first disassembling process. Notice that disassembler has to clean the result holder
* at the beginning so you can not pass an uninitialized memory block because it can even
* cause a crash due to illegal memory access.
*
* @param result Result holder instance to be prepared.
* @see fcml_fn_disassembler_result_free
*/
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_prepare( fcml_st_disassembler_result *result );
/**
* Cleans result holder.
* Frees all memory blocks allocated by the disassembler and held inside the result holder
* (Instructions, errors etc.). Notice that result holder itself is not freed and can be
* even safety reused after calling this function. In fact this function is also called
* internally by assembler in order to clean result holder before reusing it.
*
* @param result Result holder to clean.
*/
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_result_free( fcml_st_disassembler_result *result );
/**
* Frees disassembler instance.
* Every disassembler instance manages some resources internally and as such it has
* to be deallocated as soon as it is not needed anymore.
* @param disassembler Disassembler to be freed.
*/
LIB_EXPORT void LIB_CALL fcml_fn_disassembler_free( fcml_st_disassembler *disassembler );
#ifdef __cplusplus
}
#endif
#endif /* FCML_DISASSEMBLER_H_ */
|