/// <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());
        }
Example #2
0
        /// <summary>
        /// Get the manifests from a file.
        /// </summary>
        /// <param name="filename">The file to extract the manifests from.</param>
        /// <returns>The list of manifests.</returns>
        public static IEnumerable <ExecutableManifest> GetManifests(string filename)
        {
            string fullpath = Path.GetFullPath(filename);

            using (SafeLoadLibraryHandle library =
                       SafeLoadLibraryHandle.LoadLibrary(fullpath, LoadLibraryFlags.LoadLibraryAsImageResource | LoadLibraryFlags.LoadLibraryAsDataFile))
            {
                List <ExecutableManifest> manifests = new List <ExecutableManifest>();

                Win32NativeMethods.EnumResourceNames(library, new IntPtr((int)ResType.MANIFEST), (a, b, c, d) =>
                {
                    try
                    {
                        manifests.Add(new ExecutableManifest(library, fullpath, c));
                    }
                    catch (Win32Exception)
                    {
                    }
                    catch (ArgumentException)
                    {
                    }
                    return(true);
                }, IntPtr.Zero);

                return(manifests);
            }
        }
        /// <summary>
        /// Load a library into memory.
        /// </summary>
        /// <param name="name">The path to the library.</param>
        /// <param name="flags">Additonal flags to pass to LoadLibraryEx</param>
        /// <returns></returns>
        public static SafeLoadLibraryHandle LoadLibrary(string name, LoadLibraryFlags flags)
        {
            SafeLoadLibraryHandle ret = Win32NativeMethods.LoadLibraryEx(name, IntPtr.Zero, flags);

            if (ret.IsInvalid)
            {
                throw new SafeWin32Exception();
            }
            return(ret);
        }
Example #4
0
        /// <summary>
        /// Get the manifests from a file.
        /// </summary>
        /// <param name="filename">The file to extract the manifests from.</param>
        /// <returns>The list of manifests.</returns>
        public static IEnumerable <ExecutableManifest> GetManifests(string filename)
        {
            string fullpath = Path.GetFullPath(filename);

            using (SafeLoadLibraryHandle library =
                       SafeLoadLibraryHandle.LoadLibrary(fullpath, LoadLibraryFlags.LoadLibraryAsImageResource | LoadLibraryFlags.LoadLibraryAsDataFile))
            {
                return(library.GetResources(WellKnownImageResourceType.Manifest).Where(m => m.Size > 0)
                       .Select(m => new ExecutableManifest(fullpath, m.ToArray())).ToArray());
            }
        }
Example #5
0
 /// <summary>
 /// Format a message.
 /// </summary>
 /// <param name="module">The module containing the message.</param>
 /// <param name="message_id">The ID of the message.</param>
 /// <returns>The message. Empty string on error.</returns>
 public static string FormatMessage(SafeLoadLibraryHandle module, uint message_id)
 {
     if (Win32NativeMethods.FormatMessage(FormatFlags.AllocateBuffer | FormatFlags.FromHModule
                                          | FormatFlags.FromSystem | FormatFlags.IgnoreInserts,
                                          module.DangerousGetHandle(), message_id, 0, out SafeLocalAllocBuffer buffer, 0, IntPtr.Zero) > 0)
     {
         using (buffer) {
             return(Marshal.PtrToStringUni(buffer.DangerousGetHandle()).Trim());
         }
     }
     return(string.Empty);
 }
        internal ExecutableManifest(SafeLoadLibraryHandle hModule, string fullpath, IntPtr hName)
        {
            FullPath = fullpath;

            IntPtr hResHandle = Win32NativeMethods.FindResource(hModule, hName, new IntPtr((int)ResType.MANIFEST));

            if (hResHandle == IntPtr.Zero)
            {
                throw new ArgumentException("Can't find manifest resource");
            }

            IntPtr hResource = Win32NativeMethods.LoadResource(hModule, hResHandle);
            IntPtr buf       = Win32NativeMethods.LockResource(hResource);
            int    size      = Win32NativeMethods.SizeofResource(hModule, hResHandle);

            if (size <= 0)
            {
                throw new ArgumentException("Invalid manifest size");
            }
            byte[] manifest = new byte[size];

            Marshal.Copy(buf, manifest, 0, size);
            MemoryStream stm = new MemoryStream(manifest);

            try
            {
                XmlDocument doc = LoadDocument(stm);

                UiAccess       = GetUiAccess(doc);
                AutoElevate    = GetAutoElevate(doc);
                ExecutionLevel = GetExecutionLevel(doc);
                LongPathAware  = GetLongPathAware(doc);

                XmlWriterSettings settings = new XmlWriterSettings
                {
                    Indent              = true,
                    OmitXmlDeclaration  = true,
                    NewLineOnAttributes = true
                };
                StringWriter string_writer = new StringWriter();
                XmlWriter    writer        = XmlWriter.Create(string_writer, settings);
                doc.Save(writer);
                ManifestXml = string_writer.ToString();
            }
            catch (XmlException)
            {
                ParseError  = true;
                ManifestXml = Encoding.UTF8.GetString(stm.ToArray());
            }
        }
