资源释放

本文最后更新于:2021-08-09 晚上

资源释放

恶意代码会广泛的使用此技术,因为它可以使程序变得简洁,提高隐蔽性。如果一个程序需要额外的加载一些DLL、文本文件或者其他类型文件,将它们可以作为资源插入到程序中,在程序运行的时候再将它们释放到本地上,这样恶意代码会更加隐蔽。

函数介绍

FindResource函数,确定具有指定类型和名称的资源在指定模块中的位置
1
2
3
4
5
HRSRC FindResourceW(
HMODULE hModule,
LPCWSTR lpName,
LPCWSTR lpType
);

hModule:处理包含资源的可执行文件模块。若hModule为NULL,则系统从当前进程的模块中装载资源。

lpName:指定资源名称

lpType:指定资源类型

返回值:如果函数运行成功,那么返回值为指定资源信息块的句柄。可将这个句柄传递给其它函数获取其他信息。如果失败,则返回NULL;

SizeofResource函数:获取指定资源的字节数
1
2
3
4
DWORD SizeofResource(
HMODULE hModule,
HRSRC hResInfo
);

hModule:包含资源的可执行文件模块的句柄。若hModule为NULL,则系统从当前进程的模块中装载资源。

hResInfo:资源局部。此句柄必须由函数FindResource或FindResourceEx来出创建。

返回值:如果函数运行成功,则返回值为资源的字节数;如果函数运行失败,则返回值为0;

LoadResource函数:装载指定资源到全局存储器
1
2
3
4
HGLOBAL LoadResource(
HMODULE hModule,
HRSRC hResInfo
);

hModule:包含资源的可执行文件模块的句柄。若hModule为NULL,则系统从当前进程的模块中装载资源。

hResInfo:资源局部。此句柄必须由函数FindResource或FindResourceEx来出创建。

返回值:如果函数运行成功,则返回值为相关资源数据的句柄。如果函数运行失败,则返回值为NULL。

LockResource函数:锁定资源并得到资源在内存中的第一个字节的指针
1
2
3
LPVOID LockResource(
HGLOBAL hResData
);

hResData:装载资源的句柄。函数LoadResource可以返回这个句柄。

返回值:如果装载资源被锁住,则返回值是资源的第一个字节的指针;反之则为NULL。

实现过程

创建一个test.txt文件,写入内容

在程序中添加一个自定义资源,自定义资源名称为“MYRES”,再将刚才创建的txt文件添加进去

程序实现源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// FreeRes.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <Windows.h>
#include "resource.h"
//资源控件名称,资源名称,释放后的名称
BOOL FreeRes(UINT uiResourceName,TCHAR* lpszResType,char* lpszSaveFileName) {
//获取指定模块的资源
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(uiResourceName), lpszResType);
if (hRes == NULL) {
MessageBox(NULL, L"获取资源失败", L"", NULL);
return FALSE;
}
//获取大小
DWORD dwSize = SizeofResource(NULL, hRes);
if (dwSize == 0) {
MessageBox(NULL, L"获取字节数失败", L"", NULL);
return FALSE;
}
//装载资源
HGLOBAL hGlobal = LoadResource(NULL, hRes);
if (hGlobal == NULL) {
MessageBox(NULL, L"装载资源失败", L"", NULL);
return FALSE;
}
//锁定资源
LPVOID lPvoid = LockResource(hGlobal);
if(lPvoid == NULL){
MessageBox(NULL, L"锁定资源失败", L"", NULL);
return FALSE;
}
//开始释放资源
FILE* fp;
fopen_s(&fp, lpszSaveFileName, "wb+");//wb+读写打开或建立一个二进制文件,允许读和写
if (fp == NULL) {
MessageBox(NULL, L"写入资源失败", L"", NULL);
return FALSE;
}
fwrite(lPvoid, sizeof(char), dwSize, fp);
fclose(fp);
return TRUE;
}
int main()
{
printf("按下回车键开始释放资源\n");
getchar();
BOOL FLAG=FreeRes(IDR_MYRES2,TEXT("MYRES"),"free.txt");
if (FLAG == TRUE) {
printf("释放成功\n");
}
else
printf("释放失败\n");
getchar();
}

查看free.txt内容

参考

参考《Windows黑客编程技术详解》一书