drwrap error

79 views
Skip to first unread message

Андрей Неважный

unread,
Feb 26, 2021, 2:54:52 AM2/26/21
to DynamoRIO Users
#include "utils.h"
#include "drmgr.h"
#include "drsyms.h"
#include "drwrap.h"
#include "dr_defines.h"
//#include "bb_getinfo.h"

#include <stddef.h>
#include <iostream>
#include <list>
#include <algorithm>
#include <string.h>
#include <fstream>
#include <signal.h>

#define LEN 256

drsym_error_t get_sym(app_pc pc, module_data_t *mod);
char* get_info(void *drcontext, app_pc pc, module_data_t *mod, app_pc last_instr, file_t fd);
void free_drsmy();

static void *mod_lock;
static void *wrap_lock;
static file_t fd;
static size_t towrap = 0;

typedef struct option_t {
bool disassembly;
bool verbose;
bool disassembly_function;
bool is_cbr;
char function_name[LEN];
bool report_file;
char report_file_name[LEN];
bool wrap_function;
char wrap_function_name[LEN];
size_t wrap_function_args;
} option_t;

static option_t options;

static drsym_info_t *syminfo;

struct func_info {
const char *name_function;
app_pc start_addr;
app_pc end_addr;
app_pc pc;
};


void dump_mem(app_pc arg, app_pc address) {
char first[MAXIMUM_PATH] = { 0 };
size_t bytes_read = 0;

dr_safe_read(arg, BUFFER_SIZE_BYTES(first), first, &bytes_read);
if (bytes_read < BUFFER_SIZE_BYTES(bytes_read))
first[bytes_read] = '\0';
NULL_TERMINATE_BUFFER(first);

if (bytes_read) {
dr_fprintf(fd, "[DUMP];" PFX ";", address);
for (int j = 0; j<bytes_read; j++) {
if (first[j] == 0)
break;
dr_fprintf(fd, "0x%02x ", first[j]);
}
dr_fprintf(fd, "\n");
}
}

static void wrap_pre(void *wrapcxt, OUT void **user_data) {
size_t i = 0;
app_pc address = 0;

dr_mutex_lock(wrap_lock);
address = drwrap_get_func(wrapcxt);
for (i = 0; i < options.wrap_function_args; i++) {
char first[MAXIMUM_PATH] = { 0 };
size_t bytes_read = 0;

app_pc arg = (app_pc)drwrap_get_arg(wrapcxt, i);
DR_ASSERT(arg);
dr_fprintf(fd, "[ARG];%s;" PFX ";%d;%d;" PFX "\n", options.wrap_function_name, address, i, options.wrap_function_args, arg);

dump_mem(arg, address);
}
dr_mutex_unlock(wrap_lock);
}

static void wrap_post(void *wrapcxt, void *user_data) {
app_pc address = 0;
app_pc ret = NULL;

dr_mutex_lock(wrap_lock);
address = drwrap_get_func(wrapcxt);

void *drcontext = drwrap_get_drcontext(wrapcxt);

DR_TRY_EXCEPT(drcontext, {
ret = (app_pc)drwrap_get_retval(wrapcxt);
}, {
ret = NULL;
});

if (ret != NULL) {
dr_fprintf(fd, "[RET];%s;" PFX ";" PFX "\n", options.wrap_function_name, address, ret);
dump_mem(ret, address);
}
else {
dr_fprintf(fd, "[ERR];Return address exception\n");
}

dr_mutex_unlock(wrap_lock);
}

static void iterate_imports(const module_data_t *mod)
{
const char *mod_name = dr_module_preferred_name(mod);

dr_symbol_import_iterator_t *imp_iter =
dr_symbol_import_iterator_start(mod->handle, NULL);
while (dr_symbol_import_iterator_hasnext(imp_iter)) {
dr_symbol_import_t *sym = dr_symbol_import_iterator_next(imp_iter);
dr_fprintf(fd, "Name: %s\n", sym->name);
}
dr_symbol_import_iterator_stop(imp_iter);
}

static bool enumerate_sym(const char *name, size_t modoffs, void *data) {
if (*name != 0) {
if (options.verbose) {
dr_fprintf(fd, "Offset: " PFX " Name: %s\n", modoffs, name);
}
if (!strcmp(name, options.wrap_function_name)) {
towrap = modoffs;
}
}
return true;
}

static void event_module_load(void *drcontext, const module_data_t *mod, bool loaded) {
drsym_error_t symr;
app_pc mod_base = mod->start;
module_data_t *data = dr_get_main_module();

if (data == NULL) {
dr_fprintf(fd, "[ERR];No main module found! \n");
return;
}

const char *module_name = mod->names.file_name;

if (module_name == NULL) {
module_name = dr_module_preferred_name(mod);
}

if (options.verbose)
dr_fprintf(fd, "[MOD];%s;" PFX ";%s\n", module_name, mod_base, mod->full_path);

if (mod_base != data->start) {
dr_free_module_data(data);
return;
}

if (options.verbose) {
dr_fprintf(fd, "[IMPORTS]: \n");
iterate_imports(mod);
dr_fprintf(fd, "[EXPORTS]: \n");
}

symr = drsym_enumerate_symbols(mod->full_path, enumerate_sym, NULL, DRSYM_DEFAULT_FLAGS);
if (symr != DRSYM_SUCCESS && options.verbose)
dr_fprintf(fd, "[ERR];search / enum error %d\n", symr);

if (options.wrap_function) {
bool wrapped = false;
app_pc to_wrap = mod_base + towrap;

if (towrap != 0) {
wrapped = drwrap_wrap(to_wrap, wrap_pre, wrap_post);
DR_ASSERT(wrapped);
}
}

dr_free_module_data(data);
}

static void cbr_func(app_pc src, app_pc targ) {
dr_mcontext_t mcontext = { sizeof(mcontext),DR_MC_ALL, };
void *drcontext = dr_get_current_drcontext();

dr_flush_region((app_pc)src, (size_t)targ - (size_t)src);
dr_get_mcontext(drcontext, &mcontext);
mcontext.pc = (app_pc)targ;
dr_redirect_execution(&mcontext);
}

drsym_info_t* drsym_obj(const char *path) {
drsym_info_t *drsym_o;
drsym_o = (drsym_info_t *)malloc(sizeof(drsym_info_t));
if (drsym_o == NULL)
return NULL;
drsym_o->struct_size = sizeof(drsym_info_t);
drsym_debug_kind_t kind;
drsym_error_t symres = drsym_get_module_debug_kind(path, &kind);
if (symres == DRSYM_SUCCESS)
drsym_o->debug_kind = kind;
drsym_o->name_size = LEN;
drsym_o->file_size = LEN;
drsym_o->file = (char *)malloc(LEN);
drsym_o->name = (char *)malloc(LEN);
return drsym_o;
}


void free_drsmy_obj(drsym_info_t *drsym_o) {
if (drsym_o != NULL) {
if (drsym_o->file != NULL)
free(drsym_o->file);
if (drsym_o->name != NULL)
free(drsym_o->name);
free(drsym_o);
}
}

void free_drsmy() {
free_drsmy_obj(syminfo);
}

drsym_error_t get_sym(app_pc pc, module_data_t *mod) {
drsym_error_t symres = DRSYM_ERROR;
syminfo = drsym_obj(mod->full_path);

if (syminfo == NULL)
return symres;

size_t offset = pc - mod->start;
syminfo->start_offs = 0;
syminfo->end_offs = 0;
symres = drsym_lookup_address(mod->full_path, offset, syminfo, DRSYM_DEMANGLE);
return symres;

}

char *get_info(void *drcontext, app_pc pc, module_data_t *mod, app_pc last_instr, file_t fd) {
drsym_error_t symres;
struct func_info functions;
char *ret_function;

ret_function = (char *)malloc(LEN);

if (ret_function == NULL)
return NULL;

memset(ret_function, 0, LEN);

app_pc mod_base = mod->start;

symres = get_sym(pc, mod);

if (symres == DRSYM_ERROR)
return NULL;

functions.pc = pc;

bool wrapped1 = false;
wrapped1 = drwrap_wrap(pc, wrap_pre, wrap_post);
DR_ASSERT(wrapped1);

if (symres == DRSYM_SUCCESS || symres == DRSYM_ERROR_LINE_NOT_AVAILABLE) {
functions.name_function = syminfo->name;
functions.start_addr = syminfo->start_offs + mod_base;
functions.end_addr = syminfo->end_offs + mod_base;
dr_fprintf(fd, "[FUNC];" PFX ";" PFX ";" PFX ";%s", functions.start_addr, functions.end_addr, functions.pc, functions.name_function);

memcpy(ret_function, functions.name_function, LEN);

}
else {
app_pc first_bb = pc;
dr_fprintf(fd, "[NOFUNC];" PFX ";" PFX ";" PFX ";None", first_bb, last_instr, pc);
}

dr_fprintf(fd, "\n");
return ret_function;

}

