Merge branch 'master' into membp

# Conflicts:
#	GleeBug/Debugger.Loop.Exception.cpp
This commit is contained in:
mrexodia 2017-01-04 03:11:50 +01:00
commit c40e9e68ce
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
15 changed files with 183 additions and 18 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@ Release/
*.orig
*.vcxproj.user
docs/
.vs/

View File

@ -29,6 +29,10 @@ namespace GleeBug
mProcess->permanentDep = true;
#endif //_WIN64
//call the attach callback if appropriate
if(mAttachedToProcess && mProcess->dwProcessId == mMainProcess.dwProcessId)
cbAttachBreakpoint();
//call the callback
cbSystemBreakpoint();
}

View File

@ -4,6 +4,15 @@ namespace GleeBug
{
void Debugger::createProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess)
{
//initial attach housekeeping
if(mAttachedToProcess && !mMainProcess.dwProcessId)
{
mMainProcess.hProcess = createProcess.hProcess;
mMainProcess.hThread = createProcess.hThread;
mMainProcess.dwProcessId = mDebugEvent.dwProcessId;
mMainProcess.dwThreadId = mDebugEvent.dwThreadId;
}
//process housekeeping
mProcesses.insert({ mDebugEvent.dwProcessId,
Process(createProcess.hProcess,

View File

@ -113,7 +113,7 @@ namespace GleeBug
break;
}
//clear trap flag when set by GleeBug (to prevent an EXCEPTION_SINGLE_STEP after detach
//clear trap flag when set by GleeBug (to prevent an EXCEPTION_SINGLE_STEP after detach)
if (mDetach && mThread)
{
if (mThread->isInternalStepping || mThread->isSingleStepping)

View File

@ -42,17 +42,14 @@ namespace GleeBug
bool Thread::RegReadContext()
{
SuspendThread(this->hThread);
memset(&this->mOldContext, 0, sizeof(CONTEXT));
this->mOldContext.ContextFlags = CONTEXT_ALL;
bool bReturn = false;
this->mOldContext.ContextFlags = CONTEXT_ALL; //TODO: granular control over what's required
if (GetThreadContext(this->hThread, &this->mOldContext))
{
this->registers.SetContext(this->mOldContext);
bReturn = true;
return true;
}
ResumeThread(this->hThread);
return bReturn;
return false;
}
bool Thread::RegWriteContext() const
@ -61,10 +58,7 @@ namespace GleeBug
if (memcmp(&this->mOldContext, this->registers.GetContext(), sizeof(CONTEXT)) == 0)
return true;
//update the context
SuspendThread(this->hThread);
bool bReturn = !!SetThreadContext(this->hThread, this->registers.GetContext());
ResumeThread(this->hThread);
return bReturn;
return !!SetThreadContext(this->hThread, this->registers.GetContext());
}
void Thread::StepInto()

View File

@ -15,8 +15,8 @@ namespace GleeBug
const wchar_t* szCommandLine,
const wchar_t* szCurrentDirectory)
{
STARTUPINFOW si;
memset(&si, 0, sizeof(si));
memset(&mMainStartupInfo, 0, sizeof(mMainStartupInfo));
memset(&mMainProcess, 0, sizeof(mMainProcess));
const wchar_t* szFileNameCreateProcess;
wchar_t* szCommandLineCreateProcess;
wchar_t* szCreateWithCmdLine = nullptr;
@ -42,14 +42,28 @@ namespace GleeBug
DEBUG_PROCESS | CREATE_NEW_CONSOLE,
nullptr,
szCurrentDirectory,
&si,
&mMainStartupInfo,
&mMainProcess);
delete[] szCreateWithCmdLine;
mAttachedToProcess = false;
return result;
}
bool Debugger::Attach(DWORD processId)
{
//don't allow attaching when still debugging
if(mIsDebugging)
return false;
if(!DebugActiveProcess(processId))
return false;
mAttachedToProcess = true;
memset(&mMainStartupInfo, 0, sizeof(mMainStartupInfo));
memset(&mMainProcess, 0, sizeof(mMainProcess));
return true;
}
bool Debugger::Stop() const
{
return !!TerminateProcess(mMainProcess.hProcess, 0);

View File

@ -35,6 +35,13 @@ namespace GleeBug
const wchar_t* szCommandLine,
const wchar_t* szCurrentDirectory);
/**
\brief Attach to a debuggee.
\param processId Process to attach to.
\return true if the debuggee was attached to successfully, false otherwise.
*/
bool Attach(DWORD processId);
/**
\brief Stops the debuggee (terminate the process)
\return true if the debuggee was stopped correctly, false otherwise.
@ -161,6 +168,11 @@ namespace GleeBug
*/
virtual void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, bool firstChance) {};
/**
\brief Attach breakpoint callback. Called just before cbSystemBreakpoint, only for the process that was attached to. Provide an implementation to use this callback.
*/
virtual void cbAttachBreakpoint() {};
/**
\brief System breakpoint callback. Called after the event is internally processed. Provide an implementation to use this callback.
*/
@ -264,6 +276,7 @@ namespace GleeBug
virtual void exceptionAccessViolation(const EXCEPTION_RECORD & exceptionRecord, bool firstChance);
protected: //variables
STARTUPINFOW mMainStartupInfo;
PROCESS_INFORMATION mMainProcess;
uint32 mContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
bool mBreakDebugger = false;
@ -273,6 +286,7 @@ namespace GleeBug
bool mIsDebugging = false;
bool mDetach = false;
bool mDetachAndBreak = false;
bool mAttachedToProcess = false;
Capstone mCapstone;
/**

41
GleeBug/GleeBug.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "GleeBug.h"
namespace GleeBug
{
//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289
std::string Utf16ToUtf8(const std::wstring & wstr)
{
std::string convertedString;
auto requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
if(requiredSize > 0)
{
std::vector<char> buffer(requiredSize);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, nullptr, nullptr);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}
std::string Utf16ToUtf8(const wchar_t* wstr)
{
return Utf16ToUtf8(wstr ? std::wstring(wstr) : std::wstring());
}
std::wstring Utf8ToUtf16(const std::string & str)
{
std::wstring convertedString;
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
if(requiredSize > 0)
{
std::vector<wchar_t> buffer(requiredSize);
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize);
convertedString.assign(buffer.begin(), buffer.end() - 1);
}
return convertedString;
}
std::wstring Utf8ToUtf16(const char* str)
{
return Utf8ToUtf16(str ? std::string(str) : std::string());
}
};

View File

@ -53,6 +53,11 @@ namespace GleeBug
return a.second < b.first;
}
};
std::string Utf16ToUtf8(const std::wstring & wstr);
std::string Utf16ToUtf8(const wchar_t* wstr);
std::wstring Utf8ToUtf16(const std::string & str);
std::wstring Utf8ToUtf16(const char* str);
}
#endif //GLEEBUG_H

View File

@ -168,6 +168,7 @@
<ClCompile Include="Debugger.Thread.HardwareBreakpoint.cpp" />
<ClCompile Include="Debugger.Thread.Registers.cpp" />
<ClCompile Include="Debugger.Thread.Registers.GetSet.cpp" />
<ClCompile Include="GleeBug.cpp" />
<ClCompile Include="Static.BufferFile.cpp" />
<ClCompile Include="Static.File.cpp" />
<ClCompile Include="Static.Pattern.cpp" />

View File

@ -83,6 +83,9 @@
<ClCompile Include="..\capstone_wrapper\capstone_wrapper.cpp">
<Filter>Source Files\capstone_wrapper</Filter>
</ClCompile>
<ClCompile Include="GleeBug.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger.h">

View File

@ -153,6 +153,12 @@ protected:
rip.dwError);
}
void cbAttachBreakpoint() override
{
printf("Attach breakpoint reached, GIP: 0x%p\n",
mRegisters->Gip());
}
void cbSystemBreakpoint() override
{
printf("System breakpoint reached, GIP: 0x%p\n",

View File

@ -9,6 +9,7 @@ public:
//Debugger
PROCESS_INFORMATION* InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
{
mCbATTACHBREAKPOINT = nullptr;
if (!Init(szFileName, szCommandLine, szCurrentFolder))
return nullptr;
return &mMainProcess;
@ -27,13 +28,16 @@ public:
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
{
//TODO
return false;
if(!Attach(ProcessId))
return false;
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
mAttachProcessInfo = (PROCESS_INFORMATION*)DebugInfo;
DebugLoop();
return true;
}
bool DetachDebuggerEx(DWORD ProcessId)
{
//TODO
Detach();
return true;
}
@ -141,6 +145,16 @@ public:
mSetDebugPrivilege = VariableSet;
}
PROCESS_INFORMATION* TitanGetProcessInformation()
{
return &mMainProcess;
}
STARTUPINFOW* TitanGetStartupInformation()
{
return &mMainStartupInfo;
}
//Misc
bool IsJumpGoingToExecuteEx(HANDLE hProcess, HANDLE hThread, ULONG_PTR InstructionAddress, ULONG_PTR RegFlags)
{
@ -475,6 +489,13 @@ public:
return false;
}
//Threader
ULONG_PTR ThreaderCreateRemoteThread(ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId)
{
//TODO
return 0;
}
protected:
void cbCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO & createProcess, const Process & process) override
{
@ -530,6 +551,16 @@ protected:
mCbDEBUGEVENT(&debugEvent);
}
void cbAttachBreakpoint() override
{
if(mCbATTACHBREAKPOINT)
{
if(mAttachProcessInfo)
*mAttachProcessInfo = mMainProcess;
mCbATTACHBREAKPOINT();
}
}
void cbSystemBreakpoint() override
{
if (mCbSYSTEMBREAKPOINT)
@ -586,12 +617,16 @@ private: //functions
Thread* threadFromHandle(HANDLE hThread) const
{
if(!hThread)
return mThread;
//TODO: properly implement this
return mThread;
}
Process* processFromHandle(HANDLE hProcess) const
{
if(!hProcess)
return mProcess;
//TODO: properly implement this
return mProcess;
}
@ -664,4 +699,6 @@ private: //variables
CUSTOMHANDLER mCbOUTPUTDEBUGSTRING = nullptr;
CUSTOMHANDLER mCbUNHANDLEDEXCEPTION = nullptr;
CUSTOMHANDLER mCbDEBUGEVENT = nullptr;
STEPCALLBACK mCbATTACHBREAKPOINT = nullptr;
PROCESS_INFORMATION* mAttachProcessInfo = nullptr;
};

View File

@ -81,6 +81,16 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari
emu.SetEngineVariable(VariableId, VariableSet);
}
__declspec(dllexport) PROCESS_INFORMATION* TITCALL TitanGetProcessInformation()
{
return emu.TitanGetProcessInformation();
}
__declspec(dllexport) STARTUPINFOW* TITCALL TitanGetStartupInformation()
{
return emu.TitanGetStartupInformation();
}
//Misc
__declspec(dllexport) bool TITCALL IsJumpGoingToExecuteEx(HANDLE hProcess, HANDLE hThread, ULONG_PTR InstructionAddress, ULONG_PTR RegFlags)
{
@ -118,6 +128,11 @@ __declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, D
return emu.GetContextDataEx(hActiveThread, IndexOfRegister);
}
__declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister)
{
return GetContextDataEx(nullptr, IndexOfRegister);
}
__declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue)
{
return emu.SetContextDataEx(hActiveThread, IndexOfRegister, NewRegisterValue);
@ -149,6 +164,11 @@ __declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DW
return emu.StaticFileLoadW(szFileName, DesiredAccess, SimulateLoad, FileHandle, LoadedSize, FileMap, FileMapVA);
}
__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA)
{
return StaticFileLoadW(Utf8ToUtf16(szFileName).c_str(), DesiredAccess, SimulateLoad, FileHandle, LoadedSize, FileMap, FileMapVA);
}
__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA)
{
return emu.StaticFileUnloadW(szFileName, CommitChanges, FileHandle, LoadedSize, FileMap, FileMapVA);
@ -164,6 +184,11 @@ __declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMa
return emu.ConvertVAtoFileOffsetEx(FileMapVA, FileSize, ImageBase, AddressToConvert, AddressIsRVA, ReturnType);
}
__declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType)
{
return ConvertVAtoFileOffsetEx(FileMapVA, 0, 0, AddressToConvert, false, ReturnType);
}
__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData)
{
return emu.GetPE32DataFromMappedFile(FileMapVA, WhichSection, WhichData);
@ -174,6 +199,11 @@ __declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName,
return emu.GetPE32DataW(szFileName, WhichSection, WhichData);
}
__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData)
{
return GetPE32DataW(Utf8ToUtf16(szFileName).c_str(), WhichSection, WhichData);
}
__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA)
{
return emu.IsFileDLLW(szFileName, FileMapVA);
@ -269,3 +299,9 @@ __declspec(dllexport) void TITCALL StepInto(LPVOID traceCallBack)
{
emu.StepInto(traceCallBack);
}
//Threader
__declspec(dllexport) ULONG_PTR TITCALL ThreaderCreateRemoteThread(ULONG_PTR ThreadStartAddress, bool AutoCloseTheHandle, LPVOID ThreadPassParameter, LPDWORD ThreadId)
{
return emu.ThreaderCreateRemoteThread(ThreadStartAddress, AutoCloseTheHandle, ThreadPassParameter, ThreadId);
}

@ -1 +1 @@
Subproject commit 7fbeb7edaad3ffda7a7f37bd31086662e56f7a42
Subproject commit 619f5e0a0c43b19ca9dabf34da4ddd19cb84a704