用AheadLib進行簡單的DLL注入
阿新 • • 發佈:2018-11-04
參考連結: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位系統:
- 64位檔案預設放:C:\Windows\System32資料夾(為了相容性)
- 32位檔案預設放:C:\Windows\SysWOW64檔案