Exemplo n.º 1
0
        /// <summary>
        /// Parse all RPC servers from a PE file.
        /// </summary>
        /// <param name="file">The PE file to parse.</param>
        /// <param name="dbghelp_path">Path to a DBGHELP DLL to resolve symbols.</param>
        /// <param name="symbol_path">Symbol path for DBGHELP</param>
        /// <param name="flags">Flags for the RPC parser.</param>
        /// <remarks>This only works for PE files with the same bitness as the current process.</remarks>
        /// <returns>A list of parsed RPC server.</returns>
        public static IEnumerable <RpcServer> ParsePeFile(string file, string dbghelp_path, string symbol_path, RpcServerParserFlags flags)
        {
            List <RpcServer> servers = new List <RpcServer>();

            using (var result = SafeLoadLibraryHandle.LoadLibrary(file, LoadLibraryFlags.DontResolveDllReferences, false))
            {
                if (!result.IsSuccess)
                {
                    return(servers.AsReadOnly());
                }

                var lib      = result.Result;
                var sections = lib.GetImageSections();
                var offsets  = sections.SelectMany(s => FindRpcServerInterfaces(s, flags.HasFlagSet(RpcServerParserFlags.ParseClients)));
                if (offsets.Any())
                {
                    SymbolResolverFlags symbol_flags = flags.HasFlagSet(RpcServerParserFlags.SymSrvFallback) ? SymbolResolverFlags.SymSrvFallback : SymbolResolverFlags.None;

                    using (var sym_resolver = !flags.HasFlagSet(RpcServerParserFlags.IgnoreSymbols) ? SymbolResolver.Create(NtProcess.Current,
                                                                                                                            dbghelp_path, symbol_path, symbol_flags, null) : null)
                    {
                        NdrParserFlags parser_flags = NdrParserFlags.IgnoreUserMarshal;
                        if (flags.HasFlagSet(RpcServerParserFlags.ResolveStructureNames))
                        {
                            parser_flags |= NdrParserFlags.ResolveStructureNames;
                        }

                        foreach (var offset in offsets)
                        {
                            IMemoryReader reader = new CurrentProcessMemoryReader(sections.Select(s => Tuple.Create(s.Data.DangerousGetHandle().ToInt64(), (int)s.Data.ByteLength)));
                            NdrParser     parser = new NdrParser(reader, NtProcess.Current,
                                                                 sym_resolver, parser_flags);
                            IntPtr ifspec = lib.DangerousGetHandle() + (int)offset.Offset;
                            try
                            {
                                var rpc = parser.ReadFromRpcServerInterface(ifspec, lib.DangerousGetHandle());
                                servers.Add(new RpcServer(rpc, parser.ComplexTypes, file, offset.Offset, offset.Client));
                            }
                            catch (NdrParserException)
                            {
                            }
                        }
                    }
                }
            }

            return(servers.AsReadOnly());
        }
