使用FindResource和内存缓冲区
Using FindResource with a memory buffer
我有一个内存缓冲区,其中包含一个有效的exe文件图像,我想从中提取一些资源。
为此,我使用FindResource
函数,但该函数期望一个HMODULE,并在使用exe提供内存缓冲区时崩溃。
是否有一种方法可以使它与内存缓冲区一起工作,而不是将exe写入临时文件,使用LoadLibrary
加载它,然后做所需的工作?
我有一个内存缓冲区,其中包含一个有效的文件图像
是哪种形式?我猜比原始版本(如磁盘)要好。但是你需要'mapped as 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%正确的-你可以跳过这个检查和简化代码
//i编辑Test
函数基于@IInspectable注释-删除__try/__except -这里不需要
您的选择:
- 保存到临时文件并加载
LoadLibraryEx
。 - 解析PE文件并自己定位资源。
- 复制必要的操作,以各种内存模块库之一的方式从内存中加载模块。
相关文章:
- 在 capnp FlatArrayMessageReader 的对齐内存缓冲区中接收 zmq 消息
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 在共享缓冲区内存中创建 ::std::string 对象
- OpenGL 调试上下文警告 -"将使用视频内存作为缓冲区异议的来源
- 如何从内存缓冲区加载张量流图
- 将 mmap 内存用于开销非常低的循环缓冲区
- 不正确的 Vulkan 统一缓冲区内存对齐
- 无锁环形缓冲区boost示例中的内存排序
- 为异步发送缓冲区保留内存(提升 asio 套接字)
- 来自iostream或内存缓冲区的Apache Arrow表
- 如何重复使用原始输入缓冲区内存?
- 如何释放协议缓冲区内存
- 如何正确复制内存缓冲区?
- 将不相邻的内存缓冲区视为连续缓冲区的数据结构
- 我可以在没有任何锁的情况下从不同的线程读取内存缓冲区吗?
- C++ - 读取进程内存到缓冲区,写入进程内存(同一缓冲区上的新值)将缓冲区恢复为旧值
- Vulkan中动态统一缓冲区的缓冲区内存分配
- 正确释放协议缓冲区内存
- 清除stdin缓冲区(内存占用空间)
- 线程写入缓冲区内存和线程内存