C++实现第三方资源释放与载入过程(以DLL为例)
简介
我们经常看见有一些程序开始执行时会释放一些文件,以便于后续操作。例如一些病毒为了便于传播和隐藏,经常把一些需要用的动态库或是驱动文件打包进一个可执行文件中,再由需要使用的时候,再临时释放和加载。接下来笔者就将演示如何将DLL打包进文件,并实现动态释放和加载。
实现流程
- 开发工具:Visual Studio 2017
1.在项目工程上点击右键,选择“添加资源”;
2.选择"导入"项,选择“所有文件”,选择我们要导入的文件“test.dll”;
3.会弹出命名自定义资源类型的对话框,自定义我们的资源类型;
4.点击确定后,完成导入,"Ctrl+S"保存二进制资源文件;
5.我们可以在自动添加的“resource.h”头文件中看到我们的资源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;
}
本文为博主总结文章,欢迎转载,请注明出处。