Example #1
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);
        }
Example #2
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);
            }
        }
        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);
            }
        }
Example #4
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);
    }
Example #5
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);
            }
        }