1. 程式人生 > >用AheadLib進行簡單的DLL注入

用AheadLib進行簡單的DLL注入

參考連結:http://www.voidcn.com/article/p-hwvwbvwu-xz.html

1、首先編寫要注入的DLL檔案:dllTest_dll.dll
只進行兩個數的簡單相加

#include "dllTest_dll.h"

int add(int x,int y)
{
	return x+y;
}

DLL的標頭檔案dllTest_dll.h

#ifndef LIB_H
#define LIB_H

// 這種宣告方式是強制用c語言方式進行修飾,且用C的預設約定__cdecl方式。
// 這種方式編譯產生的DLL中有一個匯出函式:add,不加任何修飾。
extern
"C" int __declspec(dllexport)add(int x,int y); #endif

2、DLL檔案的呼叫檔案dllTest.cpp

// dllTest.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "stdio.h"
#include "windows.h"

typedef int (*lpAddFun)(int,int); // 函式宣告 lpAddFun是一個指向函式的指標,該函式有兩個引數都是int型別,函式的返回值也是int型別
// int *function(int,int)表示函式的兩個引數都是int型別,函式的返回值是指向Int型別的指標;
int _tmain(int argc, _TCHAR* argv[]) { HINSTANCE hDll; // DLL控制代碼 lpAddFun addFun; // 函式指標 //TCHAR tzPath[MAX_PATH]; hDll = LoadLibraryW(L"dllTest_dll.dll");// 如果不加L會報錯 “LoadLibraryW”: 不能將引數 1 從“const char [16]”轉換為“LPCWSTR” //與指向的型別無關;轉換要求 reinterpret_cast、C 樣式轉換或函式樣式轉換
if(hDll != NULL) { addFun = (lpAddFun)GetProcAddress(hDll,"add"); if(addFun != NULL) { int result = addFun(2,3); printf("%d\n",result); //GetSystemDirectory(tzPath,MAX_PATH); //得到系統目錄……沒用啊……這是誰寫的程式 } FreeLibrary(hDll); } system("pause"); return 0; }

測試一下:
在這裡插入圖片描述

3、用AheadLib反編譯DLL,命名為dllTest_dll2.dll

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 標頭檔案
#include <Windows.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 匯出函式
#pragma comment(linker, "/EXPORT:add=_AheadLib_add,@1")
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 巨集定義
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)

#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Hook 名稱空間
namespace Hook
{
	HHOOK m_hHook;// HOOK 控制代碼
			


	// HOOK 函式
	// LRESULT是一種資料型別,從視窗程式或回撥函式返回的32位值
	LRESULT CALLBACK HookProc(INT iCode, WPARAM wParam, LPARAM lParam)
	{
		if (iCode > 0)
		{
			;
		}

		return CallNextHookEx(m_hHook, iCode, wParam, lParam);
	}

	// Hook
	inline BOOL WINAPI Hook(INT iHookId = WH_CALLWNDPROC)
	{
		m_hHook = SetWindowsHookEx(iHookId, HookProc, NULL, GetCurrentThreadId());
		return (m_hHook != NULL);
	}

	// Unhook
	inline VOID WINAPI Unhook()
	{
		if (m_hHook)
		{
			UnhookWindowsHookEx(m_hHook);
		}
	}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AheadLib 名稱空間
namespace AheadLib
{
	HMODULE m_hModule = NULL;	// 原始模組控制代碼
	DWORD m_dwReturn[1] = {0};	// 原始函式返回地址


	// 載入原始模組
	inline BOOL WINAPI Load()
	{
		TCHAR tzPath[MAX_PATH];
		TCHAR tzTemp[MAX_PATH * 2];

		lstrcpy(tzPath, TEXT("dllTest_dllOrg"));

		// 新增這一句是為了證明我的dll能被執行;
		// 訊息框的標題是DLL Path,內容是dllTest_dllOrg也就是原來的dll
		MessageBox(NULL,tzPath,TEXT("DLL Path"),MB_ICONSTOP);//MB_ICONSTOP訊息框會出現一個停止圖示

		m_hModule = LoadLibrary(tzPath); // 載入原來的dll
		if (m_hModule == NULL)
		{
			wsprintf(tzTemp, TEXT("無法載入 %s,程式無法正常執行。"), tzPath);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
		}

		return (m_hModule != NULL);	
	}
		
	// 釋放原始模組
	inline VOID WINAPI Free()
	{
		if (m_hModule)
		{
			FreeLibrary(m_hModule);
		}
	}

	// 獲取原始函式地址
	FARPROC WINAPI GetAddress(PCSTR pszProcName)
	{
		FARPROC fpAddress;
		CHAR szProcName[16];
		TCHAR tzTemp[MAX_PATH];

		fpAddress = GetProcAddress(m_hModule, pszProcName);
		if (fpAddress == NULL)
		{
			if (HIWORD(pszProcName) == 0)
			{
				wsprintf(szProcName, "%d", pszProcName);
				pszProcName = szProcName;
			}

			wsprintf(tzTemp, TEXT("無法找到函式 %hs,程式無法正常執行。"), pszProcName);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
			ExitProcess(-2);
		}

		return fpAddress;
	}
}
using namespace AheadLib;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函式
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		// 表示禁用dll的DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知,這樣可以減少某些程式的工作集的大小
		// 成功返回非零值,失敗返回零值;
		DisableThreadLibraryCalls(hModule);

		Hook::Hook();

		return Load();
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		Free();
		Hook::Unhook();

	}

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 匯出函式
ALCDECL AheadLib_add(void)
{
	// 儲存返回地址
	__asm POP m_dwReturn[0 * TYPE long];

	// 呼叫原始函式
	GetAddress("add")();

	// 轉跳到返回地址
	__asm JMP m_dwReturn[0 * TYPE long];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

4、將上述檔案重新編譯,
將dllTest_dll2.dll改名為dllTest_dll.dll,原來的dllTest_dll.dll改名為dllTest_dllOrg.dll,則執行dllTest.exe
則發現首先彈出我們自己定義的MessageBox,
在這裡插入圖片描述
點選確定後,成功呼叫原始的dll
在這裡插入圖片描述

說明dll劫持成功!
以後可以仿照這個例子進行dll劫持了!

AheadLib.exe下載地址

系統目錄說明:
32位系統:C:\Windows\System32資料夾
64位系統:

  1. 64位檔案預設放:C:\Windows\System32資料夾(為了相容性)
  2. 32位檔案預設放:C:\Windows\SysWOW64檔案