目录
前言
木马文件会广泛使用资源释放技术,使程序变得更简洁;如果程序需要额外加载DLL文件、图片等,可以把它们作为资源插入程序中,程序运行后,文件释放到本地;这样的好处是编译出来的程序已有一个exe。
函数介绍
FindResource函数
确定指定类型和名称的资源在指定模块中的位置。
语法
HRSRC FindResource(
[in, optional] HMODULE hModule,
[in] LPCSTR lpName,
[in] LPCSTR lpType
);
参数
[in, optional] hModule
可移植可执行文件资源资源的模块句柄。若为NULL则从当前进程模块中装载资源。
[in] lpName
资源名称。
[in] lpType
资源类型。
返回值
如果函数成功,则返回值是指定资源信息块的句柄。
如果函数失败,则返回值为NULL。
SizeofResource函数
检索指定资源的大小。
语法
DWORD SizeofResource(
[in, optional] HMODULE hModule,
[in] HRSRC hResInfo
);
参数
[in, optional] hModule
可执行文件包含资源的模块的句柄。
[in] hResInfo
资源的句柄。
返回值
如果函数成功,则返回值是资源中的字节数。
如果函数失败,则返回值为零。
LoadResource函数
装载指定资源到全局存储器。
语法
HGLOBAL LoadResource(
[in, optional] HMODULE hModule,
[in] HRSRC hResInfo
);
参数
[in, optional] hModule
可执行文件包含资源的模块的句柄。如果hModule为NULL,则系统从用于创建当前进程的模块加载资源。
[in] hResInfo
要加载的资源的句柄。由FindResource函数返回。
返回值
如果函数成功,则返回值是与资源关联的数据的句柄。
如果函数失败,则返回值为NULL。
LockResource函数
锁定资源并得到资源在内存中的第一个字节的指针。
语法
LPVOID LockResource(
[in] HGLOBAL hResData
);
参数
[in] hResData
要访问的资源的句柄。
返回值
加载的资源可用,返回值是指向资源第一个字节的指针。
否则为NULL。
示例
本地创建文件test.txt:
右键项目–>添加–>资源–>自定义资源–>刚才添加的资源–>导入–>选择文件
代码
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
// 提取资源
BOOL FreeMyResourse(UINT uiResouceName, char* lpszResourceType, char* lpszSaveFileName)
{
//获取指定模块的资源
HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(uiResouceName), lpszResourceType);
if (hRsrc == NULL)
{
printf("can't find the resource!\n");
return FALSE;
}
//获取资源的大小
DWORD dwSize = SizeofResource(NULL, hRsrc);
if (dwSize <= 0)
{
printf("the resource's size is error!\n");
return FALSE;
}
//将资源加载到内存里
HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
if (hGlobal == NULL)
{
printf("load resource error!\n");
return FALSE;
}
//锁定资源
LPVOID lpVoid = LockResource(hGlobal);
if (lpVoid == NULL)
{
printf("lock resource error!\n");
return FALSE;
}
//保存资源为文件
FILE* fp = NULL;
fopen_s(&fp, lpszSaveFileName, "wb+");
if (fp == NULL)
{
printf("open file error!\n");
return FALSE;
}
fwrite(lpVoid, sizeof(char), dwSize, fp);
fclose(fp);
return TRUE;
}
int main()
{
char lpszResourceType[20] = "TEST";
char szSaveFileName[20] = "test.txt";
BOOL flag = FreeMyResourse(IDR_MYRES2, lpszResourceType, szSaveFileName);
if (flag == TRUE)
{
printf("释放成功\n");
}
return 0;
}
测试
双击“资源释放.exe”,目录下增加文件“test.txt”
原理学习
通过FindResource函数,通过资源名称和类型,定位程序中的资源,获得资源句柄。
根据资源句柄,利用SizeofResource获取资源大小。
通过LoadReource吧资源加载到程序内存。
通过LockResource锁定加载到内存中的资源,返回程序在内存中的起始地址。
根据资源大小以及内存中的起始地址,将资源读取并保存为本地文件。