Files
mirror-processhacker/2.x/incomplete/stackext_dac_stack.patch
T
wj32 8f96d7da1d added stackext_dac_stack.patch
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5060 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2012-07-06 04:30:03 +00:00

120 lines
4.5 KiB
Diff

Index: plugins/DotNetTools/stackext.c
===================================================================
--- plugins/DotNetTools/stackext.c (revision 5058)
+++ plugins/DotNetTools/stackext.c (working copy)
@@ -48,16 +48,29 @@
{
PTHREAD_STACK_CONTEXT context;
BOOLEAN isDotNet;
+ HANDLE processHandle;
+ BOOLEAN isWow64 = FALSE;
if (!NT_SUCCESS(PhGetProcessIsDotNet(Control->u.Initializing.ProcessId, &isDotNet)) || !isDotNet)
return;
+ if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess, Control->u.Initializing.ProcessId)))
+ {
+ PhGetProcessIsWow64(processHandle, &isWow64);
+ NtClose(processHandle);
+ }
+
+ if (isWow64)
+ return;
+
context = PhAllocate(sizeof(THREAD_STACK_CONTEXT));
context->Support = CreateClrProcessSupport(Control->u.Initializing.ProcessId);
PhAcquireQueuedLockExclusive(&ContextHashtableLock);
PhAddItemSimpleHashtable(ContextHashtable, Control->UniqueKey, context);
PhReleaseQueuedLockExclusive(&ContextHashtableLock);
+
+ Control->u.Initializing.CustomWalk = TRUE;
}
break;
case PluginThreadStackUninitializing:
@@ -133,5 +146,84 @@
}
}
break;
+ case PluginThreadStackWalkStack:
+ {
+ PTHREAD_STACK_CONTEXT context;
+ PVOID *item;
+ IXCLRDataTask *task;
+
+ PhAcquireQueuedLockExclusive(&ContextHashtableLock);
+
+ item = PhFindItemSimpleHashtable(ContextHashtable, Control->UniqueKey);
+
+ if (item)
+ context = *item;
+ else
+ context = NULL;
+
+ PhReleaseQueuedLockExclusive(&ContextHashtableLock);
+
+ if (!context)
+ return;
+
+ if (SUCCEEDED(IXCLRDataProcess_GetTaskByOSThreadID(
+ context->Support->DataProcess,
+ (ULONG)Control->u.WalkStack.ClientId->UniqueThread,
+ &task
+ )))
+ {
+ IXCLRDataStackWalk *stackWalk;
+
+ if (SUCCEEDED(IXCLRDataTask_CreateStackWalk(task, 0xf, &stackWalk)))
+ {
+ HRESULT result;
+ BOOLEAN firstTime = TRUE;
+ CONTEXT context;
+ ULONG contextSize;
+
+ context.ContextFlags = CONTEXT_ALL;
+ PhGetThreadContext(Control->u.WalkStack.ThreadHandle, &context);
+ result = IXCLRDataStackWalk_SetContext2(stackWalk, CLRDATA_STACK_SET_CURRENT_CONTEXT, sizeof(CONTEXT), (BYTE *)&context);
+
+ while (SUCCEEDED(result = IXCLRDataStackWalk_Next(stackWalk)) && result != S_FALSE)
+ {
+ if (firstTime)
+ {
+ PhWalkThreadStack(
+ Control->u.WalkStack.ThreadHandle,
+ Control->u.WalkStack.ProcessHandle,
+ Control->u.WalkStack.ClientId,
+ PH_WALK_KERNEL_STACK,
+ Control->u.WalkStack.Callback,
+ Control->u.WalkStack.CallbackContext
+ );
+
+ Control->u.WalkStack.Status = STATUS_SUCCESS; // prevent default walk
+ firstTime = FALSE;
+ }
+
+ if (SUCCEEDED(IXCLRDataStackWalk_GetContext(stackWalk, CONTEXT_CONTROL, sizeof(context), &contextSize, (BYTE *)&context)))
+ {
+ PH_THREAD_STACK_FRAME stackFrame;
+
+ memset(&stackFrame, 0, sizeof(PH_THREAD_STACK_FRAME));
+
+#ifdef _M_X64
+ stackFrame.PcAddress = (PVOID)context.Rip;
+#else
+ stackFrame.PcAddress = (PVOID)context.Eip;
+#endif
+
+ Control->u.WalkStack.Callback(&stackFrame, Control->u.WalkStack.CallbackContext);
+ }
+ }
+
+ IXCLRDataStackWalk_Release(stackWalk);
+ }
+
+ IXCLRDataTask_Release(task);
+ }
+ }
+ break;
}
}