/// <summary> /// 直接从内存中复制模块,不执行格式转换操作 /// </summary> /// <param name="process"></param> /// <param name="address"></param> /// <param name="imageLayout"></param> /// <returns></returns> public static byte[] Dump(NativeProcess process, void *address, ref ImageLayout imageLayout) { var firstPageInfo = process.EnumeratePageInfos(address, address).First(); bool atPageHeader = address == firstPageInfo.Address; if (!atPageHeader) { imageLayout = ImageLayout.File; } byte[] peHeader = new byte[atPageHeader ? (int)firstPageInfo.Size : (int)((byte *)firstPageInfo.Address + (uint)firstPageInfo.Size - (byte *)address)]; process.ReadBytes(address, peHeader); uint imageSize = GetImageSize(peHeader, imageLayout); // 获取模块在内存中的大小 byte[] peImage = new byte[imageSize]; switch (imageLayout) { case ImageLayout.File: if (!process.TryReadBytes(address, peImage, 0, imageSize)) { throw new InvalidOperationException(); } break; case ImageLayout.Memory: foreach (var pageInfo in process.EnumeratePageInfos(address, (byte *)address + imageSize)) { uint offset = (uint)((ulong)pageInfo.Address - (ulong)address); process.TryReadBytes(pageInfo.Address, peImage, offset, (uint)pageInfo.Size); } break; default: throw new NotSupportedException(); } // 转储 return(peImage); }
private byte[] DumpMemoryModule(IntPtr moduleHandle) { using (NativeProcess process = NativeProcess.Open(_processId)) { PageInfo firstPageInfo; byte[] buffer; uint imageSize; firstPageInfo = process.EnumeratePageInfos(moduleHandle, moduleHandle).First(); buffer = new byte[(uint)firstPageInfo.Size]; process.ReadBytes(moduleHandle, buffer); imageSize = GetImageSize(buffer); buffer = new byte[imageSize]; foreach (PageInfo pageInfo in process.EnumeratePageInfos(moduleHandle, (IntPtr)((ulong)moduleHandle + imageSize))) { uint offset; offset = (uint)((ulong)pageInfo.Address - (ulong)moduleHandle); process.TryReadBytes(pageInfo.Address, buffer, offset, (uint)pageInfo.Size); } return(buffer); } }
public static byte[] DirectCopy(uint processId, void *moduleHandle, ImageLayout imageLayout) { using (NativeProcess process = NativeProcess.Open(processId)) { PageInfo firstPageInfo; byte[] peImageData; uint imageSize; firstPageInfo = process.EnumeratePageInfos(moduleHandle, moduleHandle).First(); peImageData = new byte[(uint)firstPageInfo.Size]; process.ReadBytes(moduleHandle, peImageData); imageSize = GetImageSize(peImageData, 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(); } return(peImageData); } }
/// <summary> /// 直接从内存中复制模块,不执行格式转换操作 /// </summary> /// <param name="process"></param> /// <param name="address"></param> /// <param name="imageLayout"></param> /// <returns></returns> public static byte[]? Dump(NativeProcess process, nuint address, ref ImageLayout imageLayout) { var pageInfos = process.EnumeratePageInfos((void *)address, (void *)address).ToArray(); if (pageInfos.Length == 0) { return(null); } var firstPageInfo = pageInfos[0]; if (!IsValidPage(firstPageInfo)) { return(null); } // 判断内存页是否有效 bool atPageHeader = address == (nuint)firstPageInfo.Address; if (!atPageHeader) { imageLayout = ImageLayout.File; } // 如果不在内存页头部,只可能是文件布局 var peHeader = new byte[(int)((byte *)firstPageInfo.Address + (int)firstPageInfo.Size - (byte *)address)]; process.ReadBytes((void *)address, peHeader); uint imageSize = GetImageSize(peHeader, imageLayout); // 获取模块在内存中的大小 var peImage = new byte[imageSize]; switch (imageLayout) { case ImageLayout.File: if (!process.TryReadBytes((void *)address, peImage, 0, imageSize)) { return(null); } break; case ImageLayout.Memory: pageInfos = process.EnumeratePageInfos((void *)address, (byte *)address + imageSize).Where(t => IsValidPage(t)).ToArray(); if (pageInfos.Length == 0) { return(null); } foreach (var pageInfo in pageInfos) { uint offset = (uint)((ulong)pageInfo.Address - address); if (!process.TryReadBytes(pageInfo.Address, peImage, offset, (uint)pageInfo.Size)) { return(null); } } break; default: throw new NotSupportedException(); } // 转储 return(peImage); }
/// <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); } }