static dr_emit_flags_t event_bb_analysis(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating, OUT void **user_data) {
instr_t *instr;
instr_t *last;
module_data_t *data;
module_data_t *mod;
char *ret_function;

drsym_error_t symres;

instr = instrlist_first_app(bb);
last = instrlist_last_app(bb);

if (instr == NULL || last == NULL)
return DR_EMIT_DEFAULT;

app_pc pc = instr_get_app_pc(instr);
app_pc last_instr = instr_get_app_pc(last);
app_pc next_instr = (app_pc)decode_next_pc(drcontext, (byte *)pc);

if (pc == NULL || last_instr == NULL)
return DR_EMIT_DEFAULT;

mod = dr_lookup_module(pc);

if (mod == NULL)
return DR_EMIT_DEFAULT;

app_pc mod_base = mod->start;

data = dr_get_main_module();

if (data == NULL)
return DR_EMIT_DEFAULT;

if (mod_base != data->start)
return DR_EMIT_DEFAULT;

if (options.is_cbr) {
if (instr_is_cbr(last)) {
dr_mutex_lock(mod_lock);

app_pc next_instr = (app_pc)decode_next_pc(drcontext, (byte *)last_instr);

ret_function = get_info(drcontext, pc, mod, last_instr, fd);

if (ret_function == NULL)
return DR_EMIT_DEFAULT;

if (options.disassembly && !options.disassembly_function)
instrlist_disassemble(drcontext, (app_pc)tag, bb, fd);
else if ((!options.disassembly && options.disassembly_function) && !strcmp(options.function_name, ret_function))
instrlist_disassemble(drcontext, (app_pc)tag, bb, fd);

dr_insert_clean_call(drcontext, bb, NULL,
(void*)cbr_func,
false,
2,
OPND_CREATE_INTPTR(pc),
OPND_CREATE_INTPTR(next_instr));

free(ret_function);
dr_free_module_data(mod);
dr_free_module_data(data);

dr_mutex_unlock(mod_lock);

return DR_EMIT_STORE_TRANSLATIONS;
}
}

dr_mutex_lock(mod_lock);

ret_function = get_info(drcontext, pc, mod, last_instr, fd);
if (ret_function == NULL)
return DR_EMIT_DEFAULT;

if (options.disassembly && !options.disassembly_function)
instrlist_disassemble(drcontext, (app_pc)tag, bb, fd);
else if ((!options.disassembly && options.disassembly_function) && !strcmp(options.function_name, ret_function))
instrlist_disassemble(drcontext, (app_pc)tag, bb, fd);

free(ret_function);
dr_free_module_data(mod);
dr_free_module_data(data);

dr_mutex_unlock(mod_lock);

return DR_EMIT_DEFAULT;
}

static void event_exit(void) {
dr_mutex_destroy(mod_lock);
dr_mutex_destroy(wrap_lock);

free_drsmy();

dr_close_file(fd);

drmgr_exit();
drsym_exit();
drwrap_exit();
}

static void usage() {
dr_printf("  -disassembly\t\t\t\t\t disassemble all the functions\n");
dr_printf("  -disas_func function_name\t\t\t disassemble only the function function_name\n");
dr_printf("  -wrap_function function_name\t\t\t wrap the function function_name\n");
dr_printf("  -wrap_function_args num_args\t\t\t number of arguments of the wrapped function\n");
dr_printf("  -cbr\t\t\t\t\t\t remove the bb from the cache (in case of conditional jump)\n");
dr_printf("  -report_file file_name\t\t\t report file name\n");
dr_printf("  -verbose\t\t\t\t\t verbose true\n");
}

static void options_init(int argc, const char *argv[]) {
size_t i;
const char *disassembly;
const char *elem;

if (argc < 2) {
dr_printf("Invalid options!\n");
usage();
dr_abort();
}

options.disassembly = false;
options.verbose = false;
options.disassembly_function = false;
options.report_file = false;
options.wrap_function = false;
options.is_cbr = false;
options.wrap_function_args = 0;

for (i = 1; i < argc; i++) {
elem = argv[i];
if (strcmp(elem, "-disassembly") == 0)
options.disassembly = true;
else if (strcmp(elem, "-verbose") == 0)
options.verbose = true;
else if (strcmp(elem, "-disas_func") == 0) {
USAGE_CHECK((i + 1) < argc, "missing disassembly function");
elem = argv[++i];
if (strlen(elem) < LEN) {
options.disassembly_function = true;
memcpy(options.function_name, elem, LEN);
}
}
else if (strcmp(elem, "-report_file") == 0) {
USAGE_CHECK((i + 1) < argc, "missing report file");
elem = argv[++i];
if (strlen(elem) < LEN) {
options.report_file = true;
memcpy(options.report_file_name, elem, LEN);
}
}
else if (strcmp(elem, "-wrap_function") == 0) {
USAGE_CHECK((i + 1) < argc, "missing function to wrap");
elem = argv[++i];
if (strlen(elem) < LEN) {
options.wrap_function = true;
memcpy(options.wrap_function_name, elem, LEN);
}
}
else if (strcmp(elem, "-wrap_function_args") == 0) {
USAGE_CHECK((i + 1) < argc, "missing function arguments number");
elem = argv[++i];
if (options.wrap_function) {
options.wrap_function_args = strtoul(elem, NULL, 0);
}
else {
dr_printf("missing function to wrap!\n");
dr_abort();
}
}
else if (strcmp(elem, "-cbr") == 0) {
options.is_cbr = true;
}
else {
dr_printf("Invalid option %s \n", elem);
dr_abort();
}
}
}

DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) {
dr_set_client_name("functrace", "@invictus1306");

options_init(argc, argv);

drmgr_init();
drsym_init(0);
drwrap_init();

disassemble_set_syntax(DR_DISASM_INTEL);

mod_lock = dr_mutex_create();
wrap_lock = dr_mutex_create();

if (!options.report_file) {
dr_printf("The report file name is required!\n");
dr_abort();
}

fd = dr_open_file(options.report_file_name, DR_FILE_WRITE_OVERWRITE);
if (fd == INVALID_FILE) {
dr_printf("Unable to open log file %s\n", options.report_file_name);
dr_abort();
}

dr_register_exit_event(event_exit);
drmgr_register_module_load_event(event_module_load);
drmgr_register_bb_instrumentation_event(event_bb_analysis, NULL, NULL);
}

Hello. I'm trying to modificate functrace by invictus1306 https://github.com/invictus1306/functrace to wrap every func. but I have an error when I try to use wrap_post
<Application C:\Users\Admin\Downloads\test\Debug\test.exe (3892).  functrace internal crash at PC 0x6a501651.  Please report this at @invictus1306.  Program aborted.
0xc0000005 0x00000000 0x6a501651 0x6a501651 0x00000000 0x00000000
Base: 0x5f0c0000
Registers: eax=0x17b42ce8 ebx=0x00000000 ecx=0x0000000a edx=0x00000001
        esi=0x00000000 edi=0x17d56144 esp=0x17b3ea44 ebp=0x61171ea0
        eflags=0x0001
version 8.0.0, build 1
-no_dynamic_options -disasm_mask 1 -client_lib 'C:\Users\Admin\Downloads\myfunctrace\RelWithDebInfo\myfunctrace.dll;0;"-report_file" "myfuncreport"' -code_api -probe_api -stack_size 56K -max_elide_jmp 0 -max_elide_call 0 -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2dir
0x61171ea0 0x7d8b5756
C:\Users\Admin\Downloads\myfunctrace\RelWithDebInfo\myfunctrace.dll=0x61170000
C:\Windows/system32/ADVAPI32.dll=0x01760000
C:\Windows/system32/sechost.dll=0x017e0000
C:\Windows/system32/RPCRT4.dll=0x01860000
C:\Windows/system32/SspiCli.dll=0x00b50000
C:\Windows/system32/CRYPTBASE.dll=0x00b70000
C:\Windows/system32/bcryptPrimitives.dll=0x01040000
C:\Users\Admin\Downloads\DynamoRIO-Windows-8.0.0-1\ext\lib32\release/drwrap.dll=0x6a500000
C:\Users\A>
What's my mistake?

Derek Bruening

unread,
Feb 26, 2021, 10:01:54 AM2/26/21
to dynamor...@googlegroups.com
Did you try standard debugging steps of running debug build, getting a callstack of the crash, selectively undoing changes you made to the working base tool to determine which change causes the crash, etc.?
See https://github.com/DynamoRIO/dynamorio/wiki/Debugging.

I'm not sure asking others to pore over 500+ lines of code is the best approach: please minimize the problem, isolate the diff vs the working base tool, etc.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/d0e7982d-f21d-45a9-ba97-321e95061f4dn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages