public int DumpProcess(string directoryPath) { int count; count = 0; foreach (PageInfo pageInfo in _process.EnumeratePageInfos()) { ushort magic; byte[] peHeaderData; NativeModule module; ImageLayout imageLayout; byte[] peImageData; string fileName; string filePath; if ((ulong)pageInfo.Size > int.MaxValue) { continue; } if (!_process.TryReadUInt16(pageInfo.Address, out magic)) { continue; } if (magic != 0x5A4D) { // MZ continue; } peHeaderData = new byte[(uint)pageInfo.Size]; if (!_process.TryReadBytes(pageInfo.Address, peHeaderData)) { continue; } module = _process.UnsafeGetModule(pageInfo.Address); imageLayout = GetProbableImageLayout(peHeaderData); peImageData = DumpDotNetModule(module, imageLayout, out fileName); if (peImageData is null) { // 也许判断有误,尝试一下另一种格式 if (imageLayout == ImageLayout.Memory) { peImageData = DumpDotNetModule(module, ImageLayout.File, out fileName); } else { peImageData = DumpDotNetModule(module, ImageLayout.Memory, out fileName); } } if (peImageData is null) { continue; } filePath = Path.Combine(directoryPath, EnsureNoRepeatFileName(directoryPath, EnsureValidFileName(fileName))); File.WriteAllBytes(filePath, peImageData); count++; } return(count); }
static bool IsValidPEMagic(ClrModule module, NativeProcess process) { byte[] buffer = new byte[2]; if (!process.TryReadBytes((void *)module.ImageBase, buffer)) { return(false); } return(buffer[0] == 'M' && buffer[1] == 'Z'); }
public int DumpProcess(string directoryPath) { int count = 0; foreach (var pageInfo in _process.EnumeratePageInfos()) { if ((pageInfo.Protection & MemoryProtection.NoAccess) == MemoryProtection.NoAccess) { continue; } byte[] page = new byte[(int)pageInfo.Size]; if (!_process.TryReadBytes(pageInfo.Address, page)) { continue; } for (int i = 0; i < page.Length; i++) { fixed(byte *p = page) { if (!MaybePEImage(p + i)) { continue; } } var imageLayout = i == 0 ? GetProbableImageLayout(page) : ImageLayout.File; byte[] peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, imageLayout, out string fileName); if (peImage is null && i == 0) { // 也许判断有误,尝试一下另一种格式 if (imageLayout == ImageLayout.Memory) { peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, ImageLayout.File, out fileName); } else { peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, ImageLayout.Memory, out fileName); } } if (peImage is null) { continue; } string filePath = Path.Combine(directoryPath, EnsureNoRepeatFileName(directoryPath, EnsureValidFileName(fileName))); File.WriteAllBytes(filePath, peImage); count++; } } return(count); }
/// <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); }
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); } }
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); } }
static uint GetModuleSize(ClrModule module, NativeProcess process) { uint size = (uint)module.Size; if (size != 0) { return(size); } byte[] peHeader = new byte[0x1000]; if (!process.TryReadBytes((void *)module.ImageBase, peHeader)) { return(0); } try { return(PEImageDumper.GetImageSize(peHeader, dnlib.PE.ImageLayout.Memory)); } catch (Exception ex) { Logger.Error($"Can't get image size of module '{module.Name}' at {Formatter.FormatHex((nuint)module.ImageBase)}"); Logger.Exception(ex); return(0); } }
/// <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); }
public int DumpProcess(string directoryPath) { int count = 0; var originalFileCache = new Dictionary <string, byte[]>(StringComparer.OrdinalIgnoreCase); foreach (var pageInfo in _process.EnumeratePageInfos()) { if (!IsValidPage(pageInfo)) { continue; } byte[] page = new byte[Math.Min((int)pageInfo.Size, 0x2000)]; if (!_process.TryReadBytes(pageInfo.Address, page)) { continue; } for (int i = 0; i < page.Length - 0x200; i++) { fixed(byte *p = page) { if (!MaybePEImage(p + i, page.Length - i)) { continue; } } var imageLayout = i == 0 ? GetProbableImageLayout(page) : ImageLayout.File; byte[] peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, imageLayout, out string fileName); if (peImage is null && i == 0) { // 也许判断有误,尝试一下另一种格式 if (imageLayout == ImageLayout.Memory) { peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, ImageLayout.File, out fileName); } else { peImage = DumpDotNetModule(_process, (byte *)pageInfo.Address + i, ImageLayout.Memory, out fileName); } } if (peImage is null) { continue; } if (BuiltInAssemblyHelper.IsBuiltInAssembly(peImage)) { continue; } fileName = EnsureValidFileName(fileName); if (!IsSameFile(directoryPath, fileName, peImage, originalFileCache)) { string filePath = Path.Combine(directoryPath, EnsureNoRepeatFileName(directoryPath, fileName)); File.WriteAllBytes(filePath, peImage); } count++; } } return(count); }
/// <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); } }