Exemplo n.º 2
0
        internal DbgHelpSymbolResolver(NtProcess process, string dbghelp_path, string symbol_path, SymbolResolverFlags flags, TextWriter trace_writer)
        {
            Process      = process.Duplicate();
            _dbghelp_lib = SafeLoadLibraryHandle.LoadLibrary(dbghelp_path);
            GetFunc(ref _sym_init);
            GetFunc(ref _sym_cleanup);
            GetFunc(ref _sym_from_name);
            GetFunc(ref _sym_set_options);
            GetFunc(ref _sym_enum_modules);
            GetFunc(ref _sym_from_addr);
            GetFunc(ref _sym_get_module_info);
            GetFunc(ref _sym_load_module);
            GetFunc(ref _sym_refresh_module_list);
            GetFunc(ref _sym_enum_types);
            GetFunc(ref _sym_get_type_from_name);
            GetFunc(ref _sym_enum_types_by_name);
            GetFunc(ref _sym_get_type_info);
            GetFunc(ref _sym_get_type_info_dword, "SymGetTypeInfo");
            GetFunc(ref _sym_get_type_info_ptr, "SymGetTypeInfo");
            GetFunc(ref _sym_get_type_info_var, "SymGetTypeInfo");
            GetFunc(ref _sym_get_type_info_long, "SymGetTypeInfo");
            GetFunc(ref _sym_from_index);
            GetFunc(ref _sym_enum_symbols);
            GetFunc(ref _sym_set_context);
            GetFunc(ref _sym_get_home_directory);

            _trace_writer = trace_writer ?? new TraceTextWriter();
            SymOptions options = SymOptions.INCLUDE_32BIT_MODULES | SymOptions.UNDNAME | SymOptions.DEFERRED_LOADS;

            _enable_symsrv_fallback = flags.HasFlagSet(SymbolResolverFlags.SymSrvFallback) && !CheckForSymsrv(_dbghelp_lib.FullPath);
            _trace_symbol_loading   = flags.HasFlagSet(SymbolResolverFlags.TraceSymbolLoading);
            if (_trace_symbol_loading)
            {
                options |= SymOptions.DEBUG;
            }
            if (_enable_symsrv_fallback)
            {
                var srv = GetFallbackSymbolPaths(symbol_path);
                _symbol_cache_path  = srv.Item1;
                _symbol_server_path = srv.Item2;
                if (string.IsNullOrEmpty(_symbol_cache_path))
                {
                    throw new ArgumentException("Must specify an existing local path in the symbol path to store downloaded symbols.");
                }
                options |= SymOptions.DEBUG;
            }
            if (flags.HasFlagSet(SymbolResolverFlags.DisableExportSymbols))
            {
                options |= SymOptions.EXACT_SYMBOLS;
            }
            _sym_set_options(options);

            if (!_sym_init(Handle, symbol_path, true))
            {
                // If SymInitialize failed then we'll have to bootstrap modules manually.
                if (!_sym_init(Handle, symbol_path, false))
                {
                    throw new Win32Exception();
                }

                IntPtr[] modules = new IntPtr[1024];
                if (Win32NativeMethods.EnumProcessModulesEx(Handle, modules, modules.Length * IntPtr.Size, out int return_length,
                                                            process.Is64Bit ? EnumProcessModulesFilter.LIST_MODULES_64BIT : EnumProcessModulesFilter.LIST_MODULES_32BIT))
                {
                    foreach (IntPtr module in modules.Take(return_length / IntPtr.Size))
                    {
                        StringBuilder dllpath = new StringBuilder(260);
                        if (Win32NativeMethods.GetModuleFileNameEx(Handle, module, dllpath, dllpath.Capacity) > 0)
                        {
                            if (_sym_load_module(Handle, IntPtr.Zero, dllpath.ToString(),
                                                 Path.GetFileNameWithoutExtension(dllpath.ToString()), module.ToInt64(), GetImageSize(module)) == 0)
                            {
                                Debug.WriteLine($"Couldn't load {dllpath}");
                            }
                        }
                    }
                }
            }

            if (_trace_symbol_loading || _enable_symsrv_fallback)
            {
                _callback_handler = DbgHelpDebugCallbackHandler.GetInstance(_dbghelp_lib);
                _callback_handler.RegisterHandler(Handle, SymDebugCallback);
            }
        }
 /// <summary>
 /// Create a new instance of a symbol resolver.
 /// </summary>
 /// <param name="process">The process in which the symbols should be resolved.</param>
 /// <param name="dbghelp_path">The path to dbghelp.dll, ideally should use the one which comes with Debugging Tools for Windows.</param>
 /// <param name="symbol_path">The symbol path.</param>
 /// <param name="flags">Flags for the symbol resolver.</param>
 /// <param name="trace_writer">A text writer for output when specifying the <see cref="SymbolResolverFlags.TraceSymbolLoading">TraceSymbolLoading</see> flag.</param>
 /// <returns>The instance of a symbol resolver. Should be disposed when finished.</returns>
 public static ISymbolResolver Create(NtProcess process, string dbghelp_path, string symbol_path, SymbolResolverFlags flags, TextWriter trace_writer)
 {
     return(new DbgHelpSymbolResolver(process, dbghelp_path, symbol_path, flags, trace_writer));
 }