예제 #1
0
        public static ProcessModuleWow64Safe[] ModulesWow64Safe(this Process p)
        {
            if (ModuleCache.Count > 100)
            {
                ModuleCache.Clear();
            }

            const int LIST_MODULES_ALL = 3;
            const int MAX_PATH         = 260;

            var hModules = new IntPtr[1024];

            uint cb       = (uint)IntPtr.Size * (uint)hModules.Length;
            uint cbNeeded = cb;


            // this exception is throwing off the program ???
            // WinAPI.EnumProcessModulesEx(p.Handle, hModules, cb, out cbNeeded, LIST_MODULES_ALL);
            if (!WinAPI.EnumProcessModulesEx(p.Handle, hModules, cb, out cbNeeded, LIST_MODULES_ALL))
            {
                throw new Win32Exception();
            }
            uint numMods = cbNeeded / (uint)IntPtr.Size;

            int hash = p.StartTime.GetHashCode() + p.Id + (int)numMods;

            if (ModuleCache.ContainsKey(hash))
            {
                return(ModuleCache[hash]);
            }

            var ret = new List <ProcessModuleWow64Safe>();

            // everything below is fairly expensive, which is why we cache!
            var sb = new StringBuilder(MAX_PATH);

            for (int i = 0; i < numMods; i++)
            {
                sb.Clear();
                if (WinAPI.GetModuleFileNameEx(p.Handle, hModules[i], sb, (uint)sb.Capacity) == 0)
                {
                    throw new Win32Exception();
                }
                string fileName = sb.ToString();

                sb.Clear();
                if (WinAPI.GetModuleBaseName(p.Handle, hModules[i], sb, (uint)sb.Capacity) == 0)
                {
                    throw new Win32Exception();
                }
                string baseName = sb.ToString();

                var moduleInfo = new WinAPI.MODULEINFO();
                if (!WinAPI.GetModuleInformation(p.Handle, hModules[i], out moduleInfo, (uint)Marshal.SizeOf(moduleInfo)))
                {
                    throw new Win32Exception();
                }

                ret.Add(new ProcessModuleWow64Safe()
                {
                    FileName          = fileName,
                    BaseAddress       = moduleInfo.lpBaseOfDll,
                    ModuleMemorySize  = (int)moduleInfo.SizeOfImage,
                    EntryPointAddress = moduleInfo.EntryPoint,
                    ModuleName        = baseName
                });
            }

            ModuleCache.Add(hash, ret.ToArray());

            return(ret.ToArray());
        }
예제 #2
0
        public static ProcessModuleWow64Safe[] ModulesWow64Safe(this Process p)
        {
            if (ModuleCache.Count > 100)
            {
                ModuleCache.Clear();
            }

            const int LIST_MODULES_ALL = 3;
            const int MAX_PATH         = 260;

            var hModules = new IntPtr[1024];

            uint cb = (uint)IntPtr.Size * (uint)hModules.Length;
            uint cbNeeded;

            if (!WinAPI.EnumProcessModulesEx(p.Handle, hModules, cb, out cbNeeded, LIST_MODULES_ALL))
            {
                throw new Win32Exception();
            }
            uint numMods = cbNeeded / (uint)IntPtr.Size;

            // Create MD5 hash of loaded module pointers, if modules have changed we do the full scan
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] hashData = new byte[hModules.Count() * sizeof(Int64)];
            for (int i = 0; i < numMods; i++)
            {
                byte[] addrBytes = BitConverter.GetBytes(hModules[i].ToInt64());
                addrBytes.CopyTo(hashData, i * sizeof(Int64));
            }

            byte[] hashResult = md5.ComputeHash(hashData);
            string hashString = BitConverter.ToString(hashResult).Replace("-", string.Empty).ToLower();

            if (ModuleCache.ContainsKey(hashString))
            {
                return(ModuleCache[hashString]);
            }

            // everything below is fairly expensive, which is why we cache!
            var  ret             = new List <ProcessModuleWow64Safe>();
            var  sb              = new StringBuilder(MAX_PATH);
            bool moduleLoadError = false;

            for (int i = 0; i < numMods; i++)
            {
                try
                {
                    sb.Clear();
                    if (WinAPI.GetModuleFileNameEx(p.Handle, hModules[i], sb, (uint)sb.Capacity) == 0)
                    {
                        throw new Win32Exception();
                    }
                    string fileName = sb.ToString();

                    sb.Clear();
                    if (WinAPI.GetModuleBaseName(p.Handle, hModules[i], sb, (uint)sb.Capacity) == 0)
                    {
                        throw new Win32Exception();
                    }
                    string baseName = sb.ToString();

                    var moduleInfo = new WinAPI.MODULEINFO();
                    if (!WinAPI.GetModuleInformation(p.Handle, hModules[i], out moduleInfo, (uint)Marshal.SizeOf(moduleInfo)))
                    {
                        throw new Win32Exception();
                    }

                    ret.Add(new ProcessModuleWow64Safe()
                    {
                        FileName          = fileName,
                        BaseAddress       = moduleInfo.lpBaseOfDll,
                        ModuleMemorySize  = (int)moduleInfo.SizeOfImage,
                        EntryPointAddress = moduleInfo.EntryPoint,
                        ModuleName        = baseName
                    });
                }
                catch (Win32Exception win32Ex)
                {
                    // This exception doesnt need to be propagated up since it is a common occurence for
                    // handles to be invalidated inbetween calls to module functions. If we miss a module
                    // then we'll get it on the next invocation.
                    Log.Error(win32Ex);
                    moduleLoadError = true;
                    break;
                }
            }

            if (!moduleLoadError)
            {
                ModuleCache.Add(hashString, ret.ToArray());
            }

            return(ret.ToArray());
        }