Skip to content

Commit

Permalink
Fix 64-bit hooking, improve debugging, support older processors
Browse files Browse the repository at this point in the history
  • Loading branch information
spender-sandbox committed Jan 22, 2016
1 parent 8f29c84 commit c95495a
Show file tree
Hide file tree
Showing 13 changed files with 337 additions and 154 deletions.
2 changes: 2 additions & 0 deletions bson/bson.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
<AdditionalOptions>/Qsafe_fp_loads %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
Expand Down
2 changes: 1 addition & 1 deletion config.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ int read_config(void)
#endif
}
else if (!strcmp(key, "disable_hook_content")) {
g_config.disable_hook_content = value[0] == '1';
g_config.disable_hook_content = atoi(value);
}
/*
else if(!strcmp(key, "host-ip")) {
Expand Down
5 changes: 5 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#ifndef __CONFIG_H
#define __CONFIG_H

/*
Cuckoo Sandbox - Automated Malware Analysis
Copyright (C) 2010-2012 Cuckoo Sandbox Developers
Expand Down Expand Up @@ -101,3 +104,5 @@ struct _g_config {
extern struct _g_config g_config;

int read_config(void);

#endif
68 changes: 54 additions & 14 deletions cuckoomon.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ void disable_tail_call_optimization(void)
#define CUCKOODBG 0
#endif

#define HOOK(library, funcname) {L###library, #funcname, NULL, \
#define HOOK(library, funcname) {L###library, #funcname, NULL, NULL, \
&New_##funcname, (void **) &Old_##funcname, NULL, FALSE, 0, FALSE}

#define HOOK_SPECIAL(library, funcname) {L###library, #funcname, NULL, \
#define HOOK_SPECIAL(library, funcname) {L###library, #funcname, NULL, NULL, \
&New_##funcname, (void **) &Old_##funcname, NULL, TRUE, 0, FALSE}

#define HOOK_NOTAIL_ALT(library, funcname, numargs) {L###library, #funcname, NULL, \
#define HOOK_NOTAIL_ALT(library, funcname, numargs) {L###library, #funcname, NULL, NULL, \
&New_##funcname, (void **) &Old_##funcname, &Alt_##funcname, TRUE, numargs, TRUE}

#define HOOK_NOTAIL(library, funcname, numargs) {L###library, #funcname, NULL, \
#define HOOK_NOTAIL(library, funcname, numargs) {L###library, #funcname, NULL, NULL, \
&New_##funcname, NULL, NULL, TRUE, numargs, TRUE}

static hook_t g_hooks[] = {
Expand Down Expand Up @@ -249,7 +249,8 @@ static hook_t g_hooks[] = {

HOOK_NOTAIL(user32, CreateWindowExA, 12),
HOOK_NOTAIL(user32, CreateWindowExW, 12),
HOOK(user32, FindWindowA),

HOOK(user32, FindWindowA),
HOOK(user32, FindWindowW),
HOOK(user32, FindWindowExA),
HOOK(user32, FindWindowExW),
Expand All @@ -263,8 +264,8 @@ static hook_t g_hooks[] = {
HOOK(user32, SetWindowLongW),
HOOK(user32, SetWindowLongPtrA),
HOOK(user32, SetWindowLongPtrW),

//
//
// Sync Hooks
//

Expand All @@ -273,7 +274,9 @@ static hook_t g_hooks[] = {
HOOK(ntdll, NtCreateEvent),
HOOK(ntdll, NtOpenEvent),
HOOK(ntdll, NtCreateNamedPipeFile),
//


//
// Process Hooks
//

Expand Down Expand Up @@ -376,6 +379,8 @@ static hook_t g_hooks[] = {
//
// Network Hooks
//


HOOK(netapi32, NetUserGetInfo),
HOOK(netapi32, NetGetJoinInformation),
HOOK(netapi32, NetUserGetLocalGroups),
Expand Down Expand Up @@ -553,13 +558,16 @@ void set_hooks_dll(const wchar_t *library)
}
}

extern void invalidate_regions_for_hook(const hook_t *hook);

void revalidate_all_hooks(void)
{
int i;
for (i = 0; i < ARRAYSIZE(g_hooks); i++) {
if (g_hooks[i].addr && !is_valid_address_range((ULONG_PTR)g_hooks[i].addr, 1)) {
if (g_hooks[i].hook_addr && !is_valid_address_range((ULONG_PTR)g_hooks[i].hook_addr, 1)) {
g_hooks[i].is_hooked = 0;
g_hooks[i].addr = NULL;
g_hooks[i].hook_addr = NULL;
invalidate_regions_for_hook(&g_hooks[i]);
}
}
}
Expand All @@ -571,9 +579,16 @@ VOID CALLBACK DllLoadNotification(
_In_ const PLDR_DLL_NOTIFICATION_DATA NotificationData,
_In_opt_ PVOID Context)
{
PWCHAR dllname;
COPY_UNICODE_STRING(library, NotificationData->Loaded.BaseDllName);

if (g_config.debug) {
int ret = 0;
/* Just for debug purposes, gives a stripped fake function name */
LOQ_void("system", "sup", "NotificationReason", NotificationReason == 1 ? "load" : "unload", "DllName", library.Buffer, "DllBase", NotificationReason == 1 ? NotificationData->Loaded.DllBase : NotificationData->Unloaded.DllBase);
}

