3030
3131namespace NtApiDotNet . Win32 . Debugger
3232{
33- internal sealed partial class DbgHelpSymbolResolver : ISymbolResolver , ISymbolTypeResolver , IDisposable
33+ internal sealed partial class DbgHelpSymbolResolver : ISymbolResolver , ISymbolTypeResolver , ISymbolEnumerator , IDisposable
3434 {
3535 public static string DEFAULT_SYMSRV = "https://msdl.microsoft.com/download/symbols" ;
3636
@@ -215,6 +215,13 @@ delegate bool SymGetHomeDirectoryW(
215215 HomeDirectoryType type ,
216216 [ In , Out ] StringBuilder dir ,
217217 IntPtr size
218+ ) ;
219+
220+ [ UnmanagedFunctionPointer ( CallingConvention . StdCall , CharSet = CharSet . Unicode , SetLastError = true ) ]
221+ delegate bool SymGetDiaSession (
222+ SafeKernelObjectHandle hProcess ,
223+ long BaseOfDll ,
224+ [ MarshalAs ( UnmanagedType . Interface ) ] out IDiaSession DiaSession
218225 ) ;
219226
220227 private readonly SafeLoadLibraryHandle _dbghelp_lib ;
@@ -239,6 +246,7 @@ IntPtr size
239246 private readonly SymSetContext _sym_set_context ;
240247 private readonly SymEnumSymbolsW _sym_enum_symbols ;
241248 private readonly SymGetHomeDirectoryW _sym_get_home_directory ;
249+ private readonly SymGetDiaSession _sym_get_dia_session ;
242250 private IEnumerable < SymbolLoadedModule > _loaded_modules ;
243251 private readonly TextWriter _trace_writer ;
244252 private readonly bool _trace_symbol_loading ;
@@ -250,6 +258,11 @@ IntPtr size
250258 private void GetFunc < T > ( ref T f ) where T : Delegate
251259 {
252260 f = _dbghelp_lib . GetFunctionPointer < T > ( ) ;
261+ }
262+
263+ private void GetFuncNoThrow < T > ( ref T f ) where T : Delegate
264+ {
265+ f = _dbghelp_lib . GetFunctionPointer < T > ( false ) ;
253266 }
254267
255268 private void GetFunc < T > ( ref T f , string name ) where T : Delegate
@@ -267,6 +280,29 @@ private static string GetNameFromSymbolInfo(SafeStructureInOutBuffer<SYMBOL_INFO
267280 return buffer . Data . ReadNulTerminatedUnicodeString ( ) ;
268281 }
269282
283+ private DllMachineType GetSymbolMachineType ( SYMBOL_INFO sym_info )
284+ {
285+ IDiaSession session = null ;
286+ IDiaSymbol symbol = null ;
287+ try
288+ {
289+ if ( _sym_get_dia_session == null || ! _sym_get_dia_session ( Handle , sym_info . ModBase , out session ) )
290+ return DllMachineType . UNKNOWN ;
291+
292+ if ( session . findSymbolByVA ( sym_info . Address , sym_info . Tag , out symbol ) != 0 )
293+ return DllMachineType . UNKNOWN ;
294+
295+ return ( DllMachineType ) symbol . machineType ;
296+ }
297+ finally
298+ {
299+ if ( symbol != null )
300+ Marshal . ReleaseComObject ( symbol ) ;
301+ if ( session != null )
302+ Marshal . ReleaseComObject ( session ) ;
303+ }
304+ }
305+
270306 private static SafeStructureInOutBuffer < SYMBOL_INFO > MapSymbolInfo ( IntPtr symbol_info )
271307 {
272308 int base_size = Marshal . SizeOf ( typeof ( SYMBOL_INFO ) ) ;
@@ -707,7 +743,8 @@ private DataSymbolInformation GetSymbolInfoForAddress(IntPtr address)
707743 var result = sym_info . Result ;
708744
709745 return new DataSymbolInformation ( result . Tag , result . Size , result . TypeIndex ,
710- result . Address , GetModuleForAddress ( new IntPtr ( result . ModBase ) ) , GetNameFromSymbolInfo ( sym_info ) ) ;
746+ result . Address , GetModuleForAddress ( new IntPtr ( result . ModBase ) ) ,
747+ GetNameFromSymbolInfo ( sym_info ) , GetSymbolMachineType ( result ) ) ;
711748 }
712749
713750 return null ;
@@ -724,7 +761,8 @@ private DataSymbolInformation GetSymbolInfoForName(string name)
724761 }
725762 var result = sym_info . Result ;
726763 return new DataSymbolInformation ( result . Tag , result . Size , result . TypeIndex ,
727- result . Address , GetModuleForAddress ( new IntPtr ( result . ModBase ) ) , GetNameFromSymbolInfo ( sym_info ) ) ;
764+ result . Address , GetModuleForAddress ( new IntPtr ( result . ModBase ) ) ,
765+ GetNameFromSymbolInfo ( sym_info ) , GetSymbolMachineType ( result ) ) ;
728766 }
729767 }
730768
@@ -850,8 +888,20 @@ private Tuple<string, Uri> GetFallbackSymbolPaths(string symbol_path)
850888 }
851889 }
852890 return Tuple . Create ( cache_path , server_path ) ;
891+ }
892+
893+ private bool GetSymbolInfo ( List < SymbolInformation > symbols , IntPtr symbol_info , Dictionary < long , SymbolLoadedModule > modules )
894+ {
895+ using ( var sym_info = MapSymbolInfo ( symbol_info ) )
896+ {
897+ var result = sym_info . Result ;
898+ var symbol = new DataSymbolInformation ( result . Tag , result . Size , result . TypeIndex ,
899+ result . Address , GetModuleForAddress ( new IntPtr ( result . ModBase ) ) ,
900+ GetNameFromSymbolInfo ( sym_info ) , GetSymbolMachineType ( result ) ) ;
901+ symbols . Add ( symbol ) ;
902+ return true ;
903+ }
853904 }
854-
855905 #endregion
856906
857907 #region Public Methods
@@ -1058,6 +1108,23 @@ public TypeInformation GetTypeForSymbolByAddress(IntPtr address)
10581108 var ret = CreateType ( type_cache , symbol . Tag , symbol . Module . BaseAddress . ToInt64 ( ) , symbol . TypeIndex , symbol . Size , symbol . Module , symbol . Name , symbol . Address ) ;
10591109 type_cache . FixupPointerTypes ( ) ;
10601110 return ret ;
1111+ }
1112+
1113+ public IEnumerable < SymbolInformation > EnumerateSymbols ( IntPtr base_address , string mask )
1114+ {
1115+ if ( string . IsNullOrWhiteSpace ( mask ) )
1116+ {
1117+ throw new ArgumentException ( $ "'{ nameof ( mask ) } ' cannot be null or whitespace.", nameof ( mask ) ) ;
1118+ }
1119+
1120+ List < SymbolInformation > symbols = new List < SymbolInformation > ( ) ;
1121+ Dictionary < long , SymbolLoadedModule > modules = GetLoadedModules ( ) . ToDictionary ( m => m . BaseAddress . ToInt64 ( ) ) ;
1122+ if ( ! _sym_enum_symbols ( Handle , base_address . ToInt64 ( ) ,
1123+ mask , ( s , z , x ) => GetSymbolInfo ( symbols , s , modules ) , IntPtr . Zero ) )
1124+ {
1125+ Win32Utils . GetLastWin32Error ( ) . ToNtException ( ) ;
1126+ }
1127+ return symbols . AsReadOnly ( ) ;
10611128 }
10621129
10631130 #endregion
@@ -1091,6 +1158,7 @@ internal DbgHelpSymbolResolver(NtProcess process, string dbghelp_path, string sy
10911158 GetFunc ( ref _sym_enum_symbols ) ;
10921159 GetFunc ( ref _sym_set_context ) ;
10931160 GetFunc ( ref _sym_get_home_directory ) ;
1161+ GetFuncNoThrow ( ref _sym_get_dia_session ) ;
10941162
10951163 _trace_writer = trace_writer ?? new TraceTextWriter ( ) ;
10961164 SymOptions options = SymOptions . INCLUDE_32BIT_MODULES | SymOptions . UNDNAME | SymOptions . DEFERRED_LOADS ;
@@ -1178,8 +1246,8 @@ void IDisposable.Dispose()
11781246 {
11791247 Dispose ( true ) ;
11801248 GC . SuppressFinalize ( this ) ;
1181- }
1182-
1249+ }
1250+
11831251 #endregion
11841252 }
11851253}
0 commit comments