gpt4 book ai didi

c++ - 将 FindResource 与内存缓冲区一起使用

转载 作者:搜寻专家 更新时间:2023-10-31 01:34:31 25 4
gpt4 key购买 nike

我有一个包含有效 exe 文件图像的内存缓冲区,我想从中提取一些资源。
为此,我正在使用 FindResource 函数,但该函数需要一个 HMODULE,并在为 exe 提供内存缓冲区时崩溃。

有没有办法让它与内存缓冲区一起工作,而不是将 exe 写入临时文件,使用 LoadLibrary 加载它,然后执行所需的工作?

最佳答案

I'm have a memory buffer which contains a valid file image

以哪种形式?我猜比原始的(如在磁盘上)。但您需要“映射为图像”内存才能使用 FindResource。不是自己硬映射你的原始图像(如果你只想访问资源,而不是从内存中执行它)代码示例:

PVOID MapImage(PIMAGE_DOS_HEADER pvRawData, ULONG cbRawData)
{
if (cbRawData < sizeof(IMAGE_DOS_HEADER))
{
return 0;
}

if (pvRawData->e_magic != IMAGE_DOS_SIGNATURE)
{
return 0;
}

ULONG e_lfanew = pvRawData->e_lfanew, s = e_lfanew + sizeof(IMAGE_NT_HEADERS);

if (e_lfanew >= s || s > cbRawData)
{
return 0;
}

PIMAGE_NT_HEADERS pinth = (PIMAGE_NT_HEADERS)RtlOffsetToPointer(pvRawData, e_lfanew);

if (pinth->Signature != IMAGE_NT_SIGNATURE)
{
return 0;
}

ULONG SizeOfImage = pinth->OptionalHeader.SizeOfImage, SizeOfHeaders = pinth->OptionalHeader.SizeOfHeaders;

s = e_lfanew + SizeOfHeaders;

if (SizeOfHeaders > SizeOfImage || SizeOfHeaders >= s || s > cbRawData)
{
return 0;
}

s = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + pinth->FileHeader.SizeOfOptionalHeader;

if (s > SizeOfHeaders)
{
return 0;
}

ULONG NumberOfSections = pinth->FileHeader.NumberOfSections;

PIMAGE_SECTION_HEADER pish = (PIMAGE_SECTION_HEADER)RtlOffsetToPointer(pinth, s);

ULONG Size;

if (NumberOfSections)
{
if (e_lfanew + s + NumberOfSections * sizeof(IMAGE_SECTION_HEADER) > SizeOfHeaders)
{
return 0;
}

do
{
if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData))
{
union {
ULONG VirtualAddress, PointerToRawData;
};

VirtualAddress = pish->VirtualAddress, s = VirtualAddress + Size;

if (VirtualAddress > s || s > SizeOfImage)
{
return 0;
}

PointerToRawData = pish->PointerToRawData, s = PointerToRawData + Size;

if (PointerToRawData > s || s > cbRawData)
{
return 0;
}
}

} while (pish++, --NumberOfSections);
}

PVOID ImageBase = VirtualAlloc(0, SizeOfImage, MEM_COMMIT, PAGE_READWRITE);

if (!ImageBase)
{
return 0;
}

memcpy(ImageBase, pvRawData, SizeOfHeaders);

if (NumberOfSections = pinth->FileHeader.NumberOfSections)
{
do
{
--pish;

if (Size = min(pish->Misc.VirtualSize, pish->SizeOfRawData))
{
memcpy(RtlOffsetToPointer(ImageBase, pish->VirtualAddress),
RtlOffsetToPointer(pvRawData, pish->PointerToRawData), Size);
}

} while (--NumberOfSections);

}

return ImageBase;
}

void Test(PVOID pvRawData, ULONG cbRawData, PCWSTR lpType, PCWSTR lpName)
{
if (HMODULE ImageBase = (HMODULE)MapImage((PIMAGE_DOS_HEADER)pvRawData, cbRawData))
{
if (HRSRC hResInfo = FindResource(ImageBase, lpName, lpType))
{
if (HGLOBAL hg = LoadResource(ImageBase, hResInfo))
{
__nop();
}
}

VirtualFree(ImageBase, 0, MEM_RELEASE);
}
}

包含检查有效数据大小的 MapImage。但是,如果您确定 (pvRawData, cbRawData) 100% 正确 - 您可以跳过此检查并简化代码

//我根据@IInspectable 注释编辑测试 函数 - 删除 __try/__except - 这里不需要

关于c++ - 将 FindResource 与内存缓冲区一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39398798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com