Skip to content

Instantly share code, notes, and snippets.

@MSDN-WhiteKnight
Created September 21, 2020 04:36
Show Gist options
  • Save MSDN-WhiteKnight/d10244fd97bfb33ce00b26b49deea2f4 to your computer and use it in GitHub Desktop.
Save MSDN-WhiteKnight/d10244fd97bfb33ce00b26b49deea2f4 to your computer and use it in GitHub Desktop.
ICorDebug
#include <stdio.h>
#include <Windows.h>
#include <CorHdr.h>
#include <metahost.h>
#include <CorDebug.h>
#pragma comment(lib, "mscoree.lib")
#pragma comment(lib, "CorGuids.lib")
void PrintProcessInfo(ICorDebugProcess* pDebug) {
ICorDebugThreadEnum* pThreadEnum;
HRESULT hr = pDebug->EnumerateThreads(&pThreadEnum);
if (FAILED(hr)) {
printf("EnumerateThreads error");
return;
}
ICorDebugThread* pTh = NULL;
ICorDebugFrame* pFrame;
ICorDebugFunction* pFunc;
ULONG c;
DWORD id;
while (1) {
c = 0;
hr = pThreadEnum->Next(1, &pTh, &c);
if (FAILED(hr))break;
if (c == 0)break;
id = 0;
pTh->GetID(&id);
printf("Thread ID: %u\n", id);
hr = pTh->GetActiveFrame(&pFrame);
if (FAILED(hr))continue;
}
}
class UnmanagedCallback :
public ICorDebugUnmanagedCallback
{
public:
UnmanagedCallback() {
this->m_cRef = 0;
}
volatile unsigned int m_cRef;
// Унаследовано через ICorDebugUnmanagedCallback
virtual HRESULT __stdcall QueryInterface(REFIID riid, void ** ppvObj) override
{
if (!ppvObj)
return E_INVALIDARG;
*ppvObj = NULL;
if (riid == IID_IUnknown || riid == IID_ICorDebugUnmanagedCallback)
{
// Increment the reference count and return the pointer.
*ppvObj = (LPVOID)this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
virtual ULONG __stdcall AddRef(void) override
{
InterlockedIncrement(&m_cRef);
return m_cRef;
}
virtual ULONG __stdcall Release(void) override
{
// Decrement the object's internal counter.
ULONG ulRefCount = InterlockedDecrement(&m_cRef);
if (0 == m_cRef)
{
delete this;
}
return ulRefCount;
}
virtual HRESULT __stdcall DebugEvent(LPDEBUG_EVENT pDebugEvent, BOOL fOutOfBand) override
{
;
return 0;
}
};
class ManagedCallback :
public ICorDebugManagedCallback,
public ICorDebugManagedCallback2
{
public:
ManagedCallback() {
this->m_cRef = 0;
}
volatile unsigned int m_cRef;
// Унаследовано через ICorDebugManagedCallback
virtual HRESULT __stdcall QueryInterface(REFIID riid, void ** ppvObj) override
{
if (!ppvObj)
return E_INVALIDARG;
*ppvObj = NULL;
if (riid == IID_IUnknown || riid == IID_ICorDebugManagedCallback ||
riid == IID_ICorDebugManagedCallback2)
{
// Increment the reference count and return the pointer.
*ppvObj = (LPVOID)this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
virtual ULONG __stdcall AddRef(void) override
{
InterlockedIncrement(&m_cRef);
return m_cRef;
}
virtual ULONG __stdcall Release(void) override
{
// Decrement the object's internal counter.
ULONG ulRefCount = InterlockedDecrement(&m_cRef);
if (0 == m_cRef)
{
delete this;
}
return ulRefCount;
}
virtual HRESULT __stdcall Breakpoint(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall StepComplete(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugStepper * pStepper, CorDebugStepReason reason) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall Break(ICorDebugAppDomain * pAppDomain, ICorDebugThread * thread) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall Exception(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, BOOL unhandled) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall EvalComplete(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall EvalException(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugEval * pEval) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ExitProcess(ICorDebugProcess * pProcess) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall CreateThread(ICorDebugAppDomain * pAppDomain, ICorDebugThread * thread) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ExitThread(ICorDebugAppDomain * pAppDomain, ICorDebugThread * thread) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall LoadModule(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall UnloadModule(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall LoadClass(ICorDebugAppDomain * pAppDomain, ICorDebugClass * c) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall UnloadClass(ICorDebugAppDomain * pAppDomain, ICorDebugClass * c) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall DebuggerError(ICorDebugProcess * pProcess, HRESULT errorHR, DWORD errorCode) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall LogMessage(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, WCHAR * pLogSwitchName, WCHAR * pMessage) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall LogSwitch(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, LONG lLevel, ULONG ulReason, WCHAR * pLogSwitchName, WCHAR * pParentName) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall CreateAppDomain(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) override
{
pProcess->Continue(FALSE);
printf("CreateAppDomain\n");
PrintProcessInfo(pProcess);
HRESULT hr = pProcess->Detach();
if(FAILED(hr)) printf("Detach error:0x%x\n",hr);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ExitAppDomain(ICorDebugProcess * pProcess, ICorDebugAppDomain * pAppDomain) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall LoadAssembly(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall UnloadAssembly(ICorDebugAppDomain * pAppDomain, ICorDebugAssembly * pAssembly) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ControlCTrap(ICorDebugProcess * pProcess) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall NameChange(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall UpdateModuleSymbols(ICorDebugAppDomain * pAppDomain, ICorDebugModule * pModule, IStream * pSymbolStream) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall EditAndContinueRemap(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction, BOOL fAccurate) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall BreakpointSetError(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugBreakpoint * pBreakpoint, DWORD dwError) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall CreateProcess(ICorDebugProcess *pProcess) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
// Унаследовано через ICorDebugManagedCallback2
virtual HRESULT __stdcall FunctionRemapOpportunity(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pOldFunction, ICorDebugFunction * pNewFunction, ULONG32 oldILOffset) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall CreateConnection(ICorDebugProcess * pProcess, CONNID dwConnectionId, WCHAR * pConnName) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ChangeConnection(ICorDebugProcess * pProcess, CONNID dwConnectionId) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall DestroyConnection(ICorDebugProcess * pProcess, CONNID dwConnectionId) override
{
pProcess->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall Exception(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFrame * pFrame, ULONG32 nOffset, CorDebugExceptionCallbackType dwEventType, DWORD dwFlags) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall ExceptionUnwind(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, CorDebugExceptionUnwindCallbackType dwEventType, DWORD dwFlags) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall FunctionRemapComplete(ICorDebugAppDomain * pAppDomain, ICorDebugThread * pThread, ICorDebugFunction * pFunction) override
{
pAppDomain->Continue(FALSE);
return ERROR_SUCCESS;
}
virtual HRESULT __stdcall MDANotification(ICorDebugController * pController, ICorDebugThread * pThread, ICorDebugMDA * pMDA) override
{
pController->Continue(FALSE);
return ERROR_SUCCESS;
}
};
int main() {
ICLRMetaHost *pMetaHost = NULL;
ICLRDebugging *pCLRDebugging = NULL;
HRESULT hr;
CoInitialize(NULL);
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
(LPVOID*)&pMetaHost);
hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging,
(LPVOID*)&pCLRDebugging);
DWORD pid = GetCurrentProcessId();
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
IEnumUnknown* pEnumUnk;
hr = pMetaHost->EnumerateLoadedRuntimes(hProcess, &pEnumUnk);
IUnknown* unk;
hr = pEnumUnk->Next(1, &unk, NULL);
ICLRRuntimeInfo * pInfo;
unk->QueryInterface(__uuidof(ICLRRuntimeInfo), (void**)&pInfo);
ICorDebug* pDebug;
hr = pInfo->GetInterface(CLSID_CLRDebuggingLegacy,__uuidof(ICorDebug), (void**)&pDebug);
hr = pDebug->Initialize();
ICorDebugProcess* pDebugProcess;
ManagedCallback* mc=new ManagedCallback();
UnmanagedCallback* uc=new UnmanagedCallback();
hr = pDebug->SetManagedHandler((ICorDebugManagedCallback*)mc);
//hr = pDebug->SetUnmanagedHandler((ICorDebugUnmanagedCallback*)uc);
hr = pDebug->DebugActiveProcess(pid, FALSE, &pDebugProcess);
/**/
if (SUCCEEDED(hr)) printf("Attached");
else printf("DebugActiveProcess Error: 0x%x",hr);
getchar();
;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment