C++实现第三方资源释放与载入过程(以DLL为例)

简介

我们经常看见有一些程序开始执行时会释放一些文件,以便于后续操作。例如一些病毒为了便于传播和隐藏,经常把一些需要用的动态库或是驱动文件打包进一个可执行文件中,再由需要使用的时候,再临时释放和加载。接下来笔者就将演示如何将DLL打包进文件,并实现动态释放和加载。

实现流程

  • 开发工具:Visual Studio 2017

1.在项目工程上点击右键,选择“添加资源”;

添加资源

2.选择"导入"项,选择“所有文件”,选择我们要导入的文件“test.dll”;

导入文件

3.会弹出命名自定义资源类型的对话框,自定义我们的资源类型;

重新添加资源

4.点击确定后,完成导入,"Ctrl+S"保存二进制资源文件;

完成导入

5.我们可以在自动添加的“resource.h”头文件中看到我们的资源ID宏;

资源ID宏

6.编程实现载入资源。

编程实现载入资源

代码样例

  • DLL样例文件代码
////////////////////////////////
//
// FileName : HelloWorldDll.cpp
// Creator : PeterZheng
// Date : 2018/11/02 11:10
// Comment : HelloWorld Test DLL ^_^
//
////////////////////////////////

#include <iostream>
#include <Windows.h>

using namespace std;

BOOL WINAPI DllMain(
	_In_ HINSTANCE hinstDLL,
	_In_ DWORD     fdwReason,
	_In_ LPVOID    lpvReserved
)
{
	switch (fdwReason)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_PROCESS_DETACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
		break;
	}
	return TRUE;
}

extern"C" __declspec(dllexport) VOID Func()
{
	MessageBox(NULL, "HelloWorld", "Tips", MB_OK);
	return;
}
  • EXE资源载入文件代码:
////////////////////////////////
//
// FileName : LoadResource.cpp
// Creator : PeterZheng
// Date : 2018/11/02 11:10
// Comment : Load Resource Demo
//
////////////////////////////////

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <Windows.h>
#include "resource.h"

using namespace std;

typedef VOID(*Func)(VOID);

BOOL ReleaseLibrary(UINT uResourceId, CHAR* szResourceType, CHAR* szFileName)
{
	// 找到资源
	HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(uResourceId), szResourceType);
	if (hRsrc == NULL)
	{
		MessageBox(NULL, "Find Resource Error!", "Tips", MB_OK);
		return FALSE;
	}
	// 获取资源大小
	DWORD dwSize = SizeofResource(NULL, hRsrc);
	if (dwSize <= 0)
	{
		MessageBox(NULL, "Get Resource Error!", "Tips", MB_OK);
		return FALSE;
	}

	// 载入资源
	HGLOBAL hGlobal = LoadResource(NULL, hRsrc);
	if (hGlobal == NULL)
	{
		MessageBox(NULL, "Load Resource Error!", "Tips", MB_OK);
		return FALSE;
	}

	// 锁定资源,并返回指向资源第一字节的指针
	LPVOID lpRes = LockResource(hGlobal);
	if (lpRes == NULL)
	{
		MessageBox(NULL, "Lock Resource Error!", "Tips", MB_OK);
		return FALSE;
	}
	HANDLE hFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == NULL)
	{
		MessageBox(NULL, "Create File Error!", "Tips", MB_OK);
		return FALSE;
	}
	DWORD dwWriten = 0;
	BOOL bRes = WriteFile(hFile, lpRes, dwSize, &dwWriten, NULL);
	if (bRes == FALSE || dwWriten <= 0)
	{
		MessageBox(NULL, "Write To File Error!", "Tips", MB_OK);
		return FALSE;
	}
	CloseHandle(hFile);
	CloseHandle(hGlobal);
	CloseHandle(hRsrc);
	return TRUE;
}

int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
	BOOL bRes = ReleaseLibrary(IDR_TESTRES1, (CHAR*)"TESTRES", (CHAR*)"test.dll");
	if (bRes == FALSE)
	{
		MessageBox(NULL, "Release DLL Error!", "Tips", MB_OK);
		return 0;
	}
	HMODULE hModule = LoadLibrary("test.dll");
	if (hModule == NULL)
	{
		MessageBox(NULL, "Load Library Error!", "Tips", MB_OK);
		return 0;
	}
	Func fc = (Func)GetProcAddress(hModule, "Func");
	if (fc == NULL)
	{
		MessageBox(NULL, "GetProcAddress Error!", "Tips", MB_OK);
		return 0;
	}
	fc();
	FreeLibrary(hModule);
	return 0;
}
posted @ 2019-03-19 00:06  倚剑问天  阅读(1983)  评论(0编辑  收藏  举报