Skip to content

Commit

Permalink
Introduce a number of changes:
Browse files Browse the repository at this point in the history
Make the DLL injector aware of whether the task we're injecting into is currently suspended.  If it is, then notify cuckoo not to wait
Remove the argument from the DLL injector that specifies the injection method to use -- the best inferred method will be used automatically
Report to the analyzer whether the process we're interacting with is suspended or not
Report to the analyzer whenever we're about to terminate any process, including our own, using a "terminate-event" option in the config file
Fix more instances of win32 lasterror leakage
Don't flush on every API log
  • Loading branch information
brad-sp committed Jan 21, 2015
1 parent fa3f815 commit 00efda2
Show file tree
Hide file tree
Showing 17 changed files with 356 additions and 68 deletions.
4 changes: 4 additions & 0 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ int read_config(void)
else if(!strcmp(key, "force-sleepskip")) {
g_config.force_sleepskip = value[0] == '1';
}
else if (!strcmp(key, "terminate-event")) {
strncpy(g_config.terminate_event_name, value,
ARRAYSIZE(g_config.terminate_event_name));
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ struct _g_config {
// if this mutex exists then we're shutting down
char shutdown_mutex[MAX_PATH];

// event set by analyzer when our process is potentially going to be terminated
// cuckoomon itself will flush logs at this point, but the analyzer may take additional
// actions, like process dumping
char terminate_event_name[MAX_PATH];

// is this the first process or not?
int first_process;

Expand Down
5 changes: 5 additions & 0 deletions cuckoomon.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ LONG WINAPI cuckoomon_exception_handler(

get_lasterrors(&lasterror);

log_flush();

dllname = convert_address_to_dll_name_and_offset(eip, &offset);

sprintf(msg, "Exception Caught! PID: %u EIP:", GetCurrentProcessId());
Expand Down Expand Up @@ -707,6 +709,9 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
// initialize our unhook detection
unhook_init_detection();

// initialize terminate notification event
terminate_event_init();

// initialize all hooks
set_hooks();

Expand Down
28 changes: 25 additions & 3 deletions hook_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,12 @@ static void cache_file(HANDLE file_handle, const wchar_t *path,

static void file_write(HANDLE file_handle)
{
file_record_t *r = lookup_get(&g_files, (unsigned int) file_handle, NULL);
file_record_t *r;
lasterror_t lasterror;

get_lasterrors(&lasterror);

r = lookup_get(&g_files, (unsigned int)file_handle, NULL);
if(r != NULL) {
UNICODE_STRING str = {
// microsoft actually meant "size"
Expand All @@ -115,10 +120,16 @@ static void file_write(HANDLE file_handle)
// delete the file record from the list
lookup_del(&g_files, (unsigned int) file_handle);
}

set_lasterrors(&lasterror);
}

void check_for_logging_resumption(const OBJECT_ATTRIBUTES *obj)
static void check_for_logging_resumption(const OBJECT_ATTRIBUTES *obj)
{
lasterror_t lasterror;

get_lasterrors(&lasterror);

if (g_config.file_of_interest && g_config.suspend_logging) {
wchar_t *fname = calloc(1, 32768 * sizeof(wchar_t));
wchar_t *absolutename = malloc(32768 * sizeof(wchar_t));
Expand All @@ -134,10 +145,16 @@ void check_for_logging_resumption(const OBJECT_ATTRIBUTES *obj)
free(absolutename);
free(fname);
}

set_lasterrors(&lasterror);
}

static void handle_new_file(HANDLE file_handle, const OBJECT_ATTRIBUTES *obj)
{
lasterror_t lasterror;

get_lasterrors(&lasterror);

if(is_directory_objattr(obj) == 0) {

wchar_t *fname = calloc(1, 32768 * sizeof(wchar_t));
Expand All @@ -159,13 +176,18 @@ static void handle_new_file(HANDLE file_handle, const OBJECT_ATTRIBUTES *obj)
cache_file(file_handle, fname, lstrlenW(fname), obj->Attributes);
}
free(fname);

}

set_lasterrors(&lasterror);
}

void file_close(HANDLE file_handle)
{
lasterror_t lasterror;

get_lasterrors(&lasterror);
lookup_del(&g_files, (unsigned int) file_handle);
set_lasterrors(&lasterror);
}

HOOKDEF(NTSTATUS, WINAPI, NtCreateFile,
Expand Down
3 changes: 2 additions & 1 deletion hook_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtMapViewOfSection,
"SectionOffset", SectionOffset, "ViewSize", ViewSize, "Win32Protect", Win32Protect);

if(NT_SUCCESS(ret)) {
pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
DWORD pid = pid_from_process_handle(ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);
disable_sleep_skip();
}
return ret;
Expand Down
39 changes: 18 additions & 21 deletions hook_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtCreateProcess,
LOQ_ntstatus("process", "PphO", "ProcessHandle", ProcessHandle, "ParentHandle", ParentProcess, "DesiredAccess", DesiredAccess,
"FileName", ObjectAttributes);
if(NT_SUCCESS(ret)) {
pipe("PROCESS:%d", pid_from_process_handle(*ProcessHandle));
DWORD pid = pid_from_process_handle(*ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);
disable_sleep_skip();
}
return ret;
Expand All @@ -112,7 +113,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtCreateProcessEx,
LOQ_ntstatus("process", "PphO", "ProcessHandle", ProcessHandle, "ParentHandle", ParentProcess, "DesiredAccess", DesiredAccess,
"FileName", ObjectAttributes);
if(NT_SUCCESS(ret)) {
pipe("PROCESS:%d", pid_from_process_handle(*ProcessHandle));
DWORD pid = pid_from_process_handle(*ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);
disable_sleep_skip();
}
return ret;
Expand Down Expand Up @@ -153,8 +155,9 @@ HOOKDEF(NTSTATUS, WINAPI, NtCreateUserProcess,
"ImagePathName", &ProcessParameters->ImagePathName,
"CommandLine", &ProcessParameters->CommandLine);
if(NT_SUCCESS(ret)) {
pipe("PROCESS:%d,%d", pid_from_process_handle(*ProcessHandle),
tid_from_thread_handle(*ThreadHandle));
DWORD pid = pid_from_process_handle(*ProcessHandle);
DWORD tid = tid_from_thread_handle(*ThreadHandle);
pipe("PROCESS:%d:%d,%d", is_suspended(pid, tid), pid, tid);
disable_sleep_skip();
}
return ret;
Expand All @@ -179,9 +182,9 @@ HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserProcess,
LOQ_ntstatus("process", "ohp", "ImagePath", ImagePath, "ObjectAttributes", ObjectAttributes,
"ParentHandle", ParentProcess);
if(NT_SUCCESS(ret)) {
pipe("PROCESS:%d,%d",
pid_from_process_handle(ProcessInformation->ProcessHandle),
tid_from_thread_handle(ProcessInformation->ThreadHandle));
DWORD pid = pid_from_process_handle(ProcessInformation->ProcessHandle);
DWORD tid = tid_from_thread_handle(ProcessInformation->ThreadHandle);
pipe("PROCESS:%d:%d,%d", is_suspended(pid, tid), pid, tid);
disable_sleep_skip();
}
return ret;
Expand Down Expand Up @@ -213,20 +216,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtOpenProcess,
LOQ_ntstatus("process", "Phi", "ProcessHandle", ProcessHandle,
"DesiredAccess", DesiredAccess,
"ProcessIdentifier", pid);
/*
if(NT_SUCCESS(ret)) {
// let's do an extra check here, because the msdn documentation is
// so vague..
unsigned long pid = pid_from_process_handle(*ProcessHandle);
// check if this pid is protected
if(is_protected_pid(pid)) {
CloseHandle(*ProcessHandle);
return STATUS_ACCESS_DENIED;
}
pipe("PROCESS:%d", pid);
}
*/
return ret;

return ret;
}

int process_shutting_down;
Expand All @@ -242,9 +233,14 @@ HOOKDEF(NTSTATUS, WINAPI, NtTerminateProcess,
get_lasterrors(&lasterror);
LOQ_ntstatus("process", "ph", "ProcessHandle", ProcessHandle, "ExitCode", ExitStatus);
if (ProcessHandle == NULL || GetCurrentProcessId() == GetProcessId(ProcessHandle)) {
pipe("KILL:%d", GetCurrentProcessId());
log_free();
process_shutting_down = 1;
}
else {
DWORD PID = pid_from_process_handle(ProcessHandle);
pipe("KILL:%d", PID);
}
set_lasterrors(&lasterror);

ret = Old_NtTerminateProcess(ProcessHandle, ExitStatus);
Expand Down Expand Up @@ -347,6 +343,7 @@ HOOKDEF(VOID, WINAPI, ExitProcess,
) {
int ret = 0;
LOQ_void("process", "h", "ExitCode", uExitCode);
pipe("KILL:%d", GetCurrentProcessId());
log_free();
process_shutting_down = 1;
Old_ExitProcess(uExitCode);
Expand Down
29 changes: 25 additions & 4 deletions hook_sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
NTSTATUS ret = 0;
LONGLONG interval = -DelayInterval->QuadPart;
unsigned long milli = (unsigned long)(interval / 10000);
lasterror_t lasterror;

get_lasterrors(&lasterror);

// do we want to skip this sleep?
if(interval >= 0LL) {
Expand All @@ -73,20 +76,21 @@ HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
LOQ_ntstatus("system", "s", "Status", "Skipped log limit reached");
num_skipped++;
}
return ret;
goto skipcall;
}
/* clamp sleeps between 30 seconds and 1 hour down to 10 seconds as long as we didn't force off sleep skipping */
else if (milli >= 30000 && milli <= 3600000 && g_config.force_sleepskip != 0) {
LARGE_INTEGER newint;
newint.QuadPart = -(10000 * 10000);
time_skipped.QuadPart -= interval - (10000 * 10000);
LOQ_ntstatus("system", "is", "Milliseconds", milli, "Status", "Skipped");
set_lasterrors(&lasterror);
return Old_NtDelayExecution(Alertable, &newint);
}
else if (g_config.force_sleepskip > 0) {
time_skipped.QuadPart += interval;
LOQ_ntstatus("system", "is", "Milliseconds", milli, "Status", "Skipped");
return ret;
goto skipcall;
}
else {
disable_sleep_skip();
Expand All @@ -105,37 +109,54 @@ HOOKDEF(NTSTATUS, WINAPI, NtDelayExecution,
else {
LOQ_ntstatus("system", "i", "Milliseconds", milli);
}
return Old_NtDelayExecution(Alertable, DelayInterval);
set_lasterrors(&lasterror);
return Old_NtDelayExecution(Alertable, DelayInterval);
skipcall:
set_lasterrors(&lasterror);
return ret;
}

HOOKDEF(void, WINAPI, GetLocalTime,
__out LPSYSTEMTIME lpSystemTime
) {
lasterror_t lasterror;
Old_GetLocalTime(lpSystemTime);

LARGE_INTEGER li; FILETIME ft;
SystemTimeToFileTime(lpSystemTime, &ft);

get_lasterrors(&lasterror);

SystemTimeToFileTime(lpSystemTime, &ft);
li.HighPart = ft.dwHighDateTime;
li.LowPart = ft.dwLowDateTime;
li.QuadPart += time_skipped.QuadPart;
ft.dwHighDateTime = li.HighPart;
ft.dwLowDateTime = li.LowPart;
FileTimeToSystemTime(&ft, lpSystemTime);

set_lasterrors(&lasterror);
}

HOOKDEF(void, WINAPI, GetSystemTime,
__out LPSYSTEMTIME lpSystemTime
) {
lasterror_t lasterror;

Old_GetSystemTime(lpSystemTime);

LARGE_INTEGER li; FILETIME ft;

get_lasterrors(&lasterror);

SystemTimeToFileTime(lpSystemTime, &ft);
li.HighPart = ft.dwHighDateTime;
li.LowPart = ft.dwLowDateTime;
li.QuadPart += time_skipped.QuadPart;
ft.dwHighDateTime = li.HighPart;
ft.dwLowDateTime = li.LowPart;
FileTimeToSystemTime(&ft, lpSystemTime);

set_lasterrors(&lasterror);
}

HOOKDEF(DWORD, WINAPI, GetTickCount,
Expand Down
2 changes: 1 addition & 1 deletion hook_special.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ HOOKDEF2(BOOL, WINAPI, CreateProcessInternalW,
lpCurrentDirectory, lpStartupInfo, lpProcessInformation, lpUnknown2);

if(ret != FALSE) {
pipe("PROCESS:%d,%d", lpProcessInformation->dwProcessId,
pipe("PROCESS:%d:%d,%d", 1, lpProcessInformation->dwProcessId,
lpProcessInformation->dwThreadId);

// if the CREATE_SUSPENDED flag was not set, then we have to resume
Expand Down
31 changes: 18 additions & 13 deletions hook_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ HOOKDEF(NTSTATUS, WINAPI, NtQueueApcThread,
DWORD PID = pid_from_thread_handle(ThreadHandle);
DWORD TID = tid_from_thread_handle(ThreadHandle);

pipe("PROCESS:%d,%d", PID, TID);
pipe("PROCESS:%d:%d,%d", is_suspended(PID, TID), PID, TID);

NTSTATUS ret = Old_NtQueueApcThread(ThreadHandle, ApcRoutine,
ApcRoutineContext, ApcStatusBlock, ApcReserved);
Expand All @@ -56,7 +56,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtCreateThread,
__in PINITIAL_TEB InitialTeb,
__in BOOLEAN CreateSuspended
) {
pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
DWORD pid = pid_from_process_handle(ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);

NTSTATUS ret = Old_NtCreateThread(ThreadHandle, DesiredAccess,
ObjectAttributes, ProcessHandle, ClientId, ThreadContext,
Expand All @@ -82,7 +83,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtCreateThreadEx,
IN LONG SizeOfStackReserve,
OUT PVOID lpBytesBuffer
) {
pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
DWORD pid = pid_from_process_handle(ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);

NTSTATUS ret = Old_NtCreateThreadEx(hThread, DesiredAccess,
ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter,
Expand Down Expand Up @@ -120,10 +122,8 @@ HOOKDEF(NTSTATUS, WINAPI, NtOpenThread,
LOQ_ntstatus("threading", "PhO", "ThreadHandle", ThreadHandle, "DesiredAccess", DesiredAccess,
"ObjectAttributes", ObjectAttributes);
}
//if (NT_SUCCESS(ret)) {
// pipe("PROCESS:%d,%d", PID, TID);
//}
return ret;

return ret;
}

HOOKDEF(NTSTATUS, WINAPI, NtGetContextThread,
Expand All @@ -140,8 +140,9 @@ HOOKDEF(NTSTATUS, WINAPI, NtSetContextThread,
__in const CONTEXT *Context
) {
NTSTATUS ret;

pipe("PROCESS:%d,%d", pid_from_thread_handle(ThreadHandle), tid_from_thread_handle(ThreadHandle));
DWORD pid = pid_from_thread_handle(ThreadHandle);
DWORD tid = tid_from_thread_handle(ThreadHandle);
pipe("PROCESS:%d:%d,%d", is_suspended(pid, tid), pid, tid);

ret = Old_NtSetContextThread(ThreadHandle, Context);
LOQ_ntstatus("threading", "p", "ThreadHandle", ThreadHandle);
Expand All @@ -154,8 +155,11 @@ HOOKDEF(NTSTATUS, WINAPI, NtSuspendThread,
__out_opt ULONG *PreviousSuspendCount
) {
ENSURE_ULONG(PreviousSuspendCount);
DWORD pid = pid_from_thread_handle(ThreadHandle);
DWORD tid = tid_from_thread_handle(ThreadHandle);
pipe("PROCESS:%d:%d,%d", is_suspended(pid, tid), pid, tid);

NTSTATUS ret = Old_NtSuspendThread(ThreadHandle, PreviousSuspendCount);
NTSTATUS ret = Old_NtSuspendThread(ThreadHandle, PreviousSuspendCount);
LOQ_ntstatus("threading", "pL", "ThreadHandle", ThreadHandle,
"SuspendCount", PreviousSuspendCount);
return ret;
Expand Down Expand Up @@ -209,7 +213,8 @@ HOOKDEF(HANDLE, WINAPI, CreateRemoteThread,
__in DWORD dwCreationFlags,
__out LPDWORD lpThreadId
) {
pipe("PROCESS:%d", pid_from_process_handle(hProcess));
DWORD pid = pid_from_process_handle(hProcess);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);

HANDLE ret = Old_CreateRemoteThread(hProcess, lpThreadAttributes,
dwStackSize, lpStartAddress, lpParameter, dwCreationFlags,
Expand Down Expand Up @@ -243,8 +248,8 @@ HOOKDEF(NTSTATUS, WINAPI, RtlCreateUserThread,
OUT PCLIENT_ID ClientId
) {
ENSURE_CLIENT_ID(ClientId);

pipe("PROCESS:%d", pid_from_process_handle(ProcessHandle));
DWORD pid = pid_from_process_handle(ProcessHandle);
pipe("PROCESS:%d:%d", is_suspended(pid, 0), pid);

NTSTATUS ret = Old_RtlCreateUserThread(ProcessHandle, SecurityDescriptor,
CreateSuspended, StackZeroBits, StackReserved, StackCommit,
Expand Down
Loading

0 comments on commit 00efda2

Please sign in to comment.