if (NotificationReason == 1) {
PWCHAR dllname;
COPY_UNICODE_STRING(library, NotificationData->Loaded.BaseDllName);

if (g_config.file_of_interest && !wcsicmp(library.Buffer, g_config.file_of_interest))
set_dll_of_interest((ULONG_PTR)NotificationData->Loaded.DllBase);
Expand Down Expand Up @@ -658,13 +673,26 @@ void set_hooks()
hook_enable();
}

static int parse_stack_trace(void *msg, ULONG_PTR addr)
{
unsigned int offset;
char *buf = convert_address_to_dll_name_and_offset(addr, &offset);
if (buf) {
snprintf((char *)msg + strlen(msg), sizeof(msg) - strlen(msg) - 1, " %s+%x", buf, offset);
free(buf);
}

return 0;
}

LONG WINAPI cuckoomon_exception_handler(__in struct _EXCEPTION_POINTERS *ExceptionInfo)
{
char msg[16384];
char *msg;
char *dllname;
char *sehname;
unsigned int offset;
ULONG_PTR eip;
ULONG_PTR ebp;
ULONG_PTR seh = 0;
PUCHAR eipptr;
#ifdef _WIN64
Expand All @@ -682,8 +710,10 @@ LONG WINAPI cuckoomon_exception_handler(__in struct _EXCEPTION_POINTERS *Excepti

#ifdef _WIN64
stack = (ULONG_PTR *)(ULONG_PTR)(ExceptionInfo->ContextRecord->Rsp);
ebp = (ULONG_PTR)(ExceptionInfo->ContextRecord->Rbp);
#else
stack = (DWORD *)(ULONG_PTR)(ExceptionInfo->ContextRecord->Esp);
ebp = (ULONG_PTR)(ExceptionInfo->ContextRecord->Ebp);
{
DWORD *tebtmp = (DWORD *)NtCurrentTeb();
if (tebtmp[0] != 0xffffffff)
Expand All @@ -697,10 +727,13 @@ LONG WINAPI cuckoomon_exception_handler(__in struct _EXCEPTION_POINTERS *Excepti

hook_disable();


get_lasterrors(&lasterror);

log_flush();

msg = malloc(32768);

dllname = convert_address_to_dll_name_and_offset(eip, &offset);

sprintf(msg, "Exception Caught! PID: %u EIP:", GetCurrentProcessId());
Expand All @@ -713,6 +746,10 @@ LONG WINAPI cuckoomon_exception_handler(__in struct _EXCEPTION_POINTERS *Excepti

snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg), " %.08Ix, Fault Address: %.08Ix, Esp: %.08Ix, Exception Code: %08x, ",
eip, ExceptionInfo->ExceptionRecord->ExceptionInformation[1], (ULONG_PTR)stack, ExceptionInfo->ExceptionRecord->ExceptionCode);

operate_on_backtrace(eip, ebp, msg, &parse_stack_trace);

#ifdef _FULL_STACK_TRACE
if (is_valid_address_range((ULONG_PTR)stack, 100 * sizeof(ULONG_PTR)))
{
DWORD i;
Expand All @@ -732,13 +769,16 @@ LONG WINAPI cuckoomon_exception_handler(__in struct _EXCEPTION_POINTERS *Excepti
strcat(msg, "invalid stack, ");
}
next:
#endif

if (is_valid_address_range(eip, 16)) {
snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg) - 1, "Bytes at EIP: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
snprintf(msg + strlen(msg), sizeof(msg) - strlen(msg) - 1, " Bytes at EIP: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
eipptr[0], eipptr[1], eipptr[2], eipptr[3], eipptr[4], eipptr[5], eipptr[6], eipptr[7], eipptr[8], eipptr[9], eipptr[10], eipptr[11], eipptr[12], eipptr[13], eipptr[14], eipptr[15]);
}
debug_message(msg);
if (dllname)
free(dllname);
free(msg);

set_lasterrors(&lasterror);

Expand Down
2 changes: 2 additions & 0 deletions cuckoomon.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@
<AdditionalIncludeDirectories>.\bson;.\distorm3.2-package\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>true</BufferSecurityCheck>
<EnablePREfast>false</EnablePREfast>
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
<AdditionalOptions>/Qsafe_fp_loads %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
Expand Down
1 change: 0 additions & 1 deletion hook_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ HOOKDEF_NOTAIL(WINAPI, CreateWindowExA,
__in_opt LPVOID lpParam
) {
HWND ret = (HWND)1;

// lpClassName can be one of the predefined window controls.. which lay in
// the 0..ffff range
if (((DWORD_PTR)lpClassName & 0xffff) == (DWORD_PTR)lpClassName) {
Expand Down
8 changes: 4 additions & 4 deletions hooking.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void emit_rel(unsigned char *buf, unsigned char *source, unsigned char *target)
// need to be very careful about what we call in here, as it can be called in the context of any hook
// including those that hold the loader lock

static int set_caller_info(ULONG_PTR addr)
static int set_caller_info(void *unused, ULONG_PTR addr)
{
hook_info_t *hookinfo = hook_info();

Expand All @@ -59,7 +59,7 @@ static int set_caller_info(ULONG_PTR addr)
return 0;
}

int addr_in_our_dll_range(ULONG_PTR addr)
int addr_in_our_dll_range(void *unused, ULONG_PTR addr)
{
if (addr >= g_our_dll_base && addr < (g_our_dll_base + g_our_dll_size))
return 1;
Expand All @@ -70,7 +70,7 @@ int called_by_hook(void)
{
hook_info_t *hookinfo = hook_info();

return operate_on_backtrace(hookinfo->return_address, hookinfo->frame_pointer, addr_in_our_dll_range);
return operate_on_backtrace(hookinfo->return_address, hookinfo->frame_pointer, NULL, addr_in_our_dll_range);
}

extern BOOLEAN is_ignored_thread(DWORD tid);
Expand Down Expand Up @@ -113,7 +113,7 @@ int WINAPI enter_hook(hook_t *h, ULONG_PTR sp, ULONG_PTR ebp_or_rip)
hookinfo->main_caller_retaddr = 0;
hookinfo->parent_caller_retaddr = 0;

operate_on_backtrace(sp, ebp_or_rip, set_caller_info);
operate_on_backtrace(sp, ebp_or_rip, NULL, set_caller_info);

return 1;
}
Expand Down
48 changes: 46 additions & 2 deletions hooking.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __HOOKING_H
#define __HOOKING_H

#include "ntapi.h"
#include "config.h"
#include <Windows.h>

enum {
Expand Down Expand Up @@ -80,6 +84,9 @@ typedef struct _hook_t {
// as well (this address has more priority than library/funcname)
void *addr;

// where we made our modifications
void *hook_addr;

// pointer to the new function
void *new_func;

Expand Down Expand Up @@ -130,12 +137,12 @@ hook_info_t* hook_info();
void hook_enable();
void hook_disable();
int called_by_hook(void);
int addr_in_our_dll_range(ULONG_PTR addr);
int addr_in_our_dll_range(void *unused, ULONG_PTR addr);
void get_lasterrors(lasterror_t *errors);
void set_lasterrors(lasterror_t *errors);
int WINAPI enter_hook(hook_t *h, ULONG_PTR _ebp, ULONG_PTR retaddr);
void emit_rel(unsigned char *buf, unsigned char *source, unsigned char *target);
int operate_on_backtrace(ULONG_PTR retaddr, ULONG_PTR _ebp, int(*func)(ULONG_PTR));
int operate_on_backtrace(ULONG_PTR retaddr, ULONG_PTR _ebp, void *extra, int(*func)(void *, ULONG_PTR));

extern LARGE_INTEGER time_skipped;

Expand Down Expand Up @@ -225,3 +232,40 @@ static __inline ULONG_PTR get_stack_bottom(void)
memcpy(local_name.Buffer, param_name->Buffer, \
local_name.Length); \
}

static inline BOOLEAN disable_this_hook(hook_t *h)
{
const char *required_apis[] = {
"NtCreateThread",
"NtCreateThreadEx"
"NtCreateProcess",
"NtCreateProcessEx",
"NtCreateUserProcess",
"RtlCreateUserProcess",
"RtlCreateUserThread",
"CreateRemoteThread",
"NtQueueApcThread",
"NtQueueApcThreadEx",
"NtMapViewOfSection",
"NtWriteVirtualMemory",
"WriteProcessMemory",
"NtSetContextThread",
"NtResumeThread"
};
int i;

if (g_config.disable_hook_content == 2)
return TRUE;

if (g_config.disable_hook_content != 1)
return FALSE;

for (i = 0; i < sizeof(required_apis) / sizeof(required_apis[0]); i++) {
if (!strcmp(h->funcname, required_apis[i]))
return FALSE;
}

return TRUE;
}

#endif
11 changes: 6 additions & 5 deletions hooking_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ static void hook_create_pre_tramp(hook_t *h)
};


if (g_config.disable_hook_content) {
if (disable_this_hook(h)) {
h->hookdata->pre_tramp[0] = 0xe9;
emit_rel(h->hookdata->pre_tramp + 1, h->hookdata->pre_tramp + 1, h->hookdata->tramp);
return;
Expand Down Expand Up @@ -332,7 +332,7 @@ static void hook_create_pre_tramp_notail(hook_t *h)
0xe9, 0x00, 0x00, 0x00, 0x00
};

if (g_config.disable_hook_content) {
if (disable_this_hook(h)) {
h->hookdata->pre_tramp[0] = 0xe9;
emit_rel(h->hookdata->pre_tramp + 1, h->hookdata->pre_tramp + 1, h->hookdata->tramp);
return;
Expand Down Expand Up @@ -804,6 +804,7 @@ int hook_api(hook_t *h, int type)

// successful hook is successful
h->is_hooked = 1;
h->hook_addr = addr;
}
}
else {
Expand All @@ -821,7 +822,7 @@ int hook_api(hook_t *h, int type)
return ret;
}

int operate_on_backtrace(ULONG_PTR _esp, ULONG_PTR _ebp, int(*func)(ULONG_PTR))
int operate_on_backtrace(ULONG_PTR _esp, ULONG_PTR _ebp, void *extra, int(*func)(void *, ULONG_PTR))
{
int ret;

Expand All @@ -830,7 +831,7 @@ int operate_on_backtrace(ULONG_PTR _esp, ULONG_PTR _ebp, int(*func)(ULONG_PTR))

unsigned int count = HOOK_BACKTRACE_DEPTH;

ret = func(*(ULONG_PTR *)_esp);
ret = func(extra, *(ULONG_PTR *)_esp);
if (ret)
return ret;

Expand All @@ -840,7 +841,7 @@ int operate_on_backtrace(ULONG_PTR _esp, ULONG_PTR _ebp, int(*func)(ULONG_PTR))
ULONG_PTR addr = *(ULONG_PTR *)(_ebp + sizeof(ULONG_PTR));
_ebp = *(ULONG_PTR *)_ebp;

ret = func(addr);
ret = func(extra, addr);
if (ret)
return ret;
}
Expand Down
Loading

0 comments on commit c95495a

Please sign in to comment.