99 lines
2.8 KiB
C
99 lines
2.8 KiB
C
// SPDX-FileCopyrightText: 2021 heersin <teablearcher@gmail.com>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include <rz_analysis.h>
|
|
|
|
/**
|
|
* IL trace should also these info
|
|
* 1. mem.read address & data
|
|
* 2. mem.write address & data
|
|
* 3. reg.read name & data
|
|
* 4. reg.write name & data
|
|
**/
|
|
|
|
static void htup_vector_free(HtUPKv *kv) {
|
|
rz_vector_free(kv->value);
|
|
}
|
|
|
|
/**
|
|
* Create a new trace to collect infos
|
|
* \param analysis pointer to RzAnalysis
|
|
* \param rzil RZ_IL instance
|
|
* \return pointer to RzilTrace
|
|
*/
|
|
RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil) {
|
|
rz_return_val_if_fail(rzil, NULL);
|
|
size_t i;
|
|
RzAnalysisEsilTrace *trace = RZ_NEW0(RzAnalysisEsilTrace);
|
|
if (!trace) {
|
|
return NULL;
|
|
}
|
|
|
|
// TODO : maybe we could remove memory && register in rzil trace ?
|
|
trace->registers = ht_up_new(NULL, htup_vector_free, NULL);
|
|
if (!trace->registers) {
|
|
RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace registers\n");
|
|
goto error;
|
|
}
|
|
trace->memory = ht_up_new(NULL, htup_vector_free, NULL);
|
|
if (!trace->memory) {
|
|
RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace memory\n");
|
|
goto error;
|
|
}
|
|
trace->instructions = rz_pvector_new((RzPVectorFree)rz_analysis_il_trace_instruction_free);
|
|
if (!trace->instructions) {
|
|
RZ_LOG_ERROR("rzil: Cannot allocate vector for trace instructions\n");
|
|
goto error;
|
|
}
|
|
|
|
// TODO : Integrate with stack panel in the future
|
|
|
|
// Save initial registers arenas
|
|
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
|
|
RzRegArena *a = analysis->reg->regset[i].arena;
|
|
RzRegArena *b = rz_reg_arena_new(a->size);
|
|
if (!b) {
|
|
RZ_LOG_ERROR("rzil: Cannot allocate register arena for trace\n");
|
|
goto error;
|
|
}
|
|
if (b->bytes && a->bytes && b->size > 0) {
|
|
memcpy(b->bytes, a->bytes, b->size);
|
|
}
|
|
trace->arena[i] = b;
|
|
}
|
|
return trace;
|
|
error:
|
|
rz_analysis_esil_trace_free(trace);
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Free an IL trace
|
|
* \param trace trace to be free
|
|
*/
|
|
RZ_API void rz_analysis_rzil_trace_free(RzAnalysisEsilTrace *trace) {
|
|
size_t i;
|
|
if (!trace) {
|
|
return;
|
|
}
|
|
|
|
ht_up_free(trace->registers);
|
|
ht_up_free(trace->memory);
|
|
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
|
|
rz_reg_arena_free(trace->arena[i]);
|
|
}
|
|
rz_pvector_free(trace->instructions);
|
|
trace->instructions = NULL;
|
|
RZ_FREE(trace);
|
|
}
|
|
|
|
/**
|
|
* This function should be called after executing the IL op
|
|
* Collect trace info (target and data of mem/reg read/write)
|
|
* \param analysis RzAnalysis
|
|
* \param rzil IL instance
|
|
* \param op RzAnalysisRzilOp, a general IL op structure (Designed for switching between different implementations of IL op struct)
|
|
*/
|
|
RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op) {
|
|
// TODO : rewrite this file when migrate to new op structure
|
|
}
|