From 367b37d773f30de8a104e8707e381b9a92ad0b9c Mon Sep 17 00:00:00 2001 From: mrexodia Date: Thu, 1 Sep 2016 21:15:57 +0200 Subject: [PATCH 1/7] added ThreaderCreateRemoteThread --- TitanEngineEmulator/Emulator.h | 7 +++++++ TitanEngineEmulator/TitanEngineEmulator.cpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index c0aba2f..71b74f9 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -470,6 +470,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 { diff --git a/TitanEngineEmulator/TitanEngineEmulator.cpp b/TitanEngineEmulator/TitanEngineEmulator.cpp index 7a3ca4d..46a186a 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.cpp +++ b/TitanEngineEmulator/TitanEngineEmulator.cpp @@ -268,4 +268,10 @@ __declspec(dllexport) void TITCALL SingleStep(DWORD StepCount, LPVOID StepCallBa __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); } \ No newline at end of file From e7f709fcda210bf2b6c80867616a1faa054531b1 Mon Sep 17 00:00:00 2001 From: mrexodia Date: Fri, 28 Oct 2016 02:39:38 +0200 Subject: [PATCH 2/7] performance improvements for tracing --- GleeBug/Debugger.Loop.cpp | 2 +- GleeBug/Debugger.Thread.cpp | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/GleeBug/Debugger.Loop.cpp b/GleeBug/Debugger.Loop.cpp index f9e3c67..3ff251b 100644 --- a/GleeBug/Debugger.Loop.cpp +++ b/GleeBug/Debugger.Loop.cpp @@ -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) diff --git a/GleeBug/Debugger.Thread.cpp b/GleeBug/Debugger.Thread.cpp index 970bea9..88d355f 100644 --- a/GleeBug/Debugger.Thread.cpp +++ b/GleeBug/Debugger.Thread.cpp @@ -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() From cb5ec1fae0e1b49d8b8bd04611aef6dac5a38d53 Mon Sep 17 00:00:00 2001 From: mrexodia Date: Wed, 4 Jan 2017 02:56:59 +0100 Subject: [PATCH 3/7] ignore VS2017 directories --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d397081..9fc6d1d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ Release/ *.orig *.vcxproj.user docs/ +.vs/ \ No newline at end of file From be4549a361254065a8f6e83181ba62e1a5c726f8 Mon Sep 17 00:00:00 2001 From: mrexodia Date: Wed, 4 Jan 2017 02:57:45 +0100 Subject: [PATCH 4/7] added string conversion helper functions --- GleeBug/GleeBug.cpp | 41 +++++++++++++++++++++++++++++++++ GleeBug/GleeBug.h | 5 ++++ GleeBug/GleeBug.vcxproj | 1 + GleeBug/GleeBug.vcxproj.filters | 3 +++ 4 files changed, 50 insertions(+) create mode 100644 GleeBug/GleeBug.cpp diff --git a/GleeBug/GleeBug.cpp b/GleeBug/GleeBug.cpp new file mode 100644 index 0000000..e80795f --- /dev/null +++ b/GleeBug/GleeBug.cpp @@ -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 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 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()); + } +}; \ No newline at end of file diff --git a/GleeBug/GleeBug.h b/GleeBug/GleeBug.h index 27d6969..9c58ab4 100644 --- a/GleeBug/GleeBug.h +++ b/GleeBug/GleeBug.h @@ -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 \ No newline at end of file diff --git a/GleeBug/GleeBug.vcxproj b/GleeBug/GleeBug.vcxproj index 03ec159..b1ecb74 100644 --- a/GleeBug/GleeBug.vcxproj +++ b/GleeBug/GleeBug.vcxproj @@ -168,6 +168,7 @@ + diff --git a/GleeBug/GleeBug.vcxproj.filters b/GleeBug/GleeBug.vcxproj.filters index e21dc23..41f6f89 100644 --- a/GleeBug/GleeBug.vcxproj.filters +++ b/GleeBug/GleeBug.vcxproj.filters @@ -83,6 +83,9 @@ Source Files\capstone_wrapper + + Source Files + From 56fe293287e2d435ff55a4a94df6a24290cbb672 Mon Sep 17 00:00:00 2001 From: mrexodia Date: Wed, 4 Jan 2017 03:07:52 +0100 Subject: [PATCH 5/7] implemented attach functionality --- GleeBug/Debugger.Loop.Exception.cpp | 4 ++++ GleeBug/Debugger.Loop.Process.cpp | 9 +++++++++ GleeBug/Debugger.cpp | 20 +++++++++++++++++--- GleeBug/Debugger.h | 14 ++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/GleeBug/Debugger.Loop.Exception.cpp b/GleeBug/Debugger.Loop.Exception.cpp index 4c5a0bd..79f5429 100644 --- a/GleeBug/Debugger.Loop.Exception.cpp +++ b/GleeBug/Debugger.Loop.Exception.cpp @@ -10,6 +10,10 @@ namespace GleeBug mProcess->systemBreakpoint = true; mContinueStatus = DBG_CONTINUE; + //call the attach callback if appropriate + if(mAttachedToProcess && mProcess->dwProcessId == mMainProcess.dwProcessId) + cbAttachBreakpoint(); + //call the callback cbSystemBreakpoint(); } diff --git a/GleeBug/Debugger.Loop.Process.cpp b/GleeBug/Debugger.Loop.Process.cpp index da18173..cb278ea 100644 --- a/GleeBug/Debugger.Loop.Process.cpp +++ b/GleeBug/Debugger.Loop.Process.cpp @@ -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, diff --git a/GleeBug/Debugger.cpp b/GleeBug/Debugger.cpp index 2efcff1..facf5c7 100644 --- a/GleeBug/Debugger.cpp +++ b/GleeBug/Debugger.cpp @@ -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); diff --git a/GleeBug/Debugger.h b/GleeBug/Debugger.h index 3f6480f..de0b4ef 100644 --- a/GleeBug/Debugger.h +++ b/GleeBug/Debugger.h @@ -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. */ @@ -260,6 +272,7 @@ namespace GleeBug virtual void exceptionHardwareBreakpoint(ptr exceptionAddress); protected: //variables + STARTUPINFOW mMainStartupInfo; PROCESS_INFORMATION mMainProcess; uint32 mContinueStatus = DBG_EXCEPTION_NOT_HANDLED; bool mBreakDebugger = false; @@ -269,6 +282,7 @@ namespace GleeBug bool mIsDebugging = false; bool mDetach = false; bool mDetachAndBreak = false; + bool mAttachedToProcess = false; Capstone mCapstone; /** From c5197f92d574024e6855b396c5f802290d2a3ede Mon Sep 17 00:00:00 2001 From: mrexodia Date: Wed, 4 Jan 2017 03:08:21 +0100 Subject: [PATCH 6/7] added various functions to TitanEngineEmulator --- MyDebugger/MyDebugger.h | 6 ++++ TitanEngineEmulator/Emulator.h | 36 +++++++++++++++++++-- TitanEngineEmulator/TitanEngineEmulator.cpp | 30 +++++++++++++++++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/MyDebugger/MyDebugger.h b/MyDebugger/MyDebugger.h index 589e4b9..7590128 100644 --- a/MyDebugger/MyDebugger.h +++ b/MyDebugger/MyDebugger.h @@ -135,6 +135,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", diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index 71b74f9..0be7e15 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -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) { @@ -532,6 +546,16 @@ protected: mCbDEBUGEVENT(&debugEvent); } + void cbAttachBreakpoint() override + { + if(mCbATTACHBREAKPOINT) + { + if(mAttachProcessInfo) + *mAttachProcessInfo = mMainProcess; + mCbATTACHBREAKPOINT(); + } + } + void cbSystemBreakpoint() override { if (mCbSYSTEMBREAKPOINT) @@ -588,12 +612,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; } @@ -648,4 +676,6 @@ private: //variables CUSTOMHANDLER mCbOUTPUTDEBUGSTRING = nullptr; CUSTOMHANDLER mCbUNHANDLEDEXCEPTION = nullptr; CUSTOMHANDLER mCbDEBUGEVENT = nullptr; + STEPCALLBACK mCbATTACHBREAKPOINT = nullptr; + PROCESS_INFORMATION* mAttachProcessInfo = nullptr; }; \ No newline at end of file diff --git a/TitanEngineEmulator/TitanEngineEmulator.cpp b/TitanEngineEmulator/TitanEngineEmulator.cpp index 46a186a..ba809d9 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.cpp +++ b/TitanEngineEmulator/TitanEngineEmulator.cpp @@ -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); From 9cc0b8c756b605c6bfda36b7041da85cced4478b Mon Sep 17 00:00:00 2001 From: mrexodia Date: Wed, 4 Jan 2017 03:10:22 +0100 Subject: [PATCH 7/7] updated capstone_wrapper --- capstone_wrapper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/capstone_wrapper b/capstone_wrapper index 5416abe..619f5e0 160000 --- a/capstone_wrapper +++ b/capstone_wrapper @@ -1 +1 @@ -Subproject commit 5416abe36359bfc02346712d0c77509f9758a96f +Subproject commit 619f5e0a0c43b19ca9dabf34da4ddd19cb84a704