출처:
ftp://ftp.oreilly.de/pub/examples/english_examples/9780735622142/cd_contents/MiniFuzz/LaunchExe.cpp
http://blog.naver.com/PostView.nhn?blogId=hks9999&logNo=30105498369
#include "stdafx.h"
#include "fuzz.h"
#include "log.h"
using namespace std;
// How long should the app run for us to consider the test a success (1.2secs)
const DWORD MAX_EXE_RUNTIME_MS = 1200;
// log interesting info if we get a debug event back from the debugged app
bool ReportFailure(DEBUG_EVENT *pdbg, const char *szFilename) {
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pdbg->dwThreadId);
if (!hThread) {
Log("OpenThread failed");
return false;
}
string sExc;
switch(pdbg->u.Exception.ExceptionRecord.ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION : sExc = "Access Violation"; break;
case EXCEPTION_STACK_OVERFLOW: sExc = "Stack Overflow"; break;
case EXCEPTION_DATATYPE_MISALIGNMENT: sExc = "Datatype misalignment"; break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED : sExc = "Array Bounds Exceeded"; break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO: sExc = "Float Div/0"; break;
case EXCEPTION_INT_DIVIDE_BY_ZERO: sExc = "Int Div/0"; break;
case EXCEPTION_ILLEGAL_INSTRUCTION: sExc = "Illegal Instruction"; break;
case EXCEPTION_IN_PAGE_ERROR: sExc = "In-page error"; break;
case EXCEPTION_PRIV_INSTRUCTION: sExc = "Privileged Instruction";break;
default : sExc = "Unknown"; break;
}
CONTEXT ctx;
memset(&ctx,0,sizeof CONTEXT);
ctx.ContextFlags = CONTEXT_ALL;
if (!GetThreadContext(hThread, &ctx)) {
Log("GetThreadContext failed");
return false;
}
ReportFuzzError(szFilename,sExc,ctx);
return true;
}
// spawn the exe to fuzz
bool LaunchFile(const char *szDir, const char *szExe, const char *szFilename, bool *pfDeleteTempFile) {
if (pfDeleteTempFile == NULL && szDir == NULL || szExe == NULL || szFilename == NULL) {
Log("Invalid args to LaunchFile");
return false;
}
*pfDeleteTempFile = false;
bool fError = false;
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&pi,0,sizeof PROCESS_INFORMATION);
memset(&si,0,sizeof STARTUPINFO);
si.cb = sizeof STARTUPINFO;
// build up the cmd-line
string sExe(szExe);
sExe.append(" ");
sExe.append(szFilename);
BOOL fRet = CreateProcess(NULL,
const_cast<LPSTR>(sExe.c_str()),
NULL, NULL,
FALSE,
DEBUG_ONLY_THIS_PROCESS,
NULL, NULL,
&si, &pi);
if (!fRet) {
Log("Unable to launch process", szExe, GetLastError());
return false;
}
DWORD dwStart = GetTickCount();
// Now wait for debug events from the new process
do {
DEBUG_EVENT dbg;
if (WaitForDebugEvent(&dbg, 200)) {
// we get copies of all loaded DLL file handles - we don't need 'em - so close 'em
if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) {
CloseHandle(dbg.u.LoadDll.hFile);
ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
continue;
}
// we get a copy of the loaded exe file handle - we don't need it - so close it
if (dbg.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
CloseHandle(dbg.u.CreateProcessInfo.hFile);
ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
continue;
}
// at this point we only care about real debug events
if (dbg.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) {
ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
continue;
}
// An exception occured
// CAVEAT: this code can catch *ALL* exceptions, including first-chance exceptions.
// Catching and logging a first-chance exception does *NOT* mean there is a security bug
// in your code. Don't go filing bugs on first-chance exceptions unless it's a real bug!
switch (dbg.u.Exception.ExceptionRecord.ExceptionCode) {
case EXCEPTION_ACCESS_VIOLATION :
case EXCEPTION_STACK_OVERFLOW:
case EXCEPTION_DATATYPE_MISALIGNMENT:
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED :
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_IN_PAGE_ERROR:
case EXCEPTION_PRIV_INSTRUCTION:
// DO NOT HANDLE FIRST CHANCE EXCEPTIONS!
// If you want to handle them, then change this code to:
// if (dbg.u.Exception.dwFirstChance) {
if (!dbg.u.Exception.dwFirstChance) {
ReportFailure(&dbg, szFilename);
fError = true;
}
break;
default:
ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
break;
}
} else {
break;
}
} while((GetTickCount() - dwStart) < MAX_EXE_RUNTIME_MS);
DebugActiveProcessStop(pi.dwProcessId);
if (!TerminateProcess(pi.hProcess,1))
Log("Unable to kill process", szExe, GetLastError());
if (pi.hThread)
CloseHandle(pi.hThread);
if (pi.hProcess)
CloseHandle(pi.hProcess);
if (pfDeleteTempFile && !fError)
*pfDeleteTempFile = true;
return fError;
}
'fuzzing' 카테고리의 다른 글
CreateProcess시 핸들 누수 현상 (0) | 2013.04.08 |
---|---|
Fuzzing Frameworks (0) | 2011.05.09 |
The Art of File Format Fuzzing (0) | 2011.03.02 |