C++實現第三方資源釋放與載入過程(以DLL爲例)

簡介

咱們常常看見有一些程序開始執行時會釋放一些文件,以便於後續操做。例如一些病毒爲了便於傳播和隱藏,常常把一些須要用的動態庫或是驅動文件打包進一個可執行文件中,再由須要使用的時候,再臨時釋放和加載。接下來筆者就將演示如何將DLL打包進文件,並實現動態釋放和加載。ios

實現流程

  • 開發工具:Visual Studio 2017

1.在項目工程上點擊右鍵,選擇「添加資源」;編程

添加資源

2.選擇"導入"項,選擇「全部文件」,選擇咱們要導入的文件「test.dll」;工具

導入文件

3.會彈出命名自定義資源類型的對話框,自定義咱們的資源類型;開發工具

從新添加資源

4.點擊肯定後,完成導入,"Ctrl+S"保存二進制資源文件;spa

完成導入

5.咱們能夠在自動添加的「resource.h」頭文件中看到咱們的資源ID宏;指針

資源ID宏

6.編程實現載入資源。code

編程實現載入資源

代碼樣例

  • 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;
}
相關文章
相關標籤/搜索