Skip to content

Commit 1f2b178

Browse files
committed
Snapshot
21 Dec, 2024
1 parent d954820 commit 1f2b178

12 files changed

+419
-129
lines changed

bin/WinDepends.exe

16.5 KB
Binary file not shown.

bin/WinDepends.pdb

3.26 KB
Binary file not shown.

src/WinDepends/CConfigMgr.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* VERSION: 1.00
88
*
9-
* DATE: 16 Dec 2024
9+
* DATE: 19 Dec 2024
1010
*
1111
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
1212
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
@@ -52,10 +52,11 @@ public class CConfiguration
5252
public string ExternalViewerArguments { get; set; }
5353
public string ExternalFunctionHelpURL { get; set; }
5454
public string CoreServerAppLocation { get; set; }
55-
public string SymbolsDllsPath { get; set; }
55+
public string SymbolsDllPath { get; set; }
5656
public string SymbolsStorePath { get; set; }
5757

5858
public uint MinAppAddress { get; set; }
59+
public Color SymbolsHighlightColor { get; set; }
5960

6061
public List<SearchOrderType> SearchOrderListUM { get; set; }
6162
public List<SearchOrderType> SearchOrderListKM { get; set; }
@@ -97,9 +98,10 @@ public CConfiguration(CConfiguration other)
9798
ExternalViewerArguments = other.ExternalViewerArguments;
9899
ExternalFunctionHelpURL = other.ExternalFunctionHelpURL;
99100
CoreServerAppLocation = other.CoreServerAppLocation;
100-
SymbolsDllsPath = other.SymbolsDllsPath;
101+
SymbolsDllPath = other.SymbolsDllPath;
101102
SymbolsStorePath = other.SymbolsStorePath;
102103
MinAppAddress = other.MinAppAddress;
104+
SymbolsHighlightColor = other.SymbolsHighlightColor;
103105

104106
SearchOrderListUM = new List<SearchOrderType>(other.SearchOrderListUM);
105107
SearchOrderListKM = new List<SearchOrderType>(other.SearchOrderListKM);
@@ -126,6 +128,9 @@ public CConfiguration(bool bSetDefault)
126128
MinAppAddress = CConsts.DefaultAppStartAddress;
127129
UseApiSetSchemaFile = false;
128130

131+
SymbolsDllPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
132+
SymbolsHighlightColor = Color.Yellow;
133+
129134
string cpuArch = RuntimeInformation.ProcessArchitecture.ToString().ToLower();
130135
CoreServerAppLocation = $"{Path.GetDirectoryName(Application.ExecutablePath)}\\{CConsts.WinDependsCoreApp}.{cpuArch}.exe";
131136

src/WinDepends/CSymbolResolver.cs

+168-61
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* VERSION: 1.00
88
*
9-
* DATE: 17 Dec 2024
9+
* DATE: 19 Dec 2024
1010
*
1111
* MS Symbols resolver support class.
1212
*
@@ -16,7 +16,8 @@
1616
* PARTICULAR PURPOSE.
1717
*
1818
*******************************************************************************/
19-
using System.Diagnostics;
19+
using Microsoft.Win32.SafeHandles;
20+
using System.Collections.Concurrent;
2021
using System.Runtime.InteropServices;
2122
using System.Text;
2223

@@ -25,24 +26,38 @@ namespace WinDepends;
2526
public static class CSymbolResolver
2627
{
2728
#region "P/Invoke stuff"
28-
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
29-
public delegate IntPtr SymLoadModuleExDelegate(IntPtr hProcess, IntPtr hFile, string ImageName, string ModuleName, long BaseOfDll, int SizeOfDll, IntPtr Data, int Flags);
30-
31-
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
32-
public delegate bool SymInitializeDelegate(IntPtr hProcess, string UserSearchPath, bool fInvadeProcess);
33-
34-
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
35-
public delegate bool SymCleanupDelegate(IntPtr hProcess);
36-
37-
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
38-
public delegate bool SymFromAddrDelegate(IntPtr hProcess, long Address, out long Displacement, ref SYMBOL_INFO Symbol);
39-
40-
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
41-
public delegate uint UnDecorateSymbolNameDelegate(
42-
[MarshalAs(UnmanagedType.LPWStr)] string name,
43-
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder outputString,
44-
int maxStringLength,
45-
UNDNAME flags);
29+
public const uint SYMOPT_CASE_INSENSITIVE = 0x00000001;
30+
public const uint SYMOPT_UNDNAME = 0x00000002;
31+
public const uint SYMOPT_DEFERRED_LOADS = 0x00000004;
32+
public const uint SYMOPT_NO_CPP = 0x00000008;
33+
public const uint SYMOPT_LOAD_LINES = 0x00000010;
34+
public const uint SYMOPT_OMAP_FIND_NEAREST = 0x00000020;
35+
public const uint SYMOPT_LOAD_ANYTHING = 0x00000040;
36+
public const uint SYMOPT_IGNORE_CVREC = 0x00000080;
37+
public const uint SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100;
38+
public const uint SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200;
39+
public const uint SYMOPT_EXACT_SYMBOLS = 0x00000400;
40+
public const uint SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800;
41+
public const uint SYMOPT_IGNORE_NT_SYMPATH = 0x00001000;
42+
public const uint SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000;
43+
public const uint SYMOPT_PUBLICS_ONLY = 0x00004000;
44+
public const uint SYMOPT_NO_PUBLICS = 0x00008000;
45+
public const uint SYMOPT_AUTO_PUBLICS = 0x00010000;
46+
public const uint SYMOPT_NO_IMAGE_SEARCH = 0x00020000;
47+
public const uint SYMOPT_SECURE = 0x00040000;
48+
public const uint SYMOPT_NO_PROMPTS = 0x00080000;
49+
public const uint SYMOPT_OVERWRITE = 0x00100000;
50+
public const uint SYMOPT_IGNORE_IMAGEDIR = 0x00200000;
51+
public const uint SYMOPT_FLAT_DIRECTORY = 0x00400000;
52+
public const uint SYMOPT_FAVOR_COMPRESSED = 0x00800000;
53+
public const uint SYMOPT_ALLOW_ZERO_ADDRESS = 0x01000000;
54+
public const uint SYMOPT_DISABLE_SYMSRV_AUTODETECT = 0x02000000;
55+
public const uint SYMOPT_READONLY_CACHE = 0x04000000;
56+
public const uint SYMOPT_SYMPATH_LAST = 0x08000000;
57+
public const uint SYMOPT_DISABLE_FAST_SYMBOLS = 0x10000000;
58+
public const uint SYMOPT_DISABLE_SYMSRV_TIMEOUT = 0x20000000;
59+
public const uint SYMOPT_DISABLE_SRVSTAR_ON_STARTUP = 0x40000000;
60+
public const uint SYMOPT_DEBUG = 0x80000000;
4661

4762
[Flags]
4863
public enum UNDNAME : uint
@@ -99,29 +114,75 @@ public enum UNDNAME : uint
99114
NoThrowSignatures = 0x0100,
100115
}
101116

102-
[StructLayout(LayoutKind.Sequential)]
117+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
103118
public struct SYMBOL_INFO
104119
{
105-
public uint SizeOfStruct;
106-
public uint TypeIndex;
107-
public ulong Reserved;
108-
public ulong ModBase;
109-
public uint Flags;
110-
public ulong Value;
111-
public ulong Address;
112-
public uint Register;
113-
public uint Scope;
114-
public uint Tag;
115-
public uint NameLen;
116-
public uint MaxNameLen;
117-
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
120+
public UInt32 SizeOfStruct;
121+
public UInt32 TypeIndex;
122+
public UInt64 Reserved;
123+
public UInt64 Reserved2;
124+
public UInt32 Index;
125+
public UInt32 Size;
126+
public UInt64 ModBase;
127+
public UInt32 Flags;
128+
public UInt64 Value;
129+
public UInt64 Address;
130+
public UInt32 Register;
131+
public UInt32 Scope;
132+
public UInt32 Tag;
133+
public UInt32 NameLen;
134+
public UInt32 MaxNameLen;
135+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2000)]
118136
public string Name;
119137
}
120138
#endregion
121139

140+
static readonly UInt32 MAX_SYM_NAME = 2000;
141+
static readonly UInt32 SIZE_OF_SYMBOL_INFO = (uint)Marshal.SizeOf(typeof(SYMBOL_INFO)) - (MAX_SYM_NAME * 2);
142+
122143
// P/Invoke delegates
144+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
145+
delegate IntPtr SymLoadModuleExDelegate(SafeProcessHandle hProcess,
146+
IntPtr hFile,
147+
[MarshalAs(UnmanagedType.LPWStr)] string ImageName,
148+
[MarshalAs(UnmanagedType.LPWStr)] string ModuleName,
149+
UInt64 BaseOfDll,
150+
int SizeOfDll,
151+
IntPtr Data,
152+
int Flags);
153+
154+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
155+
delegate bool SymInitializeDelegate(SafeProcessHandle hProcess,
156+
[MarshalAs(UnmanagedType.LPWStr)] string UserSearchPath,
157+
bool fInvadeProcess);
158+
159+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
160+
delegate bool SymCleanupDelegate(SafeProcessHandle hProcess);
161+
162+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
163+
delegate bool SymFromAddrDelegate(
164+
SafeProcessHandle hProcess,
165+
UInt64 Address,
166+
out UInt64 Displacement,
167+
ref SYMBOL_INFO Symbol);
168+
169+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
170+
delegate uint SymGetOptionsDelegate();
171+
172+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
173+
delegate uint SymSetOptionsDelegate(uint options);
174+
175+
[UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)]
176+
delegate uint UnDecorateSymbolNameDelegate(
177+
[MarshalAs(UnmanagedType.LPWStr)] string name,
178+
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder outputString,
179+
int maxStringLength,
180+
UNDNAME flags);
181+
123182
static SymLoadModuleExDelegate SymLoadModuleEx;
124183
static SymInitializeDelegate SymInitialize;
184+
static SymGetOptionsDelegate SymGetOptions;
185+
static SymSetOptionsDelegate SymSetOptions;
125186
static SymCleanupDelegate SymCleanup;
126187
static SymFromAddrDelegate SymFromAddr;
127188
static UnDecorateSymbolNameDelegate UnDecorateSymbolName;
@@ -132,23 +193,55 @@ public struct SYMBOL_INFO
132193
public static string DllsPath { get; set; }
133194
public static string StorePath { get; set; }
134195

196+
static readonly SafeProcessHandle CurrentProcess = new SafeProcessHandle(new IntPtr(-1), false);
197+
198+
private struct SymModuleItem
199+
{
200+
public IntPtr BaseAddress;
201+
}
202+
203+
static readonly ConcurrentDictionary<string, SymModuleItem> symModulesCache = new();
204+
205+
public static void CacheSymModule(string symModuleName, IntPtr baseAddress)
206+
{
207+
var item = new SymModuleItem { BaseAddress = baseAddress };
208+
symModulesCache.AddOrUpdate(symModuleName, item, (key, oldValue) => item);
209+
}
210+
211+
public static IntPtr RetrieveCachedSymModule(string symModuleName)
212+
{
213+
if (symModulesCache.TryGetValue(symModuleName, out var item))
214+
{
215+
return item.BaseAddress;
216+
}
217+
else
218+
{
219+
return IntPtr.Zero;
220+
}
221+
}
222+
135223
private static void ClearDelegates()
136224
{
137225
SymLoadModuleEx = null;
138226
SymInitialize = null;
139227
SymCleanup = null;
140228
SymFromAddr = null;
141229
UnDecorateSymbolName = null;
230+
SymSetOptions = null;
231+
SymGetOptions = null;
142232
}
143233
private static bool InitializeDelegates()
144234
{
145235
UnDecorateSymbolName = Marshal.GetDelegateForFunctionPointer<UnDecorateSymbolNameDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "UnDecorateSymbolNameW"));
146236
SymLoadModuleEx = Marshal.GetDelegateForFunctionPointer<SymLoadModuleExDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymLoadModuleExW"));
147-
SymInitialize = Marshal.GetDelegateForFunctionPointer<SymInitializeDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymInitialize"));
237+
SymGetOptions = Marshal.GetDelegateForFunctionPointer<SymGetOptionsDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymGetOptions"));
238+
SymSetOptions = Marshal.GetDelegateForFunctionPointer<SymSetOptionsDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymSetOptions"));
239+
SymInitialize = Marshal.GetDelegateForFunctionPointer<SymInitializeDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymInitializeW"));
240+
SymFromAddr = Marshal.GetDelegateForFunctionPointer<SymFromAddrDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymFromAddrW"));
148241
SymCleanup = Marshal.GetDelegateForFunctionPointer<SymCleanupDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymCleanup"));
149-
SymFromAddr = Marshal.GetDelegateForFunctionPointer<SymFromAddrDelegate>(NativeMethods.GetProcAddress(DbgHelpModule, "SymFromAddr"));
150242

151-
if (UnDecorateSymbolName == null || SymLoadModuleEx == null || SymInitialize == null || SymCleanup == null || SymFromAddr == null)
243+
if (UnDecorateSymbolName == null || SymLoadModuleEx == null || SymGetOptions == null || SymSetOptions == null ||
244+
SymInitialize == null || SymCleanup == null || SymFromAddr == null)
152245
{
153246
ClearDelegates();
154247
return false;
@@ -157,17 +250,25 @@ private static bool InitializeDelegates()
157250
return true;
158251
}
159252

