Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
            public static byte[] Copy(uint processId, IntPtr processHandle, IntPtr moduleHandle, bool is64)
            {
                ulong imageSize;

                byte[] buffer;

                imageSize = GetImageSize(processHandle, moduleHandle, is64);
                buffer    = new byte[imageSize];
                using (NativeProcess process = NativeProcess.Open(processId))
                    foreach (PageInfo pageInfo in process.EnumeratePageInfos(moduleHandle, (IntPtr)((ulong)moduleHandle + imageSize)))
                    {
                        int startOffset;
                        int endOffset;

                        startOffset = (int)((long)pageInfo.Address - (long)moduleHandle);
                        //以p为起点,远程进程中页面起点映射到buffer中的偏移
                        endOffset = startOffset + (int)pageInfo.Size;
                        //以p为起点,远程进程中页面终点映射到buffer中的偏移
                        fixed(byte *p = buffer)
                        {
                            if (startOffset < 0)
                            {
                                //页面前半部分超出buffer
                                ReadProcessMemory(processHandle, moduleHandle, p, (IntPtr)((ulong)pageInfo.Size - ((ulong)moduleHandle - (ulong)pageInfo.Address)), null);
                            }
                            else
                            {
                                if (endOffset <= buffer.Length)
                                {
                                    //整个页面都可以存入buffer
                                    ReadProcessMemory(processHandle, pageInfo.Address, p + startOffset, pageInfo.Size, null);
                                }
                                else
                                {
                                    //页面后半部分/全部超出buffer
                                    ReadProcessMemory(processHandle, pageInfo.Address, p + startOffset, pageInfo.Size - (endOffset - buffer.Length), null);
                                    break;
                                }
                            }
                        }
                    }
                return(buffer);
            }
Пример #7
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);
    }
Пример #8
0
        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);
        }
Пример #9
0
        /// <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);
            }
        }