Skip to content

Instantly share code, notes, and snippets.

@orisano
Last active August 14, 2016 07:11
Show Gist options
  • Save orisano/7eff521a2e59d5392c4dac25c1bb75ef to your computer and use it in GitHub Desktop.
Save orisano/7eff521a2e59d5392c4dac25c1bb75ef to your computer and use it in GitHub Desktop.
#include "DECAF_types.h"
#include "DECAF_main.h"
#include "DECAF_callback.h"
#include "DECAF_callback_common.h"
#include "vmi_callback.h"
#include "utils/Output.h"
#include "DECAF_target.h"
#include "hookapi.h"
static plugin_interface_t geteip_interface;
static DECAF_Handle processbegin_handle = DECAF_NULL_HANDLE;
static DECAF_Handle blockbegin_handle = DECAF_NULL_HANDLE;
char targetname[512];
uint32_t target_cr3;
typedef struct {
uint32_t ret_addr;
DECAF_Handle hook_handle;
} hook_context_t;
typedef uint32_t addr_t;
#define HOOK_INIT(fn, arg, hook_call, hook_ret) \
struct fn##_arg_t { arg; } fn##_arg; \
static void fn##_ret(void *param) { \
hook_context_t* ctx = (hook_context_t*)param; \
struct fn##_arg_t* arguments = &fn##_arg; \
DECAF_printf("%s::ret\n", #fn); \
hookapi_remove_hook(ctx->hook_handle); \
free(ctx); \
hook_ret; \
} \
static void fn##_call(void* opaque) { \
struct fn##_arg_t* arguments = &fn##_arg; \
hook_context_t* ctx = (hook_context_t*)malloc(sizeof(hook_context_t)); \
if (!ctx) return; \
DECAF_printf("%s::call\n", #fn); \
DECAF_read_mem(NULL, cpu_single_env->regs[R_ESP], 4, &ctx->ret_addr); \
DECAF_read_mem(NULL, cpu_single_env->regs[R_ESP] + 4, sizeof(fn##_arg), &fn##_arg); \
ctx->hook_handle = hookapi_hook_return(ctx->ret_addr, fn##_ret, ctx, sizeof(*ctx)); \
hook_call; \
} \
static DECAF_Handle fn##_handle = DECAF_NULL_HANDLE
#define HOOK_FUNC(fn, dll_or_lib) fn##_handle = hookapi_hook_function_byname(dll_or_lib, #fn, 1, target_cr3, fn##_call, NULL, 0)
HOOK_INIT(URLDownloadToFileW, addr_t pCaller; addr_t szURL,
{},
{
int i;
if (cpu_single_env->regs[R_EAX] == 0) {
char url[256];
DECAF_read_mem(NULL, arguments->szURL, sizeof(url), url);
DECAF_printf("today's C2Server => ");
for (i = 0; url[i]; i += 2) {
DECAF_printf("%c", url[i]);
}
DECAF_printf("\n");
}
});
HOOK_INIT(ReadFile,
addr_t file_handle; addr_t buf_addr; uint32_t buf_size; addr_t size_addr,
{},
{
uint32_t size;
char buf[2048];
DECAF_read_mem(NULL, arguments->size_addr, 4, &size);
if (size < sizeof(buf)) {
DECAF_read_mem(NULL, arguments->buf_addr, size, buf);
buf[size] = 0;
DECAF_printf("file:\n%s\n", buf);
} else {
DECAF_printf("file size too large (2048<)\n");
}
});
static void geteip_block_begin_callback(DECAF_Callback_Params* params)
{
if(params->bb.env->cr[3] == target_cr3)
{
target_ulong eip = params->bb.env->eip;
target_ulong eax = params->bb.env->regs[R_EAX];
// DECAF_printf("EIP = 0x%08x, EAX = 0x%08x\n", eip, eax);
}
}
static void geteip_loadmainmodule_callback(VMI_Callback_Params* params)
{
if(strcmp(params->cp.name,targetname) == 0)
{
DECAF_printf("Process %s you spcecified starts \n", params->cp.name);
target_cr3 = params->cp.cr3;
HOOK_FUNC(URLDownloadToFileW, "urlmon.dll");
HOOK_FUNC(ReadFile, "kernel32.dll");
blockbegin_handle = DECAF_register_callback(DECAF_BLOCK_BEGIN_CB, &geteip_block_begin_callback, NULL);
}
}
void do_monitor_proc(Monitor* mon, const QDict* qdict)
{
if ((qdict != NULL) && (qdict_haskey(qdict, "procname")))
strncpy(targetname, qdict_get_str(qdict, "procname"), 512);
targetname[511] = '\0';
DECAF_printf("Ready to track %s\n", targetname);
}
static int geteip_init(void)
{
DECAF_printf("Hello, World!\n");
processbegin_handle = VMI_register_callback(VMI_CREATEPROC_CB, &geteip_loadmainmodule_callback, NULL);
if (processbegin_handle == DECAF_NULL_HANDLE)
DECAF_printf("Could not register for the create or remove proc events\n");
return 0;
}
static void geteip_cleanup(void)
{
DECAF_printf("Bye, World\n");
if (processbegin_handle != DECAF_NULL_HANDLE)
{
VMI_unregister_callback(VMI_CREATEPROC_CB, processbegin_handle);
processbegin_handle = DECAF_NULL_HANDLE;
}
if (blockbegin_handle != DECAF_NULL_HANDLE)
{
DECAF_unregister_callback(DECAF_BLOCK_BEGIN_CB, blockbegin_handle);
blockbegin_handle = DECAF_NULL_HANDLE;
}
}
static mon_cmd_t geteip_term_cmds[] =
{
#include "plugin_cmds.h"
{NULL, NULL, },
};
plugin_interface_t* init_plugin(void)
{
geteip_interface.mon_cmds = geteip_term_cmds;
geteip_interface.plugin_cleanup = &geteip_cleanup;
geteip_init();
return (&geteip_interface);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment