public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { ClrModule dacModule; InjectionClrVersion clrVersion; InjectionOptions injectionOptions; MetadataInfoService metadataInfoService; MetadataInfo metadataInfo; byte[] peImageData; dacModule = TryGetDacModule(moduleHandle); 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() }; using (NativeProcess process = NativeProcess.Open(_processId)) 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(moduleHandle, imageLayout, metadataInfo, null); // 尝试不使用文件中的节头 } catch { peImageData = DumpModule(moduleHandle, imageLayout, metadataInfo, dacModule.FileName); // 如果出错,使用文件中的节头 } File.WriteAllBytes(filePath, peImageData); return(true); }
private static byte[] DumpModule(NativeModule module, ImageLayout imageLayout, MetadataInfo metadataInfo, string imagePath) { byte[] peImageData; peImageData = PEImageHelper.DirectCopy(module, imageLayout, !(imagePath is null), imagePath); if (imageLayout == ImageLayout.File) { // 统一为内存格式,方便修复 FileLayoutToMemoryLayout(ref peImageData, metadataInfo); } FixDotNetHeaders(peImageData, metadataInfo); // 修复.NET头 peImageData = PEImageHelper.ConvertImageLayout(peImageData, ImageLayout.Memory, ImageLayout.File); // 转换回文件格式用于保存 return(peImageData); }
public bool DumpModule(IntPtr moduleHandle, ImageLayout imageLayout, string filePath) { ClrModule dacModule; InjectionClrVersion clrVersion; Injection.Options options; AntiAntiDumpService antiAntiDumpService; AntiAntiDumpInfo antiAntiDumpInfo; MetadataInfo metadataInfo; byte[] peImageData; dacModule = TryGetDacModule(moduleHandle); if (dacModule == 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版本 options = new Injection.Options { PortName = Guid.NewGuid().ToString(), ObjectName = Guid.NewGuid().ToString() }; using (NativeProcess process = NativeProcess.Open(_processId)) if (!process.InjectManaged(typeof(AntiAntiDumpService).Assembly.Location, typeof(Injection).FullName, "Main", options.Serialize(), clrVersion, out int result) || result != 0) { return(false); } antiAntiDumpService = (AntiAntiDumpService)Activator.GetObject(typeof(AntiAntiDumpService), $"Ipc://{options.PortName}/{options.ObjectName}"); // 注入DLL,通过.NET Remoting获取AntiAntiDumpService实例 antiAntiDumpInfo = antiAntiDumpService.GetAntiAntiDumpInfo(moduleHandle); if (!antiAntiDumpInfo.CanAntiAntiDump) { return(false); } imageLayout = (ImageLayout)antiAntiDumpInfo.ImageLayout; // 覆盖通过DAC获取的,不确定DAC获取的是否准确,毕竟DAC的bug还不少 metadataInfo = antiAntiDumpInfo.MetadataInfo; PrintStreamInfo("#~ or #-", metadataInfo.TableStream); PrintStreamInfo("#Strings", metadataInfo.StringHeap); PrintStreamInfo("#US", metadataInfo.UserStringHeap); PrintStreamInfo("#GUID", metadataInfo.GuidHeap); PrintStreamInfo("#Blob", metadataInfo.BlobHeap); peImageData = PEImageHelper.DirectCopy(_processId, (void *)moduleHandle, imageLayout); FixHeader(peImageData, antiAntiDumpInfo); peImageData = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.File); File.WriteAllBytes(filePath, peImageData); return(true); }