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()); }
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()); }