439 lines
14 KiB
C#
439 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Zodiacon.DebugHelp
|
|
{
|
|
// Token: 0x0200000A RID: 10
|
|
public sealed class SymbolHandler : IDisposable
|
|
{
|
|
// Token: 0x06000023 RID: 35 RVA: 0x0000229A File Offset: 0x0000049A
|
|
private SymbolHandler(IntPtr hProcess, bool ownHandle)
|
|
{
|
|
this._hProcess = hProcess;
|
|
this._ownHandle = ownHandle;
|
|
}
|
|
|
|
// Token: 0x06000024 RID: 36 RVA: 0x000022B0 File Offset: 0x000004B0
|
|
public static SymbolHandler CreateFromProcess(int pid, SymbolOptions options = SymbolOptions.None, string searchPath = null)
|
|
{
|
|
if (searchPath == null)
|
|
{
|
|
searchPath = SymbolHandler.GetDefaultSearchPath();
|
|
}
|
|
IntPtr hProcess = new IntPtr(pid);
|
|
if (Win32.SymInitialize(hProcess, searchPath, true))
|
|
{
|
|
return new SymbolHandler(hProcess, false);
|
|
}
|
|
throw new Win32Exception(Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
// Token: 0x06000025 RID: 37 RVA: 0x000022EC File Offset: 0x000004EC
|
|
public static SymbolHandler TryCreateFromProcess(int pid, SymbolOptions options = SymbolOptions.None, string searchPath = null)
|
|
{
|
|
if (searchPath == null)
|
|
{
|
|
searchPath = SymbolHandler.GetDefaultSearchPath();
|
|
}
|
|
IntPtr hProcess = new IntPtr(pid);
|
|
if (Win32.SymInitialize(hProcess, searchPath, true))
|
|
{
|
|
return new SymbolHandler(hProcess, false);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x06000026 RID: 38 RVA: 0x0000231E File Offset: 0x0000051E
|
|
public static SymbolHandler CreateFromHandle(IntPtr handle, SymbolOptions options = SymbolOptions.None, string searchPath = null)
|
|
{
|
|
if (searchPath == null)
|
|
{
|
|
searchPath = SymbolHandler.GetDefaultSearchPath();
|
|
}
|
|
Win32.SymSetOptions(options);
|
|
Win32.SymInitialize(handle, searchPath, true).ThrowIfWin32Failed(0);
|
|
return new SymbolHandler(handle, false);
|
|
}
|
|
|
|
// Token: 0x06000027 RID: 39 RVA: 0x00002348 File Offset: 0x00000548
|
|
private static string GetDefaultSearchPath()
|
|
{
|
|
string text = Environment.GetEnvironmentVariable("_NT_SYMBOL_PATH");
|
|
if (text != null)
|
|
{
|
|
int num = text.IndexOf('*');
|
|
if (num < 0)
|
|
{
|
|
return text;
|
|
}
|
|
text = text.Substring(num + 1, text.IndexOf('*', num + 1) - num - 1);
|
|
if (string.IsNullOrWhiteSpace(text))
|
|
{
|
|
text = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
// Token: 0x06000028 RID: 40 RVA: 0x0000239C File Offset: 0x0000059C
|
|
public static SymbolHandler Create(SymbolOptions options = SymbolOptions.CaseInsensitive | SymbolOptions.UndecorateNames, string searchPath = null)
|
|
{
|
|
if (Debugger.IsAttached)
|
|
{
|
|
options |= (SymbolOptions)2147483648U;
|
|
}
|
|
if (searchPath == null)
|
|
{
|
|
searchPath = SymbolHandler.GetDefaultSearchPath();
|
|
}
|
|
Win32.SymSetOptions(options);
|
|
IntPtr hProcess = new IntPtr(++SymbolHandler._instances);
|
|
Win32.SymInitialize(hProcess, searchPath, false).ThrowIfWin32Failed(0);
|
|
return new SymbolHandler(hProcess, false);
|
|
}
|
|
|
|
// Token: 0x06000029 RID: 41 RVA: 0x000023F1 File Offset: 0x000005F1
|
|
public void Dispose()
|
|
{
|
|
Win32.SymCleanup(this._hProcess);
|
|
if (this._ownHandle)
|
|
{
|
|
Win32.CloseHandle(this._hProcess);
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600002A RID: 42 RVA: 0x00002414 File Offset: 0x00000614
|
|
public ulong LoadSymbolsForModule(string imageName, ulong dllBase = 0UL, string moduleName = null, IntPtr? hFile = null)
|
|
{
|
|
ulong num = Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, dllBase, 0U, IntPtr.Zero, 0U);
|
|
int lastWin32Error = Marshal.GetLastWin32Error();
|
|
if (num == 0UL && lastWin32Error != 0)
|
|
{
|
|
throw new Win32Exception(lastWin32Error);
|
|
}
|
|
return num;
|
|
}
|
|
|
|
// Token: 0x0600002B RID: 43 RVA: 0x00002464 File Offset: 0x00000664
|
|
public ulong TryLoadSymbolsForModule(string imageName, string moduleName = null, IntPtr? hFile = null)
|
|
{
|
|
return Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, 0UL, 0U, IntPtr.Zero, 0U);
|
|
}
|
|
|
|
// Token: 0x0600002C RID: 44 RVA: 0x000024A0 File Offset: 0x000006A0
|
|
public Task<ulong> TryLoadSymbolsForModuleAsync(string imageName, ulong dllBase = 0UL, string moduleName = null, IntPtr? hFile = null)
|
|
{
|
|
return Task.Run<ulong>(() => Win32.SymLoadModuleEx(this._hProcess, hFile ?? IntPtr.Zero, imageName, moduleName, dllBase, 0U, IntPtr.Zero, 0U));
|
|
}
|
|
|
|
// Token: 0x0600002D RID: 45 RVA: 0x000024DC File Offset: 0x000006DC
|
|
public SymbolInfo GetSymbolFromAddress(ulong address, out ulong displacement)
|
|
{
|
|
SymbolInfo result = default(SymbolInfo);
|
|
result.Init();
|
|
Win32.SymFromAddr(this._hProcess, address, out displacement, ref result).ThrowIfWin32Failed(0);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600002E RID: 46 RVA: 0x0000250F File Offset: 0x0000070F
|
|
public bool TryGetSymbolFromAddress(ulong address, ref SymbolInfo symbol, out ulong displacement)
|
|
{
|
|
symbol.Init();
|
|
return Win32.SymFromAddr(this._hProcess, address, out displacement, ref symbol);
|
|
}
|
|
|
|
// Token: 0x0600002F RID: 47 RVA: 0x00002528 File Offset: 0x00000728
|
|
public IReadOnlyList<ModuleInfo> EnumModules()
|
|
{
|
|
List<ModuleInfo> modules = new List<ModuleInfo>(8);
|
|
Win32.SymEnumerateModules64(this._hProcess, delegate(string name, ulong dllBase, IntPtr context)
|
|
{
|
|
modules.Add(new ModuleInfo
|
|
{
|
|
Name = name,
|
|
Base = dllBase
|
|
});
|
|
return true;
|
|
}, IntPtr.Zero).ThrowIfWin32Failed(0);
|
|
return modules;
|
|
}
|
|
|
|
// Token: 0x06000030 RID: 48 RVA: 0x00002570 File Offset: 0x00000770
|
|
public bool GetSymbolFromName(string name, ref SymbolInfo symbol)
|
|
{
|
|
return Win32.SymFromName(this._hProcess, name, ref symbol);
|
|
}
|
|
|
|
// Token: 0x06000031 RID: 49 RVA: 0x0000257F File Offset: 0x0000077F
|
|
public bool GetSymbolFromIndex(ulong dllBase, int index, ref SymbolInfo symbol)
|
|
{
|
|
return Win32.SymFromIndex(this._hProcess, dllBase, index, ref symbol);
|
|
}
|
|
|
|
// Token: 0x06000032 RID: 50 RVA: 0x00002590 File Offset: 0x00000790
|
|
public ICollection<SymbolInfo> EnumSymbols(ulong baseAddress, string mask = "*!*")
|
|
{
|
|
List<SymbolInfo> symbols = new List<SymbolInfo>(16);
|
|
Win32.SymEnumSymbols(this._hProcess, baseAddress, mask, delegate(ref SymbolInfo symbol, uint size, IntPtr context)
|
|
{
|
|
symbols.Add(symbol);
|
|
return true;
|
|
}, IntPtr.Zero);
|
|
return symbols;
|
|
}
|
|
|
|
// Token: 0x06000033 RID: 51 RVA: 0x000025D8 File Offset: 0x000007D8
|
|
public IList<SymbolInfo> EnumTypes(ulong baseAddress, string mask = "*")
|
|
{
|
|
List<SymbolInfo> symbols = new List<SymbolInfo>(16);
|
|
Win32.SymEnumTypesByName(this._hProcess, baseAddress, mask, delegate(ref SymbolInfo symbol, uint size, IntPtr context)
|
|
{
|
|
symbols.Add(symbol);
|
|
return true;
|
|
}, IntPtr.Zero);
|
|
return symbols;
|
|
}
|
|
|
|
// Token: 0x06000034 RID: 52 RVA: 0x00002620 File Offset: 0x00000820
|
|
public unsafe IList<SourceFile> EnumSourceFiles(ulong baseAddress, string mask = "*")
|
|
{
|
|
List<SourceFile> files = new List<SourceFile>(4);
|
|
Win32.SymEnumSourceFiles(this._hProcess, baseAddress, mask, delegate(SOURCEFILE source, IntPtr context)
|
|
{
|
|
files.Add(new SourceFile
|
|
{
|
|
BaseAddress = source.ModuleBase,
|
|
FileName = new string(source.FileName)
|
|
});
|
|
return true;
|
|
}, IntPtr.Zero);
|
|
return files;
|
|
}
|
|
|
|
// Token: 0x06000035 RID: 53 RVA: 0x00002664 File Offset: 0x00000864
|
|
public int GetTypeIndexFromName(ulong baseAddress, string name)
|
|
{
|
|
SymbolInfo symbolInfo = SymbolInfo.Create();
|
|
if (!Win32.SymGetTypeFromName(this._hProcess, baseAddress, name, ref symbolInfo))
|
|
{
|
|
return 0;
|
|
}
|
|
return symbolInfo.TypeIndex;
|
|
}
|
|
|
|
// Token: 0x06000036 RID: 54 RVA: 0x00002690 File Offset: 0x00000890
|
|
public bool GetTypeFromName(ulong baseAddress, string name, ref SymbolInfo type)
|
|
{
|
|
return Win32.SymGetTypeFromName(this._hProcess, baseAddress, name, ref type);
|
|
}
|
|
|
|
// Token: 0x06000037 RID: 55 RVA: 0x000026A0 File Offset: 0x000008A0
|
|
public bool Refresh()
|
|
{
|
|
return Win32.SymRefreshModuleList(this._hProcess);
|
|
}
|
|
|
|
// Token: 0x06000038 RID: 56 RVA: 0x000026B0 File Offset: 0x000008B0
|
|
public unsafe string GetTypeInfoName(ulong dllBase, int typeIndex)
|
|
{
|
|
char* value;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Name, out value))
|
|
{
|
|
string result = new string(value);
|
|
Marshal.FreeCoTaskMem(new IntPtr((void*)value));
|
|
return result;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x06000039 RID: 57 RVA: 0x000026E4 File Offset: 0x000008E4
|
|
public SymbolTag GetSymbolTag(ulong dllBase, int typeIndex)
|
|
{
|
|
SymbolTag result = SymbolTag.Null;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Tag, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600003A RID: 58 RVA: 0x00002708 File Offset: 0x00000908
|
|
public Variant GetSymbolValue(ulong dllBase, int typeIndex)
|
|
{
|
|
Variant result = default(Variant);
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Value, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600003B RID: 59 RVA: 0x00002730 File Offset: 0x00000930
|
|
public ulong GetSymbolLength(ulong dllBase, int typeIndex)
|
|
{
|
|
ulong result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Length, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600003C RID: 60 RVA: 0x00002750 File Offset: 0x00000950
|
|
public int GetSymbolDataKind(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.DataKind, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600003D RID: 61 RVA: 0x00002770 File Offset: 0x00000970
|
|
public UdtKind GetSymbolUdtKind(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.UdtKind, out result))
|
|
{
|
|
return (UdtKind)result;
|
|
}
|
|
return UdtKind.Unknown;
|
|
}
|
|
|
|
// Token: 0x0600003E RID: 62 RVA: 0x00002794 File Offset: 0x00000994
|
|
public int GetSymbolType(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Type, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x0600003F RID: 63 RVA: 0x000027B4 File Offset: 0x000009B4
|
|
public int GetSymbolBitPosition(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.BitPosition, out result))
|
|
{
|
|
return result;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// Token: 0x06000040 RID: 64 RVA: 0x000027D8 File Offset: 0x000009D8
|
|
public int GetSymbolCount(ulong dllBase, int typeIndex)
|
|
{
|
|
int result = -1;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Count, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x06000041 RID: 65 RVA: 0x000027FC File Offset: 0x000009FC
|
|
public int GetSymbolAddressOffset(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.AddressOffset, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x06000042 RID: 66 RVA: 0x0000281C File Offset: 0x00000A1C
|
|
public BasicType GetSymbolBaseType(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.BaseType, out result);
|
|
return (BasicType)result;
|
|
}
|
|
|
|
// Token: 0x06000043 RID: 67 RVA: 0x0000283C File Offset: 0x00000A3C
|
|
public int GetSymbolOffset(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Offset, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x06000044 RID: 68 RVA: 0x0000285C File Offset: 0x00000A5C
|
|
public int GetSymbolChildrenCount(ulong dllBase, int typeIndex)
|
|
{
|
|
int result;
|
|
Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.ChildrenCount, out result);
|
|
return result;
|
|
}
|
|
|
|
// Token: 0x06000045 RID: 69 RVA: 0x0000287C File Offset: 0x00000A7C
|
|
public StructDescriptor BuildStructDescriptor(ulong dllBase, int typeIndex)
|
|
{
|
|
int num;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.ChildrenCount, out num))
|
|
{
|
|
StructDescriptor structDescriptor = new StructDescriptor(num);
|
|
ulong num2;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.Length, out num2))
|
|
{
|
|
structDescriptor.Length = (int)num2;
|
|
}
|
|
FindChildrenParams findChildrenParams = new FindChildrenParams
|
|
{
|
|
Count = num
|
|
};
|
|
structDescriptor.Length = (int)num2;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, typeIndex, SymbolTypeInfo.FindChildren, ref findChildrenParams))
|
|
{
|
|
for (int i = 0; i < findChildrenParams.Count; i++)
|
|
{
|
|
SymbolInfo symbolInfo = SymbolInfo.Create();
|
|
int num3 = findChildrenParams.Child[i];
|
|
if (this.GetSymbolFromIndex(dllBase, num3, ref symbolInfo))
|
|
{
|
|
int offset;
|
|
SymbolTag tag;
|
|
Variant variant;
|
|
if (Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Offset, out offset) && Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Tag, out tag))
|
|
{
|
|
symbolInfo.Tag = tag;
|
|
symbolInfo.TypeIndex = num3;
|
|
StructMember member = new StructMember(ref symbolInfo, offset);
|
|
structDescriptor.AddMember(member);
|
|
}
|
|
else if (Win32.SymGetTypeInfo(this._hProcess, dllBase, num3, SymbolTypeInfo.Value, out variant))
|
|
{
|
|
symbolInfo.Tag = SymbolTag.Enum;
|
|
symbolInfo.Value = variant.lValue;
|
|
symbolInfo.TypeIndex = num3;
|
|
StructMember structMember = new StructMember(ref symbolInfo, 0);
|
|
int size = symbolInfo.Size;
|
|
if (size != 1)
|
|
{
|
|
if (size != 2)
|
|
{
|
|
if (size == 8)
|
|
{
|
|
structMember.Value = variant.lValue;
|
|
}
|
|
else
|
|
{
|
|
structMember.Value = (long)variant.iValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
structMember.Value = (long)variant.sValue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
structMember.Value = (long)((ulong)variant.bValue);
|
|
}
|
|
structDescriptor.AddMember(structMember);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return structDescriptor;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x0400000E RID: 14
|
|
private static int _instances;
|
|
|
|
// Token: 0x0400000F RID: 15
|
|
private IntPtr _hProcess;
|
|
|
|
// Token: 0x04000010 RID: 16
|
|
private bool _ownHandle;
|
|
}
|
|
}
|