public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { try { byte[] peImageData; peImageData = PEImageHelper.DirectCopy(_process.UnsafeGetModule((void *)moduleHandle), imageLayout); peImageData = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.File); File.WriteAllBytes(filePath, peImageData); return(true); } catch { return(false); } }
private void mnuViewFunctions_Click(object sender, EventArgs e) { if (lvwModules.SelectedIndices.Count == 0) { return; } var functionsForm = new FunctionsForm(_process.UnsafeGetModule((void *)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null))); functionsForm.Show(); }
private void mnuViewFunctions_Click(object sender, EventArgs e) { if (lvwModules.SelectedIndices.Count == 0) { return; } FunctionsForm functionsForm; #pragma warning disable IDE0067 functionsForm = new FunctionsForm(_process.UnsafeGetModule((void *)ulong.Parse(lvwModules.GetFirstSelectedSubItem(chModuleHandle.Index).Text.Substring(2), NumberStyles.HexNumber, null))); #pragma warning restore IDE0067 functionsForm.FormClosed += (v1, v2) => functionsForm.Dispose(); functionsForm.Show(); }
public FunctionsForm(uint processId, nuint moduleHandle) { InitializeComponent(); Utils.ScaleByDpi(this); process = NativeProcess.Open(processId); if (process.IsInvalid) { throw new InvalidOperationException(); } module = process.UnsafeGetModule((void *)moduleHandle); Text = TitleComposer.Compose(true, "Export Functions", module.Name, null); Utils.EnableDoubleBuffer(lvwFunctions); lvwFunctions.ListViewItemSorter = new ListViewItemSorter(lvwFunctions, new[] { TypeCode.String, TypeCode.UInt64, TypeCode.Int16 }) { AllowHexLeading = true }; RefreshFunctionList(); }
/// <summary> /// 直接从内存中复制模块,不执行格式转换操作 /// </summary> /// <param name="processId">进程ID</param> /// <param name="moduleHandle">模块句柄</param> /// <param name="imageLayout">模块在内存中的格式</param> /// <param name="useSectionHeadersInFile">是否使用文件中的节头</param> /// <param name="alternativeToImagePath">如果无法正常获取模块路径,可提供备选模块路径</param> /// <returns></returns> public static byte[] DirectCopy(uint processId, void *moduleHandle, ImageLayout imageLayout, bool useSectionHeadersInFile, string alternativeToImagePath) { if (processId == 0) { throw new ArgumentNullException(nameof(processId)); } if (moduleHandle is null) { throw new ArgumentNullException(nameof(moduleHandle)); } if (useSectionHeadersInFile) { if (string.IsNullOrEmpty(alternativeToImagePath)) { alternativeToImagePath = null; } else { if (!File.Exists(alternativeToImagePath)) { throw new FileNotFoundException(nameof(alternativeToImagePath)); } } } using (NativeProcess process = NativeProcess.Open(processId)) { PageInfo firstPageInfo; string imagePath; byte[] peImageData; uint imageSize; firstPageInfo = process.EnumeratePageInfos(moduleHandle, moduleHandle).First(); if (useSectionHeadersInFile) { imagePath = process.UnsafeGetModule(moduleHandle).ImagePath; if (string.IsNullOrEmpty(imagePath) || !File.Exists(imagePath)) { imagePath = alternativeToImagePath; } } else { imagePath = default; } // 获取模块路径(如果需要使用文件中的节头) if (useSectionHeadersInFile) { imageSize = GetImageSize(File.ReadAllBytes(imagePath), imageLayout); } else { byte[] peHeaderData; peHeaderData = new byte[(uint)firstPageInfo.Size]; process.ReadBytes(moduleHandle, peHeaderData); imageSize = GetImageSize(peHeaderData, imageLayout); } // 获取模块在内存中的大小 peImageData = new byte[imageSize]; switch (imageLayout) { case ImageLayout.File: if (!process.TryReadBytes(firstPageInfo.Address, peImageData, 0, imageSize)) { throw new InvalidOperationException(); } break; case ImageLayout.Memory: foreach (PageInfo pageInfo in process.EnumeratePageInfos(moduleHandle, (byte *)moduleHandle + imageSize)) { uint offset; offset = (uint)((ulong)pageInfo.Address - (ulong)moduleHandle); process.TryReadBytes(pageInfo.Address, peImageData, offset, (uint)pageInfo.Size); } break; default: throw new NotSupportedException(); } // 转储 if (useSectionHeadersInFile) { using (PEImage peHeader = new PEImage(imagePath, false)) { int startOffset; int endOffset; byte[] sectionHeadersData; startOffset = (int)peHeader.ImageSectionHeaders.First().StartOffset; endOffset = (int)peHeader.ImageSectionHeaders.Last().EndOffset; sectionHeadersData = peHeader.CreateReader((FileOffset)startOffset).ReadBytes(endOffset - startOffset); Buffer.BlockCopy(sectionHeadersData, 0, peImageData, startOffset, endOffset - startOffset); } } // 替换节头(如果需要使用文件中的节头) return(peImageData); } }
public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { try { NativeModule module; ClrModule dacModule; InjectionClrVersion clrVersion; InjectionOptions injectionOptions; MetadataInfoService metadataInfoService; MetadataInfo metadataInfo; byte[] peImageData; module = _process.UnsafeGetModule((void *)moduleHandle); dacModule = TryGetDacModule(module); if (dacModule is null) { return(false); } switch (dacModule.Runtime.ClrInfo.Version.Major) { case 2: clrVersion = InjectionClrVersion.V2; break; case 4: clrVersion = InjectionClrVersion.V4; break; default: return(false); } // 判断要dump的模块的CLR版本 injectionOptions = new InjectionOptions { PortName = Guid.NewGuid().ToString(), ObjectName = Guid.NewGuid().ToString() }; if (!_process.InjectManaged(typeof(MetadataInfoService).Assembly.Location, typeof(Injection).FullName, "Main", XmlSerializer.Serialize(injectionOptions), clrVersion, out int result) || result != 0) { return(false); } metadataInfoService = (MetadataInfoService)Activator.GetObject(typeof(MetadataInfoService), $"Ipc://{injectionOptions.PortName}/{injectionOptions.ObjectName}"); // 注入DLL,通过.NET Remoting获取MetadataInfoService实例 metadataInfo = XmlSerializer.Deserialize <MetadataInfo>(metadataInfoService.GetMetadataInfo(moduleHandle)); if (!metadataInfo.PEInfo.IsValid) { return(false); } imageLayout = (ImageLayout)metadataInfo.PEInfo.ImageLayout; try { peImageData = DumpModule(module, imageLayout, metadataInfo, null); // 尝试不使用文件中的节头 } catch { peImageData = DumpModule(module, imageLayout, metadataInfo, dacModule.FileName); // 如果出错,使用文件中的节头 } File.WriteAllBytes(filePath, peImageData); return(true); } catch { return(false); } }