/// <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="parse_clients">True to parse client RPC interfaces.</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, bool parse_clients) { List <RpcServer> servers = new List <RpcServer>(); using (var lib = SafeLoadLibraryHandle.LoadLibrary(file, LoadLibraryFlags.DontResolveDllReferences)) { var sections = lib.GetImageSections(); var offsets = sections.SelectMany(s => FindRpcServerInterfaces(s, parse_clients)); if (offsets.Any()) { using (var sym_resolver = SymbolResolver.Create(NtProcess.Current, dbghelp_path, symbol_path)) { 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, NdrParserFlags.IgnoreUserMarshal); IntPtr ifspec = lib.DangerousGetHandle() + (int)offset.Offset; var rpc = parser.ReadFromRpcServerInterface(ifspec); servers.Add(new RpcServer(rpc, parser.ComplexTypes, file, offset.Offset, offset.Client)); } } } } return(servers.AsReadOnly()); }
private COMProxyInstance(string path, Guid clsid, ISymbolResolver resolver) { NdrParser parser = new NdrParser(resolver); Entries = parser.ReadFromComProxyFile(path, clsid); ComplexTypes = parser.ComplexTypes; }
private COMProxyInterfaceInstance(COMCLSIDEntry clsid, ISymbolResolver resolver, COMInterfaceEntry intf, COMRegistry registry) { NdrParser parser = new NdrParser(resolver); Entry = parser.ReadFromComProxyFile(clsid.DefaultServer, clsid.Clsid, new Guid[] { intf.Iid }).FirstOrDefault(); ComplexTypes = parser.ComplexTypes; OriginalName = intf.Name; ClassEntry = clsid; m_registry = registry; }
private NdrProcedureDefinition[] ReadProcs(NdrParser parser, Guid base_iid, CInterfaceStubHeader stub) { int start_ofs = 3; if (base_iid == COMInterfaceEntry.IID_IDispatch) { start_ofs = 7; } return(parser.ReadFromMidlServerInfo(stub.pServerInfo, start_ofs, stub.DispatchTableCount).ToArray()); }
/// <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()); }
private bool InitFromFileInfo(IntPtr pInfo) { List <COMProxyInstanceEntry> entries = new List <COMProxyInstanceEntry>(); List <NdrComplexTypeReference> complex_types = new List <NdrComplexTypeReference>(); NdrParser parser = new NdrParser(); foreach (var file_info in COMUtilities.EnumeratePointerList <ProxyFileInfo>(pInfo)) { string[] names = file_info.GetNames(); CInterfaceStubHeader[] stubs = file_info.GetStubs(); Guid[] base_iids = file_info.GetBaseIids(); for (int i = 0; i < names.Length; ++i) { entries.Add(new COMProxyInstanceEntry(this, names[i], stubs[i].GetIid(), base_iids[i], stubs[i].DispatchTableCount, ReadProcs(parser, base_iids[i], stubs[i]))); } } complex_types.AddRange(parser.Types.OfType <NdrBaseStructureTypeReference>()); complex_types.AddRange(parser.Types.OfType <NdrUnionTypeReference>()); Entries = entries.AsReadOnly(); ComplexTypes = complex_types.AsReadOnly(); return(true); }