fix merge conflict
This commit is contained in:
@ -1,20 +0,0 @@
|
||||
/* Unicorn Emulator Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2015 */
|
||||
|
||||
#ifndef UC_HOOK_H
|
||||
#define UC_HOOK_H
|
||||
|
||||
// return -1 on failure, index to traces[] on success.
|
||||
size_t hook_add(struct uc_struct *uc, int type, uint64_t begin, uint64_t end, void *callback, void *user_data);
|
||||
|
||||
// return 0 on success, -1 on failure
|
||||
uc_err hook_del(struct uc_struct *uc, uc_hook hh);
|
||||
|
||||
// return NULL on failure
|
||||
struct hook_struct *hook_find(struct uc_struct *uc, int type, uint64_t address);
|
||||
|
||||
// return index of an free hook entry in hook_callbacks[] array.
|
||||
// this realloc memory if needed.
|
||||
size_t hook_find_new(struct uc_struct *uc);
|
||||
|
||||
#endif
|
20
include/list.h
Normal file
20
include/list.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef UC_LLIST_H
|
||||
#define UC_LLIST_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct list_item {
|
||||
struct list_item *next;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct list {
|
||||
struct list_item *head, *tail;
|
||||
};
|
||||
|
||||
struct list *list_new(void);
|
||||
void list_clear(struct list *list);
|
||||
void *list_append(struct list *list, void *data);
|
||||
bool list_remove(struct list *list, void *data);
|
||||
|
||||
#endif
|
@ -9,7 +9,16 @@
|
||||
|
||||
#include "qemu.h"
|
||||
#include "unicorn/unicorn.h"
|
||||
#include "hook.h"
|
||||
#include "list.h"
|
||||
|
||||
// These are masks of supported modes for each cpu/arch.
|
||||
// They should be updated when changes are made to the uc_mode enum typedef.
|
||||
#define UC_MODE_ARM_MASK (UC_MODE_ARM|UC_MODE_THUMB|UC_MODE_LITTLE_ENDIAN)
|
||||
#define UC_MODE_MIPS_MASK (UC_MODE_MIPS32|UC_MODE_MIPS64|UC_MODE_LITTLE_ENDIAN|UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_X86_MASK (UC_MODE_16|UC_MODE_32|UC_MODE_64|UC_MODE_LITTLE_ENDIAN)
|
||||
#define UC_MODE_PPC_MASK (UC_MODE_PPC64|UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_SPARC_MASK (UC_MODE_SPARC32|UC_MODE_SPARC64|UC_MODE_BIG_ENDIAN)
|
||||
#define UC_MODE_M68K_MASK (UC_MODE_BIG_ENDIAN)
|
||||
|
||||
#define ARR_SIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
|
||||
@ -23,6 +32,8 @@ typedef struct ModuleEntry {
|
||||
|
||||
typedef QTAILQ_HEAD(, ModuleEntry) ModuleTypeList;
|
||||
|
||||
typedef uc_err (*query_t)(struct uc_struct *uc, uc_query_type type, size_t *result);
|
||||
|
||||
// return 0 on success, -1 on failure
|
||||
typedef int (*reg_read_t)(struct uc_struct *uc, unsigned int regid, void *value);
|
||||
typedef int (*reg_write_t)(struct uc_struct *uc, unsigned int regid, const void *value);
|
||||
@ -60,16 +71,62 @@ typedef bool (*uc_args_int_t)(int intno);
|
||||
// some architecture redirect virtual memory to physical memory like Mips
|
||||
typedef uint64_t (*uc_mem_redirect_t)(uint64_t address);
|
||||
|
||||
|
||||
struct hook_struct {
|
||||
int hook_type; // uc_tracecode_type & uc_tracemem_type
|
||||
uint64_t begin, end; // range of address to be monitored
|
||||
void *callback; // either uc_cb_tracecode_t or uc_cb_tracemem_t
|
||||
struct hook {
|
||||
int type; // UC_HOOK_*
|
||||
int insn; // instruction for HOOK_INSN
|
||||
int refs; // reference count to free hook stored in multiple lists
|
||||
uint64_t begin, end; // only trigger if PC or memory access is in this address (depends on hook type)
|
||||
void *callback; // a uc_cb_* type
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
// extend memory to keep 32 more hooks each time
|
||||
#define HOOK_SIZE 32
|
||||
// hook list offsets
|
||||
// mirrors the order of uc_hook_type from include/unicorn/unicorn.h
|
||||
enum uc_hook_idx {
|
||||
UC_HOOK_INTR_IDX,
|
||||
UC_HOOK_INSN_IDX,
|
||||
UC_HOOK_CODE_IDX,
|
||||
UC_HOOK_BLOCK_IDX,
|
||||
UC_HOOK_MEM_READ_UNMAPPED_IDX,
|
||||
UC_HOOK_MEM_WRITE_UNMAPPED_IDX,
|
||||
UC_HOOK_MEM_FETCH_UNMAPPED_IDX,
|
||||
UC_HOOK_MEM_READ_PROT_IDX,
|
||||
UC_HOOK_MEM_WRITE_PROT_IDX,
|
||||
UC_HOOK_MEM_FETCH_PROT_IDX,
|
||||
UC_HOOK_MEM_READ_IDX,
|
||||
UC_HOOK_MEM_WRITE_IDX,
|
||||
UC_HOOK_MEM_FETCH_IDX,
|
||||
|
||||
UC_HOOK_MAX,
|
||||
};
|
||||
|
||||
// for loop macro to loop over hook lists
|
||||
#define HOOK_FOREACH(uc, hh, idx) \
|
||||
struct list_item *cur; \
|
||||
for ( \
|
||||
cur = (uc)->hook[idx##_IDX].head; \
|
||||
cur != NULL && ((hh) = (struct hook *)cur->data) \
|
||||
/* stop excuting callbacks on stop request */ \
|
||||
&& !uc->stop_request; \
|
||||
cur = cur->next)
|
||||
|
||||
// if statement to check hook bounds
|
||||
#define HOOK_BOUND_CHECK(hh, addr) \
|
||||
((((addr) >= (hh)->begin && (addr) <= (hh)->end) \
|
||||
|| (hh)->begin > (hh)->end))
|
||||
|
||||
#define HOOK_EXISTS(uc, idx) ((uc)->hook[idx##_IDX].head != NULL)
|
||||
#define HOOK_EXISTS_BOUNDED(uc, idx, addr) _hook_exists_bounded((uc)->hook[idx##_IDX].head, addr)
|
||||
|
||||
static inline bool _hook_exists_bounded(struct list_item *cur, uint64_t addr)
|
||||
{
|
||||
while (cur != NULL) {
|
||||
if (HOOK_BOUND_CHECK((struct hook *)cur->data, addr))
|
||||
return true;
|
||||
cur = cur->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//relloc increment, KEEP THIS A POWER OF 2!
|
||||
#define MEM_BLOCK_INCR 32
|
||||
@ -84,6 +141,7 @@ struct uc_struct {
|
||||
struct CPUTailQ cpus; // qemu/cpu-exec.c
|
||||
uc_err errnum; // qemu/cpu-exec.c
|
||||
AddressSpace as;
|
||||
query_t query;
|
||||
reg_read_t reg_read;
|
||||
reg_write_t reg_write;
|
||||
reg_reset_t reg_reset;
|
||||
@ -146,38 +204,20 @@ struct uc_struct {
|
||||
bool apic_report_tpr_access;
|
||||
CPUState *current_cpu;
|
||||
|
||||
// all the hook callbacks
|
||||
size_t hook_size;
|
||||
struct hook_struct *hook_callbacks;
|
||||
// linked lists containing hooks per type
|
||||
struct list hook[UC_HOOK_MAX];
|
||||
|
||||
// hook to count number of instructions for uc_emu_start()
|
||||
struct hook_struct hook_count;
|
||||
uc_cb_hookcode_t hook_count_callback;
|
||||
uc_hook count_hook;
|
||||
|
||||
size_t emu_counter; // current counter of uc_emu_start()
|
||||
size_t emu_count; // save counter of uc_emu_start()
|
||||
|
||||
// indexes if hooking ALL block/code/read/write events
|
||||
unsigned int hook_block_idx, hook_insn_idx, hook_read_idx, hook_write_idx;
|
||||
// boolean variables for quick check on hooking block, code, memory accesses
|
||||
bool hook_block, hook_insn, hook_mem_read, hook_mem_write;
|
||||
uint64_t block_addr; // save the last block address we hooked
|
||||
// indexes to event callbacks
|
||||
int hook_mem_read_idx; // for handling invalid memory read access on unmapped memory
|
||||
int hook_mem_write_idx; // for handling invalid memory write access on unmapped memory
|
||||
int hook_mem_fetch_idx; // for handling invalid memory fetch access on unmapped memory
|
||||
int hook_mem_read_prot_idx; // for handling invalid memory read access on read-protected memory
|
||||
int hook_mem_write_prot_idx; // for handling invalid memory write access on write-protected memory
|
||||
int hook_mem_fetch_prot_idx; // for handling invalid memory fetch access on non-executable memory
|
||||
|
||||
int hook_intr_idx; // for handling interrupt
|
||||
int hook_out_idx; // for handling OUT instruction (X86)
|
||||
int hook_in_idx; // for handling IN instruction (X86)
|
||||
int hook_syscall_idx; // for handling SYSCALL/SYSENTER (X86)
|
||||
|
||||
|
||||
bool init_tcg; // already initialized local TCGv variables?
|
||||
bool stop_request; // request to immediately stop emulation - for uc_emu_stop()
|
||||
bool quit_request; // request to quit the current TB, but continue to emulate - for uc_mem_protect()
|
||||
bool emulation_done; // emulation is done by uc_emu_start()
|
||||
QemuThread timer; // timer for emulation timeout
|
||||
uint64_t timeout; // timeout for uc_emu_start()
|
||||
|
@ -60,8 +60,10 @@ typedef size_t uc_hook;
|
||||
#define UC_API_MAJOR 0
|
||||
#define UC_API_MINOR 9
|
||||
|
||||
// Macro to create combined version which can be compared to
|
||||
// result of uc_version() API.
|
||||
/*
|
||||
Macro to create combined version which can be compared to
|
||||
result of uc_version() API.
|
||||
*/
|
||||
#define UC_MAKE_VERSION(major, minor) ((major << 8) + minor)
|
||||
|
||||
// Scales to calculate timeout on microsecond unit
|
||||
@ -76,7 +78,7 @@ typedef enum uc_arch {
|
||||
UC_ARCH_ARM64, // ARM-64, also called AArch64
|
||||
UC_ARCH_MIPS, // Mips architecture
|
||||
UC_ARCH_X86, // X86 architecture (including x86 & x86-64)
|
||||
UC_ARCH_PPC, // PowerPC architecture
|
||||
UC_ARCH_PPC, // PowerPC architecture (currently unsupported)
|
||||
UC_ARCH_SPARC, // Sparc architecture
|
||||
UC_ARCH_M68K, // M68K architecture
|
||||
UC_ARCH_MAX,
|
||||
@ -84,22 +86,32 @@ typedef enum uc_arch {
|
||||
|
||||
// Mode type
|
||||
typedef enum uc_mode {
|
||||
UC_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
|
||||
UC_MODE_ARM = 0, // 32-bit ARM
|
||||
UC_MODE_16 = 1 << 1, // 16-bit mode (X86)
|
||||
UC_MODE_32 = 1 << 2, // 32-bit mode (X86)
|
||||
UC_MODE_64 = 1 << 3, // 64-bit mode (X86, PPC)
|
||||
UC_MODE_THUMB = 1 << 4, // ARM's Thumb mode, including Thumb-2
|
||||
UC_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series
|
||||
UC_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM
|
||||
UC_MODE_MICRO = 1 << 4, // MicroMips mode (MIPS)
|
||||
UC_MODE_MIPS3 = 1 << 5, // Mips III ISA
|
||||
UC_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA
|
||||
UC_MODE_V9 = 1 << 4, // SparcV9 mode (Sparc)
|
||||
UC_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode (PPC)
|
||||
UC_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
|
||||
UC_MODE_MIPS32 = UC_MODE_32, // Mips32 ISA (Mips)
|
||||
UC_MODE_MIPS64 = UC_MODE_64, // Mips64 ISA (Mips)
|
||||
UC_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
|
||||
UC_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode
|
||||
// arm / arm64
|
||||
UC_MODE_ARM = 0, // ARM mode
|
||||
UC_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2)
|
||||
UC_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series (currently unsupported)
|
||||
UC_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM (currently unsupported)
|
||||
// mips
|
||||
UC_MODE_MICRO = 1 << 4, // MicroMips mode (currently unsupported)
|
||||
UC_MODE_MIPS3 = 1 << 5, // Mips III ISA (currently unsupported)
|
||||
UC_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA (currently unsupported)
|
||||
UC_MODE_MIPS32 = 1 << 2, // Mips32 ISA
|
||||
UC_MODE_MIPS64 = 1 << 3, // Mips64 ISA
|
||||
// x86 / x64
|
||||
UC_MODE_16 = 1 << 1, // 16-bit mode
|
||||
UC_MODE_32 = 1 << 2, // 32-bit mode
|
||||
UC_MODE_64 = 1 << 3, // 64-bit mode
|
||||
// ppc
|
||||
UC_MODE_PPC32 = 1 << 2, // 32-bit mode (currently unsupported)
|
||||
UC_MODE_PPC64 = 1 << 3, // 64-bit mode (currently unsupported)
|
||||
UC_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode (currently unsupported)
|
||||
// sparc
|
||||
UC_MODE_SPARC32 = 1 << 2, // 32-bit mode
|
||||
UC_MODE_SPARC64 = 1 << 3, // 64-bit mode
|
||||
UC_MODE_V9 = 1 << 4, // SparcV9 mode (currently unsupported)
|
||||
// m68k
|
||||
} uc_mode;
|
||||
|
||||
// All type of errors encountered by Unicorn API.
|
||||
@ -129,27 +141,39 @@ typedef enum uc_err {
|
||||
} uc_err;
|
||||
|
||||
|
||||
// Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of machine instruction(s) being executed, or 0 when size is unknown
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
/*
|
||||
Callback function for tracing code (UC_HOOK_CODE & UC_HOOK_BLOCK)
|
||||
|
||||
@address: address where the code is being executed
|
||||
@size: size of machine instruction(s) being executed, or 0 when size is unknown
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef void (*uc_cb_hookcode_t)(uc_engine *uc, uint64_t address, uint32_t size, void *user_data);
|
||||
|
||||
// Callback function for tracing interrupts (for uc_hook_intr())
|
||||
// @intno: interrupt number
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
/*
|
||||
Callback function for tracing interrupts (for uc_hook_intr())
|
||||
|
||||
@intno: interrupt number
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef void (*uc_cb_hookintr_t)(uc_engine *uc, uint32_t intno, void *user_data);
|
||||
|
||||
// Callback function for tracing IN instruction of X86
|
||||
// @port: port number
|
||||
// @size: data size (1/2/4) to be read from this port
|
||||
// @user_data: user data passed to tracing APIs.
|
||||
/*
|
||||
Callback function for tracing IN instruction of X86
|
||||
|
||||
@port: port number
|
||||
@size: data size (1/2/4) to be read from this port
|
||||
@user_data: user data passed to tracing APIs.
|
||||
*/
|
||||
typedef uint32_t (*uc_cb_insn_in_t)(uc_engine *uc, uint32_t port, int size, void *user_data);
|
||||
|
||||
// x86's handler for OUT
|
||||
// @port: port number
|
||||
// @size: data size (1/2/4) to be written to this port
|
||||
// @value: data value to be written to this port
|
||||
/*
|
||||
Callback function for OUT instruction of X86
|
||||
|
||||
@port: port number
|
||||
@size: data size (1/2/4) to be written to this port
|
||||
@value: data value to be written to this port
|
||||
*/
|
||||
typedef void (*uc_cb_insn_out_t)(uc_engine *uc, uint32_t port, int size, uint32_t value, void *user_data);
|
||||
|
||||
// All type of memory accesses for UC_HOOK_MEM_*
|
||||
@ -194,27 +218,52 @@ typedef enum uc_hook_type {
|
||||
#define UC_HOOK_MEM_FETCH_INVALID (UC_HOOK_MEM_FETCH_PROT + UC_HOOK_MEM_FETCH_UNMAPPED)
|
||||
// hook type for all events of illegal memory access
|
||||
#define UC_HOOK_MEM_INVALID (UC_HOOK_MEM_UNMAPPED + UC_HOOK_MEM_PROT)
|
||||
// hook type for all events of valid memory access
|
||||
#define UC_HOOK_MEM_VALID (UC_HOOK_MEM_READ + UC_HOOK_MEM_WRITE + UC_HOOK_MEM_FETCH)
|
||||
|
||||
// Callback function for hooking memory (UC_MEM_READ, UC_MEM_WRITE & UC_MEM_FETCH)
|
||||
// @type: this memory is being READ, or WRITE
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of data being read or written
|
||||
// @value: value of data being written to memory, or irrelevant if type = READ.
|
||||
// @user_data: user data passed to tracing APIs
|
||||
/*
|
||||
Callback function for hooking memory (UC_MEM_READ, UC_MEM_WRITE & UC_MEM_FETCH)
|
||||
|
||||
@type: this memory is being READ, or WRITE
|
||||
@address: address where the code is being executed
|
||||
@size: size of data being read or written
|
||||
@value: value of data being written to memory, or irrelevant if type = READ.
|
||||
@user_data: user data passed to tracing APIs
|
||||
*/
|
||||
typedef void (*uc_cb_hookmem_t)(uc_engine *uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
// Callback function for handling invalid memory access events (UC_MEM_*_UNMAPPED and
|
||||
// UC_MEM_*PROT events)
|
||||
// @type: this memory is being READ, or WRITE
|
||||
// @address: address where the code is being executed
|
||||
// @size: size of data being read or written
|
||||
// @value: value of data being written to memory, or irrelevant if type = READ.
|
||||
// @user_data: user data passed to tracing APIs
|
||||
// @return: return true to continue, or false to stop program (due to invalid memory).
|
||||
/*
|
||||
Callback function for handling invalid memory access events (UC_MEM_*_UNMAPPED and
|
||||
UC_MEM_*PROT events)
|
||||
|
||||
@type: this memory is being READ, or WRITE
|
||||
@address: address where the code is being executed
|
||||
@size: size of data being read or written
|
||||
@value: value of data being written to memory, or irrelevant if type = READ.
|
||||
@user_data: user data passed to tracing APIs
|
||||
|
||||
@return: return true to continue, or false to stop program (due to invalid memory).
|
||||
*/
|
||||
typedef bool (*uc_cb_eventmem_t)(uc_engine *uc, uc_mem_type type,
|
||||
uint64_t address, int size, int64_t value, void *user_data);
|
||||
|
||||
/*
|
||||
Memory region mapped by uc_mem_map() and uc_mem_map_ptr()
|
||||
Retrieve the list of memory regions with uc_mem_regions()
|
||||
*/
|
||||
typedef struct uc_mem_region {
|
||||
uint64_t begin; // begin address of the region (inclusive)
|
||||
uint64_t end; // end address of the region (inclusive)
|
||||
uint32_t perms; // memory permissions of the region
|
||||
} uc_mem_region;
|
||||
|
||||
// All type of queries for uc_query() API.
|
||||
typedef enum uc_query_type {
|
||||
// Dynamically query current hardware mode.
|
||||
// For ARM, uc_query() return 1 for Thumb mode, and 0 for Arm mode
|
||||
UC_QUERY_MODE = 1,
|
||||
} uc_query_type;
|
||||
|
||||
/*
|
||||
Return combined API version & major and minor version numbers.
|
||||
@ -256,7 +305,7 @@ bool uc_arch_supported(uc_arch arch);
|
||||
@uc: pointer to uc_engine, which will be updated at return time
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **uc);
|
||||
@ -271,11 +320,24 @@ uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **uc);
|
||||
@uc: pointer to a handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_close(uc_engine *uc);
|
||||
|
||||
/*
|
||||
Query internal status of engine.
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@type: query type. See uc_query_type
|
||||
|
||||
@result: save the internal status queried
|
||||
|
||||
@return: error code of uc_err enum type (UC_ERR_*, see above)
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_query(uc_engine *uc, uc_query_type type, size_t *result);
|
||||
|
||||
/*
|
||||
Report the last error number when some API function fail.
|
||||
Like glibc's errno, uc_errno might not retain its old value once accessed.
|
||||
@ -293,7 +355,7 @@ uc_err uc_errno(uc_engine *uc);
|
||||
@code: error code (see UC_ERR_* above)
|
||||
|
||||
@return: returns a pointer to a string that describes the error code
|
||||
passed in the argument @code
|
||||
passed in the argument @code
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
const char *uc_strerror(uc_err code);
|
||||
@ -306,7 +368,7 @@ const char *uc_strerror(uc_err code);
|
||||
@value: pointer to the value that will set to register @regid
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_write(uc_engine *uc, int regid, const void *value);
|
||||
@ -319,7 +381,7 @@ uc_err uc_reg_write(uc_engine *uc, int regid, const void *value);
|
||||
@value: pointer to a variable storing the register value.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_reg_read(uc_engine *uc, int regid, void *value);
|
||||
@ -335,7 +397,7 @@ uc_err uc_reg_read(uc_engine *uc, int regid, void *value);
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t size);
|
||||
@ -351,7 +413,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t s
|
||||
NOTE: @bytes must be big enough to contain @size bytes.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size);
|
||||
@ -368,7 +430,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *bytes, size_t size);
|
||||
we will emulate all the code available, until the code is finished.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uint64_t timeout, size_t count);
|
||||
@ -381,7 +443,7 @@ uc_err uc_emu_start(uc_engine *uc, uint64_t begin, uint64_t until, uint64_t time
|
||||
@uc: handle returned by uc_open()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_emu_stop(uc_engine *uc);
|
||||
@ -399,7 +461,7 @@ uc_err uc_emu_stop(uc_engine *uc);
|
||||
@...: variable arguments (depending on @type)
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, void *user_data, ...);
|
||||
@ -414,7 +476,7 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, void *u
|
||||
@hh: handle returned by uc_hook_add()
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_hook_del(uc_engine *uc, uc_hook hh);
|
||||
@ -441,7 +503,7 @@ typedef enum uc_prot {
|
||||
or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
|
||||
@ -463,7 +525,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
|
||||
least PROT_READ | PROT_WRITE. If it is not, the resulting behavior is undefined.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t perms, void *ptr);
|
||||
@ -472,14 +534,14 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, uint32_t per
|
||||
Unmap a region of emulation memory.
|
||||
This API deletes a memory mapping from the emulation memory space.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the memory region to be unmapped.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the memory region to be modified.
|
||||
This size must be multiple of 4KB, or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
|
||||
@ -488,7 +550,7 @@ uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
|
||||
Set memory permissions for emulation memory.
|
||||
This API changes permissions on an existing memory region.
|
||||
|
||||
@handle: handle returned by uc_open()
|
||||
@uc: handle returned by uc_open()
|
||||
@address: starting address of the memory region to be modified.
|
||||
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
|
||||
@size: size of the memory region to be modified.
|
||||
@ -498,11 +560,28 @@ uc_err uc_mem_unmap(uc_engine *uc, uint64_t address, size_t size);
|
||||
or this will return with UC_ERR_ARG error.
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_protect(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);
|
||||
|
||||
/*
|
||||
Retrieve all memory regions mapped by uc_mem_map() and uc_mem_map_ptr()
|
||||
This API allocates memory for @regions, and user must free this memory later
|
||||
by free() to avoid leaking memory.
|
||||
NOTE: memory regions may be splitted by uc_mem_unmap()
|
||||
|
||||
@uc: handle returned by uc_open()
|
||||
@regions: pointer to an array of uc_mem_region struct. This is allocated by
|
||||
Unicorn, and must be freed by user later
|
||||
@count: pointer to number of struct uc_mem_region contained in @regions
|
||||
|
||||
@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
|
||||
for detailed error).
|
||||
*/
|
||||
UNICORN_EXPORT
|
||||
uc_err uc_mem_regions(uc_engine *uc, uc_mem_region **regions, uint32_t *count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user