160-
public static void AllocateSymbolResolver(string dllsPath, string storePath)
253+
public static void AllocateSymbolResolver(string dllPath, string storePath)
161254
{
162-
DllsPath = string.IsNullOrEmpty(dllsPath) ? CConsts.DbgHelpDll : Path.Combine(dllsPath, CConsts.DbgHelpDll);
255+
DllsPath = Path.Combine(dllPath, CConsts.DbgHelpDll);
163256
StorePath = storePath;
164257

165-
DbgHelpModule = NativeMethods.LoadLibraryEx(DllsPath, IntPtr.Zero, NativeMethods.LoadLibraryFlags.LOAD_LIBRARY_SEARCH_SYSTEM32);
258+
DbgHelpModule = NativeMethods.LoadLibraryEx(DllsPath, IntPtr.Zero, 0);
166259
if (DbgHelpModule != IntPtr.Zero)
167260
{
168261
if (InitializeDelegates())
169262
{
170-
SymbolsInitialized = SymInitialize(Process.GetCurrentProcess().Handle, StorePath, false);
263+
var symOptions = SymGetOptions();
264+
265+
//SymSetOptions((symOptions | SYMOPT_DEFERRED_LOADS | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_PUBLICS_ONLY) & ~SYMOPT_UNDNAME);
266+
SymSetOptions(symOptions | SYMOPT_DEFERRED_LOADS |
267+
SYMOPT_CASE_INSENSITIVE |
268+
SYMOPT_UNDNAME |
269+
SYMOPT_AUTO_PUBLICS);
270+
271+
SymbolsInitialized = SymInitialize(CurrentProcess, StorePath, false);
171272
}
172273
}
173274

@@ -179,11 +280,12 @@ public static void ReleaseSymbolResolver()
179280
{
180281
if (SymbolsInitialized)
181282
{
182-
SymCleanup(Process.GetCurrentProcess().Handle);
283+
SymCleanup(CurrentProcess);
183284
}
184285
NativeMethods.FreeLibrary(DbgHelpModule);
185286
DbgHelpModule = IntPtr.Zero;
186287
ClearDelegates();
288+
SymbolsInitialized = false;
187289
}
188290
}
189291

@@ -208,42 +310,47 @@ static internal string UndecorateFunctionName(string functionName)
208310

209311
return string.Empty;
210312
}
211-
static internal bool LoadPDBFile(string pdbFileName)
313+
static internal IntPtr LoadModule(string fileName, UInt64 baseAddress)
212314
{
213-
if (SymbolsInitialized == false)
315+
if (!SymbolsInitialized)
214316
{
215-
return false;
317+
return IntPtr.Zero;
216318
}
217319
else
218320
{
219-
return IntPtr.Zero != SymLoadModuleEx(Process.GetCurrentProcess().Handle,
220-
IntPtr.Zero,
221-
pdbFileName,
222-
null,
223-
0,
224-
0,
225-
IntPtr.Zero,
226-
0);
321+
return SymLoadModuleEx(CurrentProcess,
322+
IntPtr.Zero,
323+
fileName,
324+
null,
325+
baseAddress,
326+
0,
327+
IntPtr.Zero,
328+
0);
227329
}
228330
}
229331

230-
public static bool QuerySymbolForAddress(long address, out string symbolName)
332+
public static bool QuerySymbolForAddress(UInt64 address, out string symbolName)
231333
{
232-
if (SymbolsInitialized == false)
334+
symbolName = null;
335+
336+
if (!SymbolsInitialized)
233337
{
234-
symbolName = null;
235338
return false;
236339
}
237340

238-
SYMBOL_INFO symbol = new();
239-
symbol.SizeOfStruct = (uint)Marshal.SizeOf(symbol);
341+
var symbolInfo = new SYMBOL_INFO
342+
{
343+
SizeOfStruct = SIZE_OF_SYMBOL_INFO,
344+
MaxNameLen = MAX_SYM_NAME
345+
};
240346

241-
if (SymFromAddr(Process.GetCurrentProcess().Handle, address, out long displacement, ref symbol))
347+
UInt64 displacement = 0;
348+
if (SymFromAddr(CurrentProcess, address, out displacement, ref symbolInfo))
242349
{
243-
symbolName = symbol.Name;
350+
symbolName = symbolInfo.Name;
244351
return true;
245352
}
246-
symbolName = null;
353+
247354
return false;
248355
}
249356

0 commit comments

Comments
 (0)