-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
668 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
################################################################################ | ||
# This .gitignore file was automatically created by Microsoft(R) Visual Studio. | ||
################################################################################ | ||
|
||
*.pdb | ||
*.sqlite | ||
/.vs | ||
/packages | ||
/WcfDumper/obj | ||
/WcfDumper/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.29519.87 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WcfDumper", "WcfDumper\WcfDumper.csproj", "{3DEA7A1C-FC22-41DD-B9C7-4593D497A730}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{3DEA7A1C-FC22-41DD-B9C7-4593D497A730}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{3DEA7A1C-FC22-41DD-B9C7-4593D497A730}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{3DEA7A1C-FC22-41DD-B9C7-4593D497A730}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{3DEA7A1C-FC22-41DD-B9C7-4593D497A730}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {2CC9585E-8222-43C4-9BD7-B238083E5893} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> | ||
</startup> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
using Microsoft.Diagnostics.Runtime; | ||
using System; | ||
using System.Collections.Generic; | ||
using WcfDumper.Helpers; | ||
|
||
namespace WcfDumper.DataModel | ||
{ | ||
public class DataTargetWrapper | ||
{ | ||
private string myFile; | ||
private int myPid; | ||
|
||
public DataTargetWrapper(string file) | ||
{ | ||
myFile = file; | ||
} | ||
|
||
public DataTargetWrapper(int pid) | ||
{ | ||
myPid = pid; | ||
} | ||
|
||
public void Process() | ||
{ | ||
bool isTargetx64 = ProcessHelper.NativeMethods.Is64Bit(myPid); | ||
|
||
bool archmatch = (isTargetx64 && Environment.Is64BitProcess) || | ||
(!isTargetx64 && !Environment.Is64BitProcess); | ||
|
||
if (!archmatch) | ||
{ | ||
Console.WriteLine($"PID: {myPid} - Inconsistent process architecture."); | ||
return; | ||
} | ||
|
||
using (DataTarget dataTarget = GetDataTarget()) | ||
{ | ||
foreach (ClrInfo clrVersionInfo in dataTarget.ClrVersions) | ||
{ | ||
ClrInfoCallback?.Invoke(clrVersionInfo); | ||
} | ||
|
||
if (dataTarget.ClrVersions.Count == 0) | ||
{ | ||
Console.WriteLine($"PID: {myPid} - Not a managed executable."); | ||
return; | ||
} | ||
|
||
ClrInfo runtimeInfo = dataTarget.ClrVersions[0]; | ||
ClrRuntime runtime = runtimeInfo.CreateRuntime(); | ||
ClrHeap heap = runtime.Heap; | ||
|
||
if (!heap.CanWalkHeap) | ||
{ | ||
ClrHeapIsNotWalkableCallback?.Invoke(); | ||
return; | ||
} | ||
foreach (ulong obj in heap.EnumerateObjectAddresses()) | ||
{ | ||
ClrType type = heap.GetObjectType(obj); | ||
|
||
// If heap corruption, continue past this object. | ||
if (type == null) | ||
continue; | ||
|
||
if (TypesToDump.Contains(type.Name)) | ||
{ | ||
ClrObjectOfTypeFoundCallback(heap, obj, type.Name); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private DataTarget GetDataTarget() | ||
{ | ||
if (myFile != null) | ||
{ | ||
return DataTarget.LoadCrashDump(myFile); | ||
} | ||
|
||
return DataTarget.AttachToProcess(myPid, 5000, AttachFlag.NonInvasive); | ||
} | ||
|
||
public Action<ClrInfo> ClrInfoCallback; | ||
public Action ClrHeapIsNotWalkableCallback; | ||
public Action<ClrHeap, ulong, string> ClrObjectOfTypeFoundCallback; | ||
public HashSet<string> TypesToDump = new HashSet<string>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace WcfDumper.DataModel | ||
{ | ||
public class OperationDescriptionEntry | ||
{ | ||
public string OperationName; | ||
public List<string> OperationBehaviors = new List<string>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace WcfDumper.DataModel | ||
{ | ||
public class ProcessInfo | ||
{ | ||
public int PID; | ||
public string Name; | ||
public string Path; | ||
public string CmdLine; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace WcfDumper.DataModel | ||
{ | ||
public class ServiceDescriptionEntry | ||
{ | ||
public ServiceDescriptionEntry(int pid) | ||
{ | ||
ProcessInfo = new ProcessInfo(); | ||
ProcessInfo.PID = pid; | ||
} | ||
|
||
public ProcessInfo ProcessInfo; | ||
public List<string> ServiceBehaviors = new List<string>(); | ||
public List<ServiceEndpointEntry> ServiceEndpoints = new List<ServiceEndpointEntry>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace WcfDumper.DataModel | ||
{ | ||
public class ServiceEndpointEntry | ||
{ | ||
public string Uri; | ||
public string Contract; | ||
public string CallbackContract; | ||
public List<string> EndpointBehaviors = new List<string>(); | ||
public List<string> ContractBehaviors = new List<string>(); | ||
public List<OperationDescriptionEntry> ContractOperations = new List<OperationDescriptionEntry>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using Microsoft.Diagnostics.Runtime; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using WcfDumper.DataModel; | ||
|
||
namespace WcfDumper.Helpers | ||
{ | ||
public static class ClrMdHelper | ||
{ | ||
public static DataTargetWrapper LoadDumpFile(string file) | ||
{ | ||
return new DataTargetWrapper(file); | ||
} | ||
|
||
public static DataTargetWrapper AttachToLiveProcess(int pid) | ||
{ | ||
return new DataTargetWrapper(pid); | ||
} | ||
|
||
public static List<ulong> GetLastObjectInHierarchyAsArray(ClrHeap heap, ulong obj, string[] hierarchy, int currentIndex, string arrayTypeToVerify) | ||
{ | ||
ulong arrayObj = ClrMdHelper.GetLastObjectInHierarchy(heap, obj, hierarchy, currentIndex); | ||
ClrType arrayType = heap.GetObjectType(arrayObj); | ||
|
||
Debug.Assert(arrayType.Name == arrayTypeToVerify); | ||
|
||
List<ulong> arrayItems = GetArrayItems(arrayType, arrayObj); | ||
return arrayItems; | ||
} | ||
|
||
public static List<ulong> GetArrayItems(ClrType type, ulong items) | ||
{ | ||
int length = type.GetArrayLength(items); | ||
var ret = new List<ulong>(); | ||
|
||
for (int i = 0; i < length; i++) | ||
{ | ||
var val = (ulong)type.GetArrayElementValue(items, i); | ||
|
||
if (val != 0) | ||
{ | ||
ret.Add(val); | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
public static ulong GetLastObjectInHierarchy(ClrHeap heap, ulong heapobject, string[] hierarchy, int currentIndex) | ||
{ | ||
ClrType type = heap.GetObjectType(heapobject); | ||
ClrInstanceField field = type.GetFieldByName(hierarchy[currentIndex]); | ||
ulong fieldValue = (ulong)field.GetValue(heapobject, false, false); | ||
|
||
currentIndex++; | ||
if (currentIndex == hierarchy.Length) | ||
{ | ||
return fieldValue; | ||
} | ||
|
||
return GetLastObjectInHierarchy(heap, fieldValue, hierarchy, currentIndex); | ||
} | ||
|
||
public static T GetObjectAs<T>(ClrHeap heap, ulong heapobject, string fieldName) | ||
{ | ||
ClrType type = heap.GetObjectType(heapobject); | ||
ClrInstanceField field = type.GetFieldByName(fieldName); | ||
T fieldValue = (T)field.GetValue(heapobject); | ||
|
||
return fieldValue; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
using System.Diagnostics; | ||
using System.Runtime.InteropServices; | ||
using System.Text.RegularExpressions; | ||
using WcfDumper.DataModel; | ||
|
||
namespace WcfDumper.Helpers | ||
{ | ||
public static class ProcessHelper | ||
{ | ||
public static ProcessInfo GetProcessDetails(int pid) | ||
{ | ||
var pi = new ProcessInfo(); | ||
pi.PID = pid; | ||
|
||
return pi; | ||
} | ||
|
||
public static List<int> GetPIDs(string wildcard) | ||
{ | ||
var processes = Process.GetProcesses(); | ||
var ret = new List<int>(); | ||
Regex regex = new Regex(wildcard, RegexOptions.IgnoreCase); | ||
|
||
foreach (var process in processes) | ||
{ | ||
using (process) | ||
{ | ||
if (regex.IsMatch(process.ProcessName)) | ||
{ | ||
ret.Add(process.Id); | ||
} | ||
} | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
internal static class NativeMethods | ||
{ | ||
public static bool Is64Bit(int pid) | ||
{ | ||
if (!Environment.Is64BitOperatingSystem) | ||
{ | ||
return false; | ||
} | ||
|
||
bool isWow64; | ||
|
||
using (var process = Process.GetProcessById(pid)) | ||
{ | ||
if (!IsWow64Process(process.Handle, out isWow64)) | ||
{ | ||
throw new Win32Exception(); | ||
} | ||
} | ||
|
||
return !isWow64; | ||
} | ||
|
||
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] | ||
[return: MarshalAs(UnmanagedType.Bool)] | ||
private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process); | ||
} | ||
} | ||
} |
Oops, something went wrong.