Ejemplo n.º 1
0
        private static byte[] DumpDotNetModule(NativeModule module, ImageLayout imageLayout, out string fileName)
        {
            try {
                byte[] peImageData;
                bool   isDotNet;

                peImageData = PEImageHelper.DirectCopy(module, imageLayout);
                peImageData = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.File);
                using (PEImage peImage = new PEImage(peImageData, true)) {
                    // 确保为有效PE文件
                    fileName = peImage.GetOriginalFilename() ?? ((IntPtr)module.Handle).ToString((ulong)module.Handle > uint.MaxValue ? "X16" : "X8");
                    isDotNet = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14].VirtualAddress != 0;
                    if (isDotNet)
                    {
                        try {
                            using (ModuleDefMD moduleDef = ModuleDefMD.Load(peImage)) {
                            }
                            // 再次验证是否为.NET程序集
                        }
                        catch {
                            isDotNet = false;
                        }
                    }
                }
                return(isDotNet ? peImageData : null);
            }
            catch {
                fileName = default;
                return(null);
            }
        }
Ejemplo n.º 2
0
        private static void FileLayoutToMemoryLayout(ref byte[] peImageData, MetadataInfo metadataInfo)
        {
            peImageData = PEImageHelper.ConvertImageLayout(peImageData, ImageLayout.File, ImageLayout.Memory);
            using (PEImage peHeader = new PEImage(peImageData, ImageLayout.File, false)) {
                // 用于转换RVA与FOA,必须指定imageLayout参数为ImageLayout.File
                DotNetPEInfo peInfo;

                if (!(metadataInfo.TableStream is null))
                {
                    metadataInfo.TableStream.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.TableStream.Rva);
                }
                if (!(metadataInfo.StringHeap is null))
                {
                    metadataInfo.StringHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.StringHeap.Rva);
                }
                if (!(metadataInfo.UserStringHeap is null))
                {
                    metadataInfo.UserStringHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.UserStringHeap.Rva);
                }
                if (!(metadataInfo.GuidHeap is null))
                {
                    metadataInfo.GuidHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.GuidHeap.Rva);
                }
                if (!(metadataInfo.BlobHeap is null))
                {
                    metadataInfo.BlobHeap.Rva = (uint)peHeader.ToRVA((FileOffset)metadataInfo.BlobHeap.Rva);
                }
                peInfo                = metadataInfo.PEInfo;
                peInfo.ImageLayout    = MetadataLocator.ImageLayout.Memory;
                peInfo.Cor20HeaderRva = (uint)peHeader.ToRVA((FileOffset)peInfo.Cor20HeaderRva);
                peInfo.MetadataRva    = (uint)peHeader.ToRVA((FileOffset)peInfo.MetadataRva);
            }
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        private static ImageLayout GetProbableImageLayout(byte[] firstPageData)
        {
            try {
                uint        imageSize;
                ImageLayout imageLayout;

                imageSize = PEImageHelper.GetImageSize(firstPageData, ImageLayout.File);
                // 获取文件格式大小
                imageLayout = imageSize >= (uint)firstPageData.Length ? ImageLayout.Memory : ImageLayout.File;
                // 如果文件格式大小大于页面大小,说明在内存中是内存格式的,反之为文件格式
                // 这种判断不准确,如果文件文件大小小于最小页面大小,判断会出错
                return(imageLayout);
            }
            catch {
                return(ImageLayout.Memory);
            }
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        private void FixHeader(byte[] peImageData, AntiAntiDumpInfo antiAntiDumpInfo)
        {
            ImageLayout        imageLayout;
            uint               cor20HeaderRva;
            uint               metadataRva;
            uint               metadataSize;
            MetadataInfo       metadataInfo;
            MetadataStreamInfo tableStreamInfo;
            MetadataStreamInfo stringHeapInfo;
            MetadataStreamInfo userStringHeapInfo;
            MetadataStreamInfo guidHeapInfo;
            MetadataStreamInfo blobHeapInfo;

            imageLayout        = (ImageLayout)antiAntiDumpInfo.ImageLayout;
            cor20HeaderRva     = antiAntiDumpInfo.Cor20HeaderRva;
            metadataRva        = antiAntiDumpInfo.MetadataRva;
            metadataSize       = antiAntiDumpInfo.MetadataSize;
            metadataInfo       = antiAntiDumpInfo.MetadataInfo;
            tableStreamInfo    = metadataInfo.TableStream;
            stringHeapInfo     = metadataInfo.StringHeap;
            userStringHeapInfo = metadataInfo.UserStringHeap;
            guidHeapInfo       = metadataInfo.GuidHeap;
            blobHeapInfo       = metadataInfo.BlobHeap;
            using (PEImage peHeader = new PEImage(peImageData, ImageLayout.File, false)) {
                // 用于转换RVA与FOA,必须指定imageLayout参数为ImageLayout.File
                switch (imageLayout)
                {
                case ImageLayout.File:
                    peImageData    = PEImageHelper.ConvertImageLayout(peImageData, imageLayout, ImageLayout.Memory);
                    cor20HeaderRva = (uint)peHeader.ToRVA((FileOffset)cor20HeaderRva);
                    metadataRva    = (uint)peHeader.ToRVA((FileOffset)metadataRva);
                    break;

                case ImageLayout.Memory:
                    break;

                default:
                    throw new NotSupportedException();
                }

                fixed(byte *p = peImageData)
                {
                    IMAGE_DATA_DIRECTORY *pNETDirectory;
                    IMAGE_COR20_HEADER *  pCor20Header;
                    STORAGESIGNATURE *    pStorageSignature;

                    byte[]         versionString;
                    STORAGEHEADER *pStorageHeader;
                    uint *         pStreamHeader;

                    pNETDirectory = (IMAGE_DATA_DIRECTORY *)(p + (uint)peHeader.ImageNTHeaders.OptionalHeader.DataDirectories[14].StartOffset);
                    pNETDirectory->VirtualAddress = cor20HeaderRva;
                    pNETDirectory->Size           = IMAGE_COR20_HEADER.UnmanagedSize;
                    // Set Data Directories
                    pCor20Header     = (IMAGE_COR20_HEADER *)(p + cor20HeaderRva);
                    pCor20Header->cb = IMAGE_COR20_HEADER.UnmanagedSize;
                    pCor20Header->MajorRuntimeVersion     = 0x2;
                    pCor20Header->MinorRuntimeVersion     = 0x5;
                    pCor20Header->MetaData.VirtualAddress = metadataRva;
                    pCor20Header->MetaData.Size           = metadataSize;
                    // Set .NET Directory
                    pStorageSignature                 = (STORAGESIGNATURE *)(p + metadataRva);
                    pStorageSignature->lSignature     = 0x424A5342;
                    pStorageSignature->iMajorVer      = 0x1;
                    pStorageSignature->iMinorVer      = 0x1;
                    pStorageSignature->iExtraData     = 0x0;
                    pStorageSignature->iVersionString = 0xC;
                    versionString = Encoding.ASCII.GetBytes("v4.0.30319");
                    for (int i = 0; i < versionString.Length; i++)
                    {
                        pStorageSignature->pVersion[i] = versionString[i];
                    }
                    // versionString仅仅占位用,程序集具体运行时版本用dnlib获取
                    // Set StorageSignature
                    pStorageHeader           = (STORAGEHEADER *)((byte *)pStorageSignature + STORAGESIGNATURE.UnmanagedSize + pStorageSignature->iVersionString);
                    pStorageHeader->fFlags   = 0x0;
                    pStorageHeader->pad      = 0x0;
                    pStorageHeader->iStreams = 0x5;
                    // Set StorageHeader
                    pStreamHeader = (uint *)((byte *)pStorageHeader + STORAGEHEADER.UnmanagedSize);
                    if (tableStreamInfo != null)
                    {
                        *pStreamHeader  = imageLayout == ImageLayout.Memory ? tableStreamInfo.Rva : (uint)peHeader.ToRVA((FileOffset)tableStreamInfo.Rva);
                        *pStreamHeader -= metadataRva;
                        pStreamHeader++;
                        *pStreamHeader = tableStreamInfo.Length;
                        pStreamHeader++;
                        *pStreamHeader = 0x00007E23;
                        // #~ 暂时不支持#-表流的程序集
                        pStreamHeader++;
                    }
                    if (stringHeapInfo != null)
                    {
                        *pStreamHeader  = imageLayout == ImageLayout.Memory ? stringHeapInfo.Rva : (uint)peHeader.ToRVA((FileOffset)stringHeapInfo.Rva);
                        *pStreamHeader -= metadataRva;
                        pStreamHeader++;
                        *pStreamHeader = stringHeapInfo.Length;
                        pStreamHeader++;
                        *pStreamHeader = 0x72745323;
                        pStreamHeader++;
                        *pStreamHeader = 0x73676E69;
                        pStreamHeader++;
                        *pStreamHeader = 0x00000000;
                        pStreamHeader++;
                        // #Strings
                    }
                    if (userStringHeapInfo != null)
                    {
                        *pStreamHeader  = imageLayout == ImageLayout.Memory ? userStringHeapInfo.Rva : (uint)peHeader.ToRVA((FileOffset)userStringHeapInfo.Rva);
                        *pStreamHeader -= metadataRva;
                        pStreamHeader++;
                        *pStreamHeader = userStringHeapInfo.Length;
                        pStreamHeader++;
                        *pStreamHeader = 0x00535523;
                        pStreamHeader++;
                        // #US
                    }
                    if (guidHeapInfo != null)
                    {
                        *pStreamHeader  = imageLayout == ImageLayout.Memory ? guidHeapInfo.Rva : (uint)peHeader.ToRVA((FileOffset)guidHeapInfo.Rva);
                        *pStreamHeader -= metadataRva;
                        pStreamHeader++;
                        *pStreamHeader = guidHeapInfo.Length;
                        pStreamHeader++;
                        *pStreamHeader = 0x49554723;
                        pStreamHeader++;
                        *pStreamHeader = 0x00000044;
                        pStreamHeader++;
                        // #GUID
                    }
                    if (blobHeapInfo != null)
                    {
                        *pStreamHeader  = imageLayout == ImageLayout.Memory ? blobHeapInfo.Rva : (uint)peHeader.ToRVA((FileOffset)blobHeapInfo.Rva);
                        *pStreamHeader -= metadataRva;
                        pStreamHeader++;
                        *pStreamHeader = blobHeapInfo.Length;
                        pStreamHeader++;
                        *pStreamHeader = 0x6F6C4223;
                        pStreamHeader++;
                        *pStreamHeader = 0x00000062;
                        pStreamHeader++;
                        // #GUID
                    }
                }
            }
            using (ModuleDefMD moduleDef = ModuleDefMD.Load(new PEImage(peImageData, imageLayout, false)))
                fixed(byte *p = peImageData)
                {
                    STORAGESIGNATURE *pStorageSignature;

                    byte[] versionString;

                    pStorageSignature = (STORAGESIGNATURE *)(p + metadataRva);
                    switch (moduleDef.CorLibTypes.AssemblyRef.Version.Major)
                    {
                    case 2:
                        versionString = Encoding.ASCII.GetBytes("v2.0.50727");
                        break;

                    case 4:
                        versionString = Encoding.ASCII.GetBytes("v4.0.30319");
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    for (int i = 0; i < versionString.Length; i++)
                    {
                        pStorageSignature->pVersion[i] = versionString[i];
                    }
                }
        }