-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support Functions for Fuzzing Attached Processes and Fix a False Hang issue in attached processes #61
base: master
Are you sure you want to change the base?
Changes from 2 commits
48f4449
8417ab3
1a406fe
7489c6d
e7fc4aa
2fce951
d2f1619
fade015
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1471,7 +1471,7 @@ DebuggerStatus Debugger::DebugLoop(uint32_t timeout, bool killing) | |
uint64_t time_elapsed = end_time - begin_time; | ||
timeout = ((uint64_t)timeout >= time_elapsed) ? timeout - (uint32_t)time_elapsed : 0; | ||
|
||
// printf("timeout: %u\n", timeout); | ||
//printf("timeout: %u\n", timeout); | ||
// printf("time: %lld\n", get_cur_time_us()); | ||
|
||
if (wait_ret) { | ||
|
@@ -1480,7 +1480,13 @@ DebuggerStatus Debugger::DebugLoop(uint32_t timeout, bool killing) | |
dbg_continue_needed = false; | ||
} | ||
|
||
if (timeout == 0) return DEBUGGER_HANGED; | ||
if (timeout == 0) { | ||
if(attach_mode) { | ||
return DEBUGGER_PROCESS_EXIT; | ||
} else { | ||
return DEBUGGER_HANGED; | ||
} | ||
} | ||
|
||
if (!wait_ret) { | ||
//printf("WaitForDebugEvent returned 0\n"); | ||
|
@@ -1491,7 +1497,7 @@ DebuggerStatus Debugger::DebugLoop(uint32_t timeout, bool killing) | |
|
||
thread_id = DebugEv->dwThreadId; | ||
|
||
// printf("eventCode: %x\n", DebugEv->dwDebugEventCode); | ||
//printf("eventCode: %x\n", DebugEv->dwDebugEventCode); | ||
|
||
switch (DebugEv->dwDebugEventCode) | ||
{ | ||
|
@@ -1739,11 +1745,10 @@ DebuggerStatus Debugger::Kill() { | |
// attaches to an active process | ||
DebuggerStatus Debugger::Attach(unsigned int pid, uint32_t timeout) { | ||
attach_mode = true; | ||
processID = pid; | ||
|
||
if (!DebugActiveProcess(pid)) { | ||
DWORD error_code = GetLastError(); | ||
|
||
|
||
if(error_code == 5) { | ||
HANDLE hToken = NULL; | ||
LUID luid; | ||
|
@@ -1810,19 +1815,25 @@ DebuggerStatus Debugger::Continue(uint32_t timeout) { | |
dbg_last_status = DEBUGGER_TARGET_START; | ||
return dbg_last_status; | ||
} | ||
if (script != NULL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is also something that should be implemented in Jackalope rather than TinyInst. IIUC "script" is used for fuzzing sample delivery, and should thus be implemented in Jackalope by subclassing the SampleDelivery class. |
||
HANDLE thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)system, script, 0, NULL); | ||
CloseHandle(thread_handle); | ||
} | ||
|
||
dbg_last_status = DebugLoop(timeout); | ||
|
||
if (dbg_last_status == DEBUGGER_PROCESS_EXIT) { | ||
CloseHandle(child_handle); | ||
CloseHandle(child_thread_handle); | ||
child_handle = NULL; | ||
child_thread_handle = NULL; | ||
if (!attach_mode) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these changes need to be reverted (IIUC they were related to the |
||
CloseHandle(child_handle); | ||
CloseHandle(child_thread_handle); | ||
child_handle = NULL; | ||
child_thread_handle = NULL; | ||
} | ||
} | ||
|
||
return dbg_last_status; | ||
} | ||
|
||
// initializes options from command line | ||
void Debugger::Init(int argc, char **argv) { | ||
have_thread_context = false; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,8 +77,12 @@ class Debugger { | |
return last_exception; | ||
} | ||
|
||
char * script; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This variable is now unused and can be removed, right? |
||
|
||
protected: | ||
|
||
DWORD processID; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This variable is unused |
||
|
||
enum MemoryProtection { | ||
READONLY, | ||
READWRITE, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,12 @@ limitations under the License. | |
#include <chrono> | ||
|
||
#include "common.h" | ||
#include <windows.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These includes and the |
||
#include <tlhelp32.h> | ||
#include <iostream> | ||
#include <string> | ||
#include <codecvt> | ||
#include <locale> | ||
|
||
uint64_t GetCurTime(void) { | ||
auto duration = std::chrono::system_clock::now().time_since_epoch(); | ||
|
@@ -96,6 +102,25 @@ int GetIntOption(const char *name, int argc, char** argv, int default_value) { | |
return (int)strtol(option, NULL, 0); | ||
} | ||
|
||
DWORD FindProcessId(char * process_name) | ||
{ | ||
PROCESSENTRY32 entry; | ||
entry.dwSize = sizeof(PROCESSENTRY32); | ||
|
||
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); | ||
|
||
if (Process32First(snapshot, &entry) == TRUE) | ||
{ | ||
while (Process32Next(snapshot, &entry) == TRUE) | ||
{ | ||
if (stricmp(entry.szExeFile, process_name) == 0) | ||
{ | ||
CloseHandle(snapshot); | ||
return entry.th32ProcessID; | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The function should return something (zero?) if the process wasn't found. |
||
} | ||
|
||
//quoting on Windows is weird | ||
size_t ArgvEscapeWindows(char *in, char *out) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think TinyInst should report incorrect status (process exit instead of timeout). If the calling application wants to treat hang as the process exit, then that's the responsibility of the calling application.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a valid concern, but in my testing of this particular mode, there are many targets that do not exit after a testcase has been successfully inserted and processed. For example, if someone were to fuzz the windows rdp server, the server would not exit after an rdp packet is processed. This would result in a false hang detection by the fuzzer and leave the tool effectively useless for targets like these. Would it be possible to incorporate a cli flag in fuzzer.cpp of jackalope to incorporate this functionality?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand what you want to accomplish, my point is just that this is not the right place to implement it. Instead of TinyInst claiming the process exited when in fact it did not, it should be the function using it, e.g.
TinyInstInstrumentation::Attach
orTinyInstInstrumentation::Run
that should adapt its behavior.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, this makes sense. I will adapt these changes into the Jackalope files then.