Example #7
0
        /// <summary>
        /// Load a library into memory.
        /// </summary>
        /// <param name="name">The path to the library.</param>
        /// <param name="flags">Additonal flags to pass to LoadLibraryEx</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>Handle to the loaded library.</returns>
        public static NtResult <SafeLoadLibraryHandle> LoadLibrary(string name, LoadLibraryFlags flags, bool throw_on_error)
        {
            SafeLoadLibraryHandle ret = Win32NativeMethods.LoadLibraryEx(name, IntPtr.Zero, flags);

            if (ret.IsInvalid)
            {
                if (throw_on_error)
                {
                    throw new SafeWin32Exception();
                }
                return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <SafeLoadLibraryHandle>(false));
            }
            return(ret.CreateResult());
        }
Example #8
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());
        }
Example #9
0
        private void ParseDelayedImport(Dictionary <IntPtr, IntPtr> imports, ImageDelayImportDescriptor desc)
        {
            if (desc.pIAT == 0 || desc.pINT == 0)
            {
                return;
            }

            string name = Marshal.PtrToStringAnsi(RvaToVA(desc.szName));
            IntPtr IAT  = RvaToVA(desc.pIAT);
            IntPtr INT  = RvaToVA(desc.pINT);

            try
            {
                using (SafeLoadLibraryHandle lib = LoadLibrary(name))
                {
                    IntPtr import_name_rva = Marshal.ReadIntPtr(INT);

                    while (import_name_rva != IntPtr.Zero)
                    {
                        IntPtr import;
                        // Ordinal
                        if (import_name_rva.ToInt64() < 0)
                        {
                            import = lib.GetProcAddress(new IntPtr(import_name_rva.ToInt64() & 0xFFFF));
                        }
                        else
                        {
                            IntPtr import_ofs  = RvaToVA(import_name_rva.ToInt64() + 2);
                            string import_name = Marshal.PtrToStringAnsi(import_ofs);
                            import = lib.GetProcAddress(import_name);
                        }

                        if (import != IntPtr.Zero)
                        {
                            imports[IAT] = import;
                        }

                        INT            += IntPtr.Size;
                        IAT            += IntPtr.Size;
                        import_name_rva = Marshal.ReadIntPtr(INT);
                    }
                }
            }
            catch (Win32Exception)
            {
            }
        }
Example #10
0
        /// <summary>
        /// Get the GetStagedPackageOrigin method as a delegate. It's supposed to be exposed by kernel32,
        /// but actually doesn't seem to be.
        /// </summary>
        /// <returns></returns>
        private static GetStagedPackageOrigin FindDelegate()
        {
            GetStagedPackageOrigin result      = null;
            SafeLoadLibraryHandle  kernel_base = SafeLoadLibraryHandle.GetModuleHandleNoThrow("kernelbase");

            if (!kernel_base.IsInvalid)
            {
                result = kernel_base.GetFunctionPointer <GetStagedPackageOrigin>(false);
            }
            if (result != null)
            {
                return(result);
            }
            SafeLoadLibraryHandle kernel32 = SafeLoadLibraryHandle.GetModuleHandle("kernel32");

            return(kernel32.GetFunctionPointer <GetStagedPackageOrigin>());
        }
        internal DbgHelpSymbolResolver(NtProcess process, string dbghelp_path, string symbol_path)
        {
            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);

            _sym_set_options(SymOptions.INCLUDE_32BIT_MODULES | SymOptions.UNDNAME | SymOptions.DEFERRED_LOADS);

            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];
                int      return_length;
                if (EnumProcessModulesEx(Handle, modules, modules.Length * IntPtr.Size, out 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 (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)
                            {
                                System.Diagnostics.Debug.WriteLine($"Couldn't load {dllpath}");
                            }
                        }
                    }
                }
            }
        }
Example #12
0
 internal static extern IntPtr FindResource(SafeLoadLibraryHandle hModule, IntPtr lpName, IntPtr lpType);
Example #13
0
 internal static extern int SizeofResource(SafeLoadLibraryHandle hModule, IntPtr hResInfo);
Example #14
0
 internal static extern bool EnumResourceNames(SafeLoadLibraryHandle hModule, IntPtr lpszType,
                                               EnumResNameProcDelegate lpEnumFunc, IntPtr lParam);
Example #15
0
 internal static extern bool GetModuleHandleEx(int dwFlags, string lpModuleName, out SafeLoadLibraryHandle phModule);
Example #16
0
 static extern bool GetModuleHandleEx(int dwFlags, IntPtr lpModuleName, out SafeLoadLibraryHandle phModule);
 private static extern IntPtr LoadResource(SafeLoadLibraryHandle hModule, IntPtr hResInfo);