This file is indexed.

/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_ */