Created
June 8, 2020 22:22
-
-
Save alastairparagas/0f5b5b95bd658c916d2a8883298248bd to your computer and use it in GitHub Desktop.
Libcall Handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// dynamorio api | |
#include "dr_api.h" | |
#include "drmgr.h" | |
#include "drwrap.h" | |
#include "drreg.h" | |
#include "drutil.h" | |
#include "drx.h" | |
#include "droption.h" | |
#include "winbase.h" | |
// standart c11 api | |
#include "windows.h" | |
#include <stddef.h> /* for offsetof */ | |
#include <stdio.h> | |
#include <string.h> /* for memset */ | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <exception> | |
// my api | |
#include "libcall_handler.h" | |
#include "utils.h" | |
#include "global.h" | |
#include "state_manager.h" | |
#include "command_manager.h" | |
using namespace std; | |
/** | |
* functions to hook the API methods | |
*/ | |
void | |
handle_module(void *drcontext, const module_data_t *mod, bool load) { | |
if(no_libcalls.get_value()) return; | |
monitor_target_function(drcontext); | |
if(only_app_libcalls.get_value()) | |
monitor_app_libcalls(drcontext, mod, load); | |
else if(only_config_libcalls.get_value()) | |
monitor_config_libcalls(drcontext, mod, load); | |
else if(all_libcalls.get_value()) | |
monitor_all_libcalls(drcontext, mod, load); | |
else { | |
process_id_t pid = dr_get_process_id(); | |
thread_id_t tid = dr_get_thread_id(drcontext); | |
WriteToLog("NOT_IMPLEMENTED | No libcall monitor option is specififed. \n"); | |
WriteToLog("NOT_IMPLEMENTED | Exiting the applications. \n"); | |
dr_exit_process(1); | |
} | |
} | |
// helper functions | |
static void | |
wrap_pre_target(void *wrapcxt, OUT void **user_data){ | |
//TODO | |
} | |
static void wrap_pre_4037b0(void *wrapcxt, OUT void **user_data) { | |
drwrap_skip_call( | |
wrapcxt, (LPVOID) 0x0, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(drwrap_get_arg(wrapcxt, 1)) | |
); | |
} | |
static void wrap_pre_404130(void *wrapcxt, OUT void **user_data) { | |
drwrap_skip_call( | |
wrapcxt, (void *) 0, (size_t) 0 | |
); | |
} | |
static void wrap_pre_402dd0(void *wrapcxt, OUT void **user_data) { | |
char *buffer = (char *) drwrap_get_arg(wrapcxt, 1); | |
strcpy(buffer, "response=$download-"); | |
drwrap_skip_call( | |
wrapcxt, (void *) 1, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(buffer) | |
); | |
} | |
static void wrap_pre_402f40(void *wrapcxt, OUT void **user_data) { | |
int *arg1 = (int *) drwrap_get_arg(wrapcxt, 1); | |
*arg1 = 1024; | |
drwrap_skip_call( | |
wrapcxt, (void *) 4, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(drwrap_get_arg(wrapcxt, 1)) | |
); | |
} | |
static void wrap_pre_403160(void *wrapcxt, OUT void **user_data) { | |
drwrap_skip_call( | |
wrapcxt, (void *) 1, (size_t) 0 | |
); | |
} | |
static void wrap_pre_402490(void *wrapcxt, OUT void **user_data) { | |
drwrap_skip_call( | |
wrapcxt, NULL, sizeof(drwrap_get_arg(wrapcxt, 0)) | |
); | |
} | |
static void | |
monitor_target_function(void *drcontext){ | |
app_pc f4037b0 = (app_pc) 0x4037b0; | |
drwrap_wrap(f4037b0, wrap_pre_4037b0, NULL); | |
app_pc f404130 = (app_pc) 0x404130; | |
drwrap_wrap(f404130, wrap_pre_404130, NULL); | |
app_pc f402dd0 = (app_pc) 0x402dd0; | |
drwrap_wrap(f402dd0, wrap_pre_402dd0, NULL); | |
app_pc f402f40 = (app_pc) 0x402f40; | |
drwrap_wrap(f402f40, wrap_pre_402f40, NULL); | |
app_pc f403160 = (app_pc) 0x403160; | |
drwrap_wrap(f403160, wrap_pre_403160, NULL); | |
app_pc f402490 = (app_pc) 0x402490; | |
drwrap_wrap(f402490, wrap_pre_402490, NULL); | |
} | |
static void | |
monitor_app_libcalls(void *drcontext, const module_data_t *mod, bool load) { | |
dr_symbol_export_iterator_t *ei = dr_symbol_export_iterator_start(mod->handle); | |
while(dr_symbol_export_iterator_hasnext(ei)) { | |
dr_symbol_export_t *sym = dr_symbol_export_iterator_next(ei); | |
// skip the loading time api calls | |
if(strcmp(sym->name, "ExpInterlockedPopEntrySListResume") == 0) continue; | |
if(strcmp(sym->name, "ExpInterlockedPopEntrySListFault") == 0) continue; | |
if(strcmp(sym->name, "ExpInterlockedPopEntrySListEnd") == 0) continue; | |
// if(strcmp(sym->name, "RtlEnterCriticalSection") == 0) continue; | |
// if(strcmp(sym->name, "RtlLeaveCriticalSection") == 0) continue; | |
app_pc towrap = (sym->is_code) ? sym->addr : NULL; | |
if(towrap != NULL) { | |
bool ok = drwrap_wrap_ex(towrap, wrap_pre_lib, wrap_post_lib, (void *) sym->name, 0); | |
// if(ok) dr_printf("%d.%d | WRAP_SUCCESS | %s @ "PFX" \n", cur_pid, cur_tid, sym->name, towrap); | |
// else dr_printf("%d.%d | WRAP_FAIL | %s @ "PFX" | PID:%d | TID:%d \n", cur_pid, cur_tid, sym->name, towrap); | |
} | |
} | |
} | |
static void | |
monitor_config_libcalls(void *drcontext, const module_data_t *mod, bool load){ | |
api_table_t::iterator it; | |
if(strcmp(dr_module_preferred_name(mod), "KERNELBASE.dll") == 0) return; // skip the kernel base for now | |
for(it = config_libcalls.begin(); it != config_libcalls.end(); it++) { | |
const char *fname = it->first.c_str(); | |
app_pc towrap = (app_pc) dr_get_proc_address(mod->handle, fname); | |
if(towrap != NULL) { | |
bool ok = drwrap_wrap_ex(towrap, wrap_pre_lib, wrap_post_lib, (void *)fname, 0); // DRWRAP_UNWIND_ON_EXCEPTION); | |
if(ok) WriteToLog("WRAP_SUCCESS | %s @ "PFX" \n", fname, towrap); | |
else WriteToLog("WRAP_FAIL | %s @ "PFX" | PID:%d | TID:%d \n", fname, towrap); | |
} | |
} | |
} | |
static void | |
monitor_all_libcalls(void *drcontext, const module_data_t *mod, bool load){ | |
dr_symbol_export_iterator_t *ei = dr_symbol_export_iterator_start(mod->handle); | |
while(dr_symbol_export_iterator_hasnext(ei)) { | |
dr_symbol_export_t *sym = dr_symbol_export_iterator_next(ei); | |
app_pc towrap = (sym->is_code) ? sym->addr : NULL; | |
if(towrap != NULL) { | |
drwrap_wrap_ex(towrap, wrap_pre_lib, NULL, (void *) sym->name, 0); | |
} | |
} | |
} | |
static void | |
stupid_thread_func() { | |
WriteToLog("stupid thread func \n"); | |
} | |
static void | |
enforce_follow_child(string child_name) { | |
char *drconfig = "C:\\code\\dynamorio\\build\\bin32\\drconfig.exe"; | |
char *app = (char *) child_name.c_str(); | |
char *library = "C:\\code\\concrete_executor\\build\\RelWithDebInfo\\tracer.dll"; | |
char *exetype = "trace"; | |
if(trace_then_concolic.get_value()) exetype = "trace_then_concolic"; | |
else if (concolic.get_value()) exetype = "concolic"; | |
char *libcalls = "only_config_libcalls"; | |
if(only_app_libcalls.get_value()) libcalls = "only_app_libcalls"; | |
else if(all_libcalls.get_value()) libcalls = "all_libcalls"; | |
char *base = (char *) static_base.get_value().c_str(); | |
WriteToProcessLog("bse is %s \n", static_base.get_value().c_str()); | |
WriteToProcessLog("bse is %s \n", base); | |
char cmd[4096]; | |
if(trace_then_concolic.get_value()) { | |
char *caddr = (char *) concolic_address.get_value().c_str(); | |
char *fmt = "%s -reg %s -syswide_on -c %s -%s -concolic_address %s -%s -%s -static_base %s"; | |
dr_snprintf(cmd, sizeof(cmd) / sizeof(cmd[0]), fmt, | |
drconfig, app, library, exetype, caddr, "child", libcalls, static_base.get_value().c_str()); | |
} else { | |
char *fmt = "%s -reg %s -syswide_on -c %s -%s -%s -%s -static_base %s"; | |
dr_snprintf(cmd, sizeof(cmd) / sizeof(cmd[0]), fmt, | |
drconfig, app, library, exetype, "child", libcalls, static_base.get_value().c_str()); | |
} | |
WriteToProcessLog("DEBUG: ENFORCE_CHILD : %s \n", cmd); | |
system(cmd); | |
WriteToProcessLog("DEBUG: after system \n", cmd); | |
} | |
static string last_api_call; | |
static vector<void *> args; | |
/** | |
* library hook management | |
*/ | |
static void | |
wrap_pre_lib(void *wrapcxt, OUT void **user_data) { | |
// collect information | |
string func_name = (const char *) *user_data; | |
last_api_call = func_name; | |
app_pc func_addr = drwrap_get_func(wrapcxt); | |
string mod_name; | |
module_data_t *dll_mod = dr_lookup_module(func_addr); | |
if(dll_mod != NULL) mod_name = dr_module_preferred_name(dll_mod); | |
string name (mod_name + "!" + func_name); | |
dr_free_module_data(dll_mod); | |
void *drcontext = drwrap_get_drcontext(wrapcxt); | |
process_id_t cur_pid = dr_get_process_id(); | |
thread_id_t cur_tid = dr_get_thread_id(drcontext); | |
// forcin the auto injection | |
if(func_name.find("CreateProcessA") != -1 || func_name.find("CreateProcessW") != -1) { | |
void *arg0 = drwrap_get_arg(wrapcxt, 0); | |
char binpath[255]; | |
if(func_name.find("CreateProcessW") != -1) | |
dr_snprintf(binpath, sizeof(binpath) / sizeof(binpath[0]), "%S", arg0); | |
else | |
dr_snprintf(binpath, sizeof(binpath) / sizeof(binpath[0]), "%s", arg0); | |
vector<string> tokens = split(binpath, '\\'); | |
string app_name = tokens.back(); | |
WriteToProcessLog("Fname %s - %s \n", name.c_str(), func_name.c_str()); | |
enforce_follow_child(app_name); | |
} | |
if(func_name.compare("WriteProcessMemory") == 0) { | |
char *msg = "message from WriteProcessMemory start end"; | |
void *pprocess = drwrap_get_arg(wrapcxt, 0); | |
DWORD pinfo = GetProcessId((HANDLE) pprocess); | |
void *baseaddr = drwrap_get_arg(wrapcxt, 1); | |
void *nsize = drwrap_get_arg(wrapcxt, 3); | |
// app_pc endaddr = (app_pc) (*((int *) baseaddr) + *((int *)nsize)); | |
WriteToSharedMem("\nPID_INJECT;%d;"PIFX";"PIFX"", pinfo, baseaddr, nsize); | |
} | |
if(func_name.compare("InternetOpenA") == 0) { | |
drwrap_skip_call( | |
wrapcxt, (void *) 1, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(drwrap_get_arg(wrapcxt, 1)) + sizeof( | |
drwrap_get_arg(wrapcxt, 2) | |
) + sizeof(drwrap_get_arg(wrapcxt, 3)) + sizeof(drwrap_get_arg(wrapcxt, 4)) | |
); | |
} | |
if(func_name.compare("InternetConnectA") == 0 || func_name.compare("HttpOpenRequestA") == 0) { | |
drwrap_skip_call( | |
wrapcxt, (void *) 1, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(drwrap_get_arg(wrapcxt, 1)) + sizeof( | |
drwrap_get_arg(wrapcxt, 2) | |
) + sizeof(drwrap_get_arg(wrapcxt, 3)) + sizeof(drwrap_get_arg(wrapcxt, 4)) + sizeof( | |
drwrap_get_arg(wrapcxt, 5) | |
) + sizeof(drwrap_get_arg(wrapcxt, 6)) + sizeof(drwrap_get_arg(wrapcxt, 7)) | |
); | |
} | |
if(func_name.compare("HttpSendRequestA") == 0) { | |
drwrap_skip_call( | |
wrapcxt, (void *) true, | |
sizeof(drwrap_get_arg(wrapcxt, 0)) + sizeof(drwrap_get_arg(wrapcxt, 1)) + sizeof( | |
drwrap_get_arg(wrapcxt, 2) | |
) + sizeof(drwrap_get_arg(wrapcxt, 3)) + sizeof(drwrap_get_arg(wrapcxt, 4)) | |
); | |
} | |
// checks the configuration and allows accordingly for logging the library information | |
// if(only_app_libcalls.get_value() || only_config_libcalls.get_value()) { | |
app_pc retaddr = NULL; | |
DR_TRY_EXCEPT(drcontext, { | |
retaddr = drwrap_get_retaddr(wrapcxt); | |
}, { /* EXCEPT */ | |
retaddr = NULL; | |
}); | |
// fix here when injection happens | |
if(retaddr != NULL) { | |
module_data_t *ret_mod = dr_lookup_module(retaddr); | |
if(ret_mod != NULL) { | |
app_pc app_start = (StateManager::instance()->inject_base == NULL) ? StateManager::instance()->exe_start : StateManager::instance()->inject_base; | |
bool from_app = (ret_mod->start == app_start); | |
dr_free_module_data(ret_mod); | |
if(!from_app) { | |
*user_data = ""; | |
if(only_app_libcalls.get_value() || only_config_libcalls.get_value()) | |
return; | |
} | |
} | |
} | |
// } | |
// log the library information | |
WriteToProcessLog("---> | %s \n", name.c_str()); | |
WriteToLog("---> | %s | ", name.c_str()); | |
api_table_t::iterator found = config_libcalls.find(func_name); | |
if(found != config_libcalls.end()) print_pre_args(wrapcxt, func_name); | |
WriteToLog("\n"); | |
pc2mod[func_addr] = name; | |
if(found == config_libcalls.end()) return; | |
// // spark -- print messagebox skip user interatction | |
// if(func_name.compare("MessageBoxA") == 0) { | |
// // char *msg = (char *)drwrap_get_arg(wrapcxt, 1); | |
// // char *title = (char *)drwrap_get_arg(wrapcxt, 2); | |
// // dr_printf("MessageBox : %s : %s", msg, title); | |
// drwrap_skip_call(wrapcxt, (void *) 1, 0); | |
// } | |
// pass all the arguments to post callback via map holding api to arg addresses | |
args.clear(); | |
param_list_t param_list = config_libcalls[func_name]; | |
param_list_t::iterator it; | |
for(it = param_list.begin(); it != param_list.end(); ++it) { | |
if(it->ordinal == -1) continue; | |
void *param_addr = drwrap_get_arg(wrapcxt, it->ordinal); | |
// if(it->mode == PARAM_OUT || it->mode == PARAM_INOUT) *user_data = param_addr; | |
args.push_back(param_addr); | |
} | |
} | |
static void | |
wrap_post_lib(void *wrapcxt, void *user_data) { | |
// there are cases when DR misses the func addr | |
app_pc func_addr = drwrap_get_func(wrapcxt); | |
string nameee = pc2mod[func_addr]; | |
// dr_printf("here map %s", nameee.c_str()); | |
const char *name = (const char *) user_data; | |
// dr_printf("here name %s\n", name); | |
if(lstrlen(name) == 0) return; | |
void * drcontext = dr_get_current_drcontext(); | |
thread_id_t cur_tid = dr_get_thread_id(drcontext); | |
process_id_t cur_pid = dr_get_process_id(); | |
// checks the configuration and allows accordingly for logging the library information | |
// if(only_app_libcalls.get_value()) { | |
// app_pc retaddr = NULL; | |
// DR_TRY_EXCEPT(drcontext, { | |
// retaddr = drwrap_get_retaddr(wrapcxt); | |
// }, { /* EXCEPT */ | |
// retaddr = NULL; | |
// }); | |
// if(retaddr != NULL) { | |
// module_data_t *ret_mod = dr_lookup_module(retaddr); | |
// if(ret_mod != NULL) { | |
// app_pc app_start = (StateManager::instance()->inject_base == NULL) ? StateManager::instance()->exe_start : StateManager::instance()->inject_base; | |
// bool from_app = (ret_mod->start == app_start); | |
// dr_free_module_data(ret_mod); | |
// if(!from_app) return; | |
// } | |
// } | |
// } | |
// handle the post call commands by angr such as updating the memory or return value | |
// sometimes func_addr returns 0 by wrapcxt | |
// then the line below fails on catching the func name | |
// string func_name = split(nameee.c_str(), '!')[1]; | |
string func_name (name); | |
if(config_libcalls.find(func_name) == config_libcalls.end()) return; | |
std::string hooked_func = CommandManager::instance()->map_cmd["function"]; | |
if(hooked_func.compare(func_name) == 0) { | |
std::string post_task = CommandManager::instance()->map_cmd["task"]; | |
if(post_task.compare("set_retval") == 0) { | |
std::string str_retval = CommandManager::instance()->map_cmd["retval"]; | |
void *retval = (void*)0; | |
if(str_retval.compare("1") == 0) | |
retval = (void*) 1; | |
// dr_printf("udpateing the retval %s : %d \n", str_retval.c_str(), retval); | |
bool ok = drwrap_set_retval(wrapcxt, (void*)retval); | |
// CommandManager::instance()->clean_command(); | |
} | |
else if(post_task.compare("set_argval") == 0){ | |
std::string str_argtype = CommandManager::instance()->map_cmd["argtype"]; | |
std::string str_argmode = CommandManager::instance()->map_cmd["argmode"]; | |
if(str_argmode.compare("out") != 0) return; /* return when the input is not filled by function */ | |
WriteToLog("here it passes the comparasion %s\n", func_name.c_str()); | |
std::string str_argval = CommandManager::instance()->map_cmd["argval"]; | |
std::string str_argordinal = CommandManager::instance()->map_cmd["ordinal"]; | |
WriteToLog("str arg ord is %s \n", str_argordinal.c_str()); | |
int argordinal = (int) StateManager::instance()->hex2app_pc(str_argordinal); | |
WriteToLog("int arg ord is %d\n", argordinal); | |
param_list_t param_list = config_libcalls[func_name]; | |
param_t arg_info ; //= param_list[argordinal+1]; // add 1 to adjust return val first | |
param_list_t::iterator it; | |
for(it = param_list.begin(); it != param_list.end(); ++it) { | |
arg_info = *it; | |
WriteToLog("ord is now %d\n", arg_info.ordinal); | |
if(arg_info.ordinal == argordinal) break; | |
} | |
if(arg_info.type == TYPE_PINT) { | |
WriteToLog("the type is pint \n"); | |
int *arg_addr = (int *) args[argordinal]; | |
WriteToLog("the argordinal is %d \n", argordinal); | |
int argval = (int) StateManager::instance()->str2int(str_argval); | |
WriteToLog("the argval is %d \n", argval); | |
*arg_addr = argval; | |
memcpy(arg_addr, (unsigned char*) &argval, sizeof(int)); | |
WriteToLog("here it pass \n"); | |
// *arg_addr = 1; // angr produces too big value, add concr strg to get the smallest psb. value | |
// CommandManager::instance()->clean_command(); | |
} | |
else if(arg_info.type = TYPE_CHAR) { | |
WriteToLog("Handle the char * for val update\n"); | |
string aaa; | |
cin >> aaa; | |
} | |
// memcpy(args[argordinal], str_argval.c_str(), strlen(str_argval.c_str()) + 1); | |
} | |
} | |
// log the library call information | |
WriteToLog(" <--- | %s \n | ", nameee); | |
api_table_t::iterator found = config_libcalls.find(func_name); | |
if(found != config_libcalls.end()) print_post_args(wrapcxt, func_name, func_addr, user_data); | |
WriteToLog("\n"); | |
} | |
/** | |
* print the function and arguments | |
*/ | |
static void | |
print_pre_args(void *wrapcxt, string func_name) { | |
param_list_t param_list = config_libcalls[func_name]; | |
// // if(param_list == NULL) return; | |
param_list_t::iterator it; | |
for(it = param_list.begin(); it != param_list.end(); ++it) { | |
param_t param = *it; | |
// dr_printf("here02 %d\n", param.ordinal); | |
if(param.ordinal == -1) continue; | |
// if(param.mode == PARAM_IN || param.mode == PARAM_INOUT) print_arg(wrapcxt, param, true/*use wrapcxt */); | |
if(param.mode != PARAM_OUT) print_arg(wrapcxt, param, true/*use wrapcxt */); | |
} | |
} | |
static void | |
print_post_args(void *wrapcxt, string func_name, app_pc func_addr, void *user_data) { | |
param_list_t param_list = config_libcalls[func_name]; | |
// arg_val_list_t arg_val_list = arg_values[func_addr]; | |
// // if(param_list == NULL) return; | |
param_list_t::iterator it; | |
for(it = param_list.begin(); it != param_list.end(); ++it) { | |
param_t param = *it; | |
// void *cuser_data = (void*)(((char*)user_data) + it->ordinal); | |
if(param.ordinal == -1 && param.type != TYPE_NULL) print_arg(wrapcxt, param, true/* use wrapcxt */); | |
else if(param.mode == PARAM_OUT || param.mode == PARAM_INOUT) print_arg(args[it->ordinal], param, false/* use user_data */); | |
} | |
} | |
static void | |
print_arg(void *wrapcxt, param_t param, bool source) { | |
void *drcontext = dr_get_current_drcontext(); | |
void *param_value; | |
if(param.ordinal == -1) param_value = drwrap_get_retval(wrapcxt); | |
else if(source) param_value = drwrap_get_arg(wrapcxt, param.ordinal); | |
else param_value = wrapcxt; | |
int *ii; | |
int i; | |
switch (param.type) | |
{ | |
case TYPE_DWORD: | |
case TYPE_SIZE_T: | |
case TYPE_PVOID: | |
case TYPE_HANDLE: | |
case TYPE_START_ROUTINE: | |
WriteToLog("%d:"PIFX" ;", param.ordinal, param_value); | |
break; | |
case TYPE_UINT: | |
WriteToLog("%d:%u ;", param.ordinal, param_value); | |
break; | |
case TYPE_PINT: | |
ii = (int *)param_value; | |
i = *ii; | |
// dr_printf("address of size "PFX"\n", param_value); | |
WriteToLog("%d:%d ;", param.ordinal, i); | |
// dr_printf(" %d:%d ;", param.ordinal, param_value); | |
break; | |
case TYPE_BOOL: | |
case TYPE_INT: | |
WriteToLog("%d:%d ;", param.ordinal, param_value); | |
break; | |
case TYPE_CHAR: | |
DR_TRY_EXCEPT(drcontext, { | |
WriteToLog("%d:%s ;", param.ordinal, param_value); | |
}, { | |
WriteToLog("%d:"PFX"[invalid_memory] ;", param.ordinal, param_value); | |
}); | |
break; | |
case TYPE_WCHAR: | |
DR_TRY_EXCEPT(drcontext, { | |
WriteToLog("%d:%S ;", param.ordinal, param_value); | |
}, { | |
WriteToLog("%d:"PFX"[invalid_memory] ;", param.ordinal, param_value); | |
}); | |
break; | |
case TYPE_PHANDLE: | |
WriteToLog(" %d:%d ;", param.ordinal, GetProcessId((HANDLE) param_value)); | |
break; | |
case TYPE_THANDLE: | |
WriteToLog(" %d:%d ;", param.ordinal, GetThreadId((HANDLE) param_value)); | |
break; | |
case TYPE_PPROCESSINFO: | |
PPROCESS_INFORMATION ppi = (PPROCESS_INFORMATION) param_value; | |
PROCESS_INFORMATION pi = *ppi; | |
WriteToLog(" %d:%d , %d ;", param.ordinal, pi.dwProcessId, pi.dwThreadId); | |
break; | |
} | |
} | |
/** | |
* parse config file | |
*/ | |
void | |
parse_config() { | |
file_t fd = INVALID_FILE; | |
uint64 file_size = 0; | |
void *map = NULL; | |
fd = dr_open_file("C:/code/concrete_executor/tracer/windows_api.config", DR_FILE_READ); | |
dr_file_size(fd, &file_size); | |
map = dr_map_file(fd, (size_t *)(&file_size), 0, NULL, DR_MEMPROT_READ, 0); | |
if(! map) { | |
WriteToLog("Error on loading the config file. \n"); | |
WriteToLog("Exiting the process. \n"); | |
dr_exit_process(1); | |
} | |
vector<string> api_list = split((const char *)map, '\n'); | |
// close the file descriptor and related sources | |
dr_unmap_file(map, (size_t)(file_size)); | |
dr_close_file(fd); | |
vector<string>::iterator it; | |
for(it = api_list.begin(); it != api_list.end(); it++) { | |
const char *api = it->c_str(); | |
if(api[0] == '#') continue; | |
vector<string> api_tokens = split(api, '|'); | |
if(api_tokens.size() == 0) continue; | |
if(api_tokens.size() == 1) continue; | |
string fname = api_tokens[1]; | |
// dr_printf("%s { \n", fname.c_str()); | |
param_list_t param_list; | |
int idx = -1; | |
vector<string>::iterator token_it; | |
for(token_it = api_tokens.begin(); token_it != api_tokens.end(); ++token_it) { | |
idx++; | |
if(idx == 1) continue; // skip the token holding the name of the function | |
int ordinal = idx -2; // retval|fname|arg0|arg1 etc. subract idx by 2 to get the original ordinal | |
if(idx == 0) ordinal = -1; // -1 holds the ret val on the arglist | |
// dr_printf(" %d:%s, ", ordinal, token_it->c_str()); | |
param_t param = parse_param(*token_it, ordinal); | |
param_list.push_back(param); | |
} | |
// dr_printf("}; \n\n"); | |
config_libcalls[fname] = param_list; | |
} | |
} | |
static param_t | |
parse_param(string token, int ordinal) { | |
param_t param; | |
param.ordinal = ordinal; // -1 for the retval | |
// set in out mode | |
param.mode = PARAM_NONE; | |
if(token.find("__inout") != -1) | |
param.mode = PARAM_INOUT; | |
else if(token.find("__out") != -1) | |
param.mode = PARAM_OUT; | |
else if(token.find("__in") != -1) | |
param.mode = PARAM_IN; | |
param.type = TYPE_NULL; | |
// set the type and typeChar | |
param.type_str = token.c_str(); | |
if(token.find("void*") != -1) param.type = TYPE_PVOID; | |
else if(token.find("void") != -1) param.type = TYPE_VOID; | |
else if(token.find("uint") != -1) param.type = TYPE_UINT; | |
else if(token.find("int*") != -1) param.type = TYPE_PINT; | |
else if(token.find("int") != -1) param.type = TYPE_INT; | |
else if(token.find("DWORD") != -1) param.type = TYPE_DWORD; | |
else if(token.find("wchar*") != -1) param.type = TYPE_WCHAR; | |
else if(token.find("char") != -1) param.type = TYPE_CHAR; | |
else if(token.find("PROCESS_INFORMATION*") != -1) param.type = TYPE_PPROCESSINFO; | |
else if(token.find("PHANDLE") != -1) param.type = TYPE_PHANDLE; | |
else if(token.find("THANDLE") != -1) param.type = TYPE_THANDLE; | |
else if(token.find("HANDLE") != -1) param.type = TYPE_HANDLE; | |
else if(token.find("HMODULE") != -1) param.type = TYPE_HANDLE; | |
else if(token.find("THREAD_START_ROUTINE*") != -1) param.type = TYPE_START_ROUTINE; | |
else if(token.find("size_t") != -1) param.type = TYPE_SIZE_T; | |
else if(token.find("bool") != -1) param.type = TYPE_BOOL; | |
else if(token.find("BOOL") != -1) param.type = TYPE_BOOL; | |
else if(token.find("NULL") != -1) param.type = TYPE_NULL; | |
return param; | |
} | |
/* | |
std::string split implementation by using delimiter as a character. | |
*/ | |
static vector<string> | |
split(const char *strToSplit, char delimeter) | |
{ | |
stringstream ss; | |
ss.str((strToSplit)); | |
string item; | |
vector<string> splittedStrings; | |
while (getline(ss, item, delimeter)) | |
splittedStrings.push_back(item); | |
return splittedStrings; | |
} | |
/// handle the direct/indirect calls | |
void | |
at_indirect_call(app_pc callsite, app_pc target_fn) { | |
void *drcontext = dr_get_current_drcontext(); | |
process_id_t pid = dr_get_process_id(); | |
thread_id_t tid = dr_get_thread_id(drcontext); | |
app_pc sta_pc = StateManager::instance()->convert_dynamic_to_static(callsite); | |
app_pc sta_fn = StateManager::instance()->convert_dynamic_to_static(target_fn); | |
WriteToLog("CALL_INDIRECT |"PFX" | "PFX" ["PFX"] \n", sta_pc, target_fn, sta_fn); | |
// dr_printf("[%s] \n", pc2mod[target_fn].c_str()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment