Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add yaml serializer for snapshot meta data #53

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions nyx/fast_vm_reload_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "nyx/fast_vm_reload.h"
#include "nyx/kvm_nested.h"
#include "nyx/state/state.h"
#include "nyx/state/snapshot_state.h"

extern int save_snapshot(const char *name, Error **errp);
extern int load_snapshot(const char *name, Error **errp);
Expand Down Expand Up @@ -131,11 +132,23 @@ static inline void create_root_snapshot(void)
fast_reload_create_in_memory(get_fast_reload_snapshot());
fast_reload_serialize_to_file(get_fast_reload_snapshot(),
GET_GLOBAL_STATE()->fast_reload_path, false);

serialize_root_snapshot_meta_data(GET_GLOBAL_STATE()->fast_reload_path);
}
} else {
nyx_debug("===> GET_GLOBAL_STATE()->fast_reload_enabled: FALSE\n");
/* so we haven't set a path for our snapshot files - just store everything in memory */
fast_reload_create_in_memory(get_fast_reload_snapshot());

/* Even if we don't serialize the snapshot we still want to have the
* option to export the meta data of the root snapshot as yaml file.
* This might be useful for the fuzzing frontend in charge; thus it
* is also up to the frontend to set a path for the snapshot directory.
* If the path is not set, we just skip this step.
*/
if (GET_GLOBAL_STATE()->fast_reload_path != NULL) {
serialize_root_snapshot_meta_data(GET_GLOBAL_STATE()->fast_reload_path);
}
}
}

Expand Down
117 changes: 117 additions & 0 deletions nyx/state/snapshot_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,120 @@ void deserialize_state(const char *filename_prefix)

free(tmp);
}

static bool yaml_write_bool(FILE *fp, const char *key, bool value)
{
return fprintf(fp, " %s: %s\n", key, value ? "true" : "false") != -1;
}

static bool yaml_write_uint64_x(FILE *fp, const char *key, uint64_t value)
{
return fprintf(fp, " %s: 0x%" PRIx64 "\n", key, value) != -1;
}

static bool yaml_write_uint64_d(FILE *fp, const char *key, uint64_t value)
{
return fprintf(fp, " %s: %" PRId64 "\n", key, value) != -1;
}

static bool yaml_write_uint64_x_range(FILE *fp, const char *key, uint64_t value_a, uint64_t value_b)
{
return fprintf(fp, " %s: [0x%" PRIx64 ", 0x%" PRIx64 "]\n", key, value_a, value_b) != -1;
}

static void yaml_write_mem_mode(FILE *fp, const char *key, mem_mode_t value)
{
switch (value) {
case mm_unkown:
assert(fprintf(fp, " %s: \"mm_unkown\"\n", key) != 1);
break;
case mm_32_protected: /* 32 Bit / No MMU */
assert(fprintf(fp, " %s: \"mm_32_protected\"\n", key) != 1);
break;
case mm_32_paging: /* 32 Bit / PAE Paging */
assert(fprintf(fp, " %s: \"mm_32_paging\"\n", key) != 1);
break;
case mm_32_pae: /* 32 Bit / PAE Paging */
assert(fprintf(fp, " %s: \"mm_32_pae\"\n", key) != 1);
break;
case mm_64_l4_paging: /* 64 Bit / L4 Paging */
assert(fprintf(fp, " %s: \"mm_64_l4_paging\"\n", key) != 1);
break;
case mm_64_l5_paging: /* 64 Bit / L5 Paging */
assert(fprintf(fp, " %s: \"mm_64_l5_paging\"\n", key) != 1);
break;
}
}

/* Helper function to serialize the meta data of a snapshot to yaml.
* This function is only called in case a root snapshot is created.
* The data written to the yaml file is not used later on, but can be used
* by the frontend to get specific information about the snapshot.
*/
void serialize_root_snapshot_meta_data(const char *snapshot_dir){
nyx_trace();

char *tmp;

assert(asprintf(&tmp, "%s/state.yaml", snapshot_dir) != -1);

FILE *fp = fopen(tmp, "wb");
if (fp == NULL) {
nyx_error("[%s] Could not open file %s.\n", __func__, tmp);
assert(false);
}

qemu_nyx_state_t *nyx_global_state = GET_GLOBAL_STATE();

assert(fprintf(fp, "---\n") != -1);

assert(fprintf(fp, "qemu_nyx:\n") != 1);
assert(yaml_write_uint64_x(fp, "nyx_serialized_state_version", NYX_SERIALIZED_STATE_VERSION));
assert(fprintf(fp, "\n") != -1);

assert(fprintf(fp, "processor_trace:\n") != 1);
for (uint8_t i = 0; i < 4; i++) {
char* key = NULL;
assert(asprintf(&key, "pt_ip_filter_configured_%d", i) != -1);
assert(yaml_write_bool(fp, key, nyx_global_state->pt_ip_filter_configured[i]));
free(key);
}

for (uint8_t i = 0; i < 4; i++) {
char* key = NULL;
assert(asprintf(&key, "pt_ip_filter_%d", i) != -1);
assert(yaml_write_uint64_x_range(fp, key, nyx_global_state->pt_ip_filter_a[i], nyx_global_state->pt_ip_filter_b[i]));
free(key);
}

assert(yaml_write_uint64_x(fp, "parent_cr3", nyx_global_state->parent_cr3));
/* TODO: remove disassembler_word_width (it is actually not used or set anymore) */
//assert(yaml_write_uint64_d(fp, "disassembler_word_width", nyx_global_state->disassembler_word_width));
//assert(yaml_write_uint64_x(fp, "fast_reload_pre_image", nyx_global_state->fast_reload_pre_image));
yaml_write_mem_mode(fp, "mem_mode", nyx_global_state->mem_mode);
assert(yaml_write_bool(fp, "pt_trace_mode", nyx_global_state->pt_trace_mode));
assert(fprintf(fp, "\n") != -1);


assert(fprintf(fp, "input_buffer:\n") != -1);
assert(yaml_write_uint64_x(fp, "input_buffer_vaddr", nyx_global_state->payload_buffer));
assert(yaml_write_bool(fp, "protect_input_buffer", nyx_global_state->protect_payload_buffer));
assert(yaml_write_uint64_x(fp, "input_buffer_size", nyx_global_state->input_buffer_size));
assert(fprintf(fp, "\n") != -1);


assert(fprintf(fp, "capabilites:\n") != -1);
assert(yaml_write_bool(fp, "cap_timeout_detection", nyx_global_state->cap_timeout_detection));
assert(yaml_write_bool(fp, "cap_only_reload_mode", nyx_global_state->cap_only_reload_mode));
assert(yaml_write_bool(fp, "cap_compile_time_tracing", nyx_global_state->cap_compile_time_tracing));
assert(yaml_write_bool(fp, "cap_ijon_tracing", nyx_global_state->cap_ijon_tracing));
assert(yaml_write_bool(fp, "cap_cr3", nyx_global_state->cap_cr3));
assert(yaml_write_uint64_x(fp, "cap_compile_time_tracing_buffer_vaddr", nyx_global_state->cap_compile_time_tracing_buffer_vaddr));
assert(yaml_write_uint64_x(fp, "cap_ijon_tracing_buffer_vaddr", nyx_global_state->cap_ijon_tracing_buffer_vaddr));
assert(yaml_write_uint64_x(fp, "cap_coverage_bitmap_size", nyx_global_state->cap_coverage_bitmap_size));
assert(fprintf(fp, "\n") != -1);

assert(fprintf(fp, "...\n") != -1);
fclose(fp);
free(tmp);
}
2 changes: 2 additions & 0 deletions nyx/state/snapshot_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ typedef struct serialized_state_root_snapshot_s {

void serialize_state(const char *filename_prefix, bool is_pre_snapshot);
void deserialize_state(const char *filename_prefix);

void serialize_root_snapshot_meta_data(const char *snapshot_dir);
2 changes: 1 addition & 1 deletion nyx/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ enum mem_mode {
mm_32_paging, /* 32 Bit / L3 Paging */
mm_32_pae, /* 32 Bit / PAE Paging */
mm_64_l4_paging, /* 64 Bit / L4 Paging */
mm_64_l5_paging, /* 32 Bit / L5 Paging */
mm_64_l5_paging, /* 64 Bit / L5 Paging */
};

typedef uint8_t mem_mode_t;