用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位系统:
- 64位文件默认放:C:\Windows\System32文件夹(为了兼容性)
- 32位文件默认放:C:\Windows\SysWOW64文件