简介
该项目的目的是向特定进程中注入DLL,实现对目标进程中的特定函数进行监控,可以实现的特定函数的Hook(获取该函数的参数,不影响该函数的正常执行)、以及远程调用。
该项目的进程间通信是通过 DLL
共享节实现的。
该项目存在的缺点:
- 无法直接通过
DLL
中的函数获取被注入进程中的自定义函数地址(程序编写者自己写的函数地址),只能使用地址数值进行InlineHook
和远程调用。 IATHook
、InlineHooK
、远程函数调用,由于无法知道函数的参数个数和类型,只能对特定函数进行Hook
,并且每个函数都需要有自己的Hook
函数。
该项目可完善的方向:
- 只能通过
GetProcAddress
函数获取到API函数地址, 如何实现实现获取该进程的自定义函数地址? - 创建一个列表框,通过
PID
和函数名检查该函数是否被使用, 并将该函数添加进入被监控的函数列表中,以实现对该列表的管理 (日后优化) - 被
Hook
函数的管理——通过结构体管理,,每个函数拥有一个结构体,结构体存储在DLL
共享节中结构体缓冲区中 - 调用者只需传入要
Hook
远程调用的函数名, 其余操作由DLL
中的函数完成 - 实现
DLL
、主程序隐藏
代码
DLL
#include <windows.h>
#include <TlHelp32.h>
#include <stdio.h>
//Dll共享节
#pragma data_seg(".shared")
struct Proc_Struct
{
DWORD dwFlags; //操作识别码
/* InlineHook的参数 */
DWORD dwdstFuncAddr; //目的函数地址
DWORD dwsrcFuncAddr; //源函数地址
CHAR szDstFuncName[16]; //目的函数名
CHAR szSrcFuncName[16]; //源函数名
DWORD dwcodeLength; //覆盖目标代码段数据长度
};
CHAR structBuff[100] = {
0};//存储结构体的缓冲区
Proc_Struct *ptr = NULL; //特殊结构体, 用于命令识别
// 结构体索引
LPVOID lpProcStructIndex = (LPVOID)&structBuff;
// 消息类型
#define MSG_Exit 0
#define MSG_Listenor 1
#define MSG_Excuteor 2
HMODULE hModule = NULL; //当前Dll的句柄
#pragma data_seg()
#pragma comment(linker,"/section:.shared,rws")
//HHOOK g_hHook = NULL; //全局钩子句柄
CHAR g_szBuff[100] = {
0 }; //数据缓冲区
DWORD g_dwBuffLen = 0; //存储的数据长度
const DWORD g_dwBuffMax = sizeof(g_szBuff); //缓冲区长度
CHAR szBuff[100]; //用于数据转换输出的缓冲区
/* PE结构体 */
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_FILE_HEADER pPEHeader;
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader;
PIMAGE_SECTION_HEADER pSectionHeader;
PIMAGE_DATA_DIRECTORY dataDir;
// 被IAT Hook的Messagebox
typedef int (WINAPI* PFUNC)(HWND, LPSTR, LPSTR, UINT);
/* InlineHook的参数 */
struct Reg
{
DWORD EAX;
DWORD ECX;
DWORD EDX;
DWORD EBX;
DWORD ESP;
DWORD EBP;
DWORD ESI;
DWORD EDI;
DWORD EFL;
}reg;
BYTE code[0x100]; //存储原硬编码
LPSTR lpszParam; //被InlineHook的函数参数
DWORD dwRet; //指向函数返回地址
DWORD dwsrcFuncAddr;//源函数地址
DWORD dwdstFuncAddr;//目标函数地址
DWORD dwcodeLength; //被覆盖的硬编码长度
//code数组的地址, 用于jmp回跳
DWORD dwCodeAddr;
BOOL CheckHookIsSet = FALSE;
// 创建函数信息描述结构体
Proc_Struct* CreateProcStruct()
{
Proc_Struct *p = (Proc_Struct*)lpProcStructIndex;
lpProcStructIndex = (LPVOID)((DWORD)lpProcStructIndex + sizeof(Proc_Struct));
return p;
}
DWORD CheckModuleIsExistInProcess(DWORD dwPID, LPSTR lpszDllPath)
{
// 初始化
HANDLE hModuleSnap = NULL; // 进程快照
MODULEENTRY32 me32 = {
0 };
me32.dwSize = sizeof(me32);
// 拍摄快照
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
if (hModuleSnap == INVALID_HANDLE_VALUE)
{
OutputDebugString("CreateToolhelp32Snapshot调用失败\n");
TCHAR szErrorInfo[100] = {
0 };
sprintf(szErrorInfo, "Error: %u\n", GetLastError());
OutputDebugString(szErrorInfo);
return -1;
}
BOOL bMoreOfSection = Module32First(hModuleSnap, &me32);
while (bMoreOfSection)
{
if (!strcmp(me32.szExePath, lpszDllPath))
{
OutputDebugString("该模块已存在!\n");
return 1;
}
bMoreOfSection = Module32Next(hModuleSnap, &me32);
}
CloseHandle(hModuleSnap);
return 0;
}
//DLL注入
DWORD LoadDll(LPSTR lpszWindowName, LPSTR lpszDllPath)
{
HANDLE hProcess = NULL; //远程进程句柄
HANDLE hThread = NULL; //远程线程句柄
DWORD dwPid = 0x00;
HWND hwnd = FindWindow(NULL, lpszWindowName);
GetWindowThreadProcessId(hwnd, &dwPid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
//检测该DLL是否已经注入到内存中
DWORD dwRet = CheckModuleIsExistInProcess(dwPid, lpszDllPath);
if (dwRet == 1)
{
MessageBox(NULL, "该模块已经被加载!", "提示", MB_OK);
return FALSE;
}
//获取进程信息失败
if (dwRet == -1)
{
MessageBox(NULL, "获取进程状态失败!", "提示", MB_OK);
return FALSE;
}
//向远程进程申请空间
LPVOID lpszDllPathAddr = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (lpszDllPathAddr)
{
//将模块句柄写入程序
if (WriteProcessMemory(hProcess, lpszDllPathAddr, lpszDllPath, MAX_PATH, NULL))
{
OutputDebugString("DLL名称写入成功!\n");
//获取函数地址
LPTHREAD_START_ROUTINE addr = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32"), "LoadLibraryA");
if (addr)
{
//创建远程线程
hThread = CreateRemoteThread(hProcess, NULL, 0, addr, lpszDllPathAddr, 0, NULL);
if (hThread)
{
OutputDebugString("线程创建成功!\n");
//WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (DWORD*)&hModule);
if (hModule)
{
OutputDebugString("线程执行成功!\n");
return TRUE;
}
else
{
OutputDebugString("线程执行失败!\n");
}
}
else
OutputDebugString("线程创建失败!\n");
}
else
OutputDebugString("获取LoadLibrary函数地址失败!\n");
}
else
OutputDebugString("模块句柄写入失败!\n");
//释放空间
if (VirtualFreeEx(hProcess, lpszDllPathAddr, 0x20, MEM_DECOMMIT))
{
OutputDebugString("空间释放成功!\n");
}
else
OutputDebugString("空间释放失败!\n");
}
else
{
OutputDebugString("DLL名称空间分配失败!\n");
}
//关闭句柄
CloseHandle(hThread);
CloseHandle(hProcess);
MessageBox(NULL, "DLL注入失败!", "提示", MB_OK);
return FALSE;
}
BOOL UnloadDll(HMODULE hModule)
{
if(FreeLibrary(hModule))
{
OutputDebugString("卸载Dll成功\n");
return TRUE;
}
return FALSE;
}
//未使用
BOOL Write(LPSTR lpszBuff, DWORD dwBuffLen)
{
if (g_dwBuffMax < dwBuffLen)
return FALSE;
ZeroMemory(g_szBuff, g_dwBuffMax);
memcpy(g_szBuff, lpszBuff, dwBuffLen);
g_dwBuffLen = dwBuffLen;
return TRUE;
}
//未使用
DWORD Read(LPSTR lpszBuff, DWORD dwBuffLen)
{
if (dwBuffLen < g_dwBuffLen)
return 0;
ZeroMemory(lpszBuff, dwBuffLen);
memcpy(lpszBuff, g_szBuff, g_dwBuffLen);
return g_dwBuffLen;
}
DWORD GetWindowThreadID(LPSTR lpszWindowName)
{
// 初始化
HANDLE hProcess;
HANDLE hThreadSnap = NULL; // 模块快照
DWORD th32ThreadID = 0;
DWORD dwPid = 0x00;
THREADENTRY32 thread32 = {
0 };
BOOL bMoreOfThread;
//获取进程句柄
HWND hwnd = FindWindow(NULL, lpszWindowName);
if (!hwnd)
{
return FALSE;
}
GetWindowThreadProcessId(hwnd, &dwPid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
//获取线程ID
thread32.dwSize = sizeof(thread32);
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
{
OutputDebugString("获取线程信息失败!\n");
return FALSE;
}
bMoreOfThread = Thread32First(hThreadSnap, &thread32);
while (bMoreOfThread)
{
if (thread32.th32OwnerProcessID == dwPid)
{
th32ThreadID = thread32.th32ThreadID;
break;
}
bMoreOfThread = Thread32Next(hThreadSnap, &thread32);
}
CloseHandle(hThreadSnap);
return th32ThreadID;
}
// IAT Hook下的Messagebox处理函数
int WINAPI MyMessageBox(HWND hWnd, LPSTR lpText, LPSTR lpCaption, UINT uType)
{
OutputDebugString("MessageBox参数如下:\n");
sprintf(szBuff, "hWnd: %x, lpText: %s, lpCaption: %s, uType: %u\n", hWnd, lpText, lpCaption, uType);
OutputDebugString(szBuff);
PFUNC pfunc = (PFUNC)dwsrcFuncAddr;
pfunc(NULL, (LPSTR)"这是被IAT HOOK后的MessageBox!", (LPSTR)"提示", MB_OK);
return 0;
}
BOOL GetPEHeader(LPVOID pImageBuffer)
{
pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
//判断是否是有效的MZ标志
if (*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE)
{
return FALSE;
}
pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);
pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + sizeof(IMAGE_FILE_HEADER));
pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pPEHeader->SizeOfOptionalHeader);
//指向首个目录表, 即导出表
dataDir = (PIMAGE_DATA_DIRECTORY)((DWORD)pOptionalHeader + 0x60);
return TRUE;
}
VOID IATHook(LPVOID lpdstFuncAddr, LPVOID lpsrcFuncAddr, BOOL isSet)
{
// 导入表中的Dll模块句柄
HMODULE hModule;
//目标进程的内存镜像
LPVOID lpImageBuff = GetModuleHandle(NULL);
//PIMAGE_IMPORT_BY_NAME importByName;
//获取PE信息
GetPEHeader(lpImageBuff);
//指向导入表
dataDir += 1;
if (dataDir != 0x00)
{
PIMAGE_IMPORT_DESCRIPTOR importDir = (PIMAGE_IMPORT_DESCRIPTOR)(dataDir->VirtualAddress + (DWORD)lpImageBuff);
//遍历导入表
while (*(DWORD*)importDir != 0x0)
{
//遍历FirstThunk
DWORD* pFirstThunk = (DWORD*)(importDir->FirstThunk + (DWORD)lpImageBuff);
//判断IAT表是否已经绑定
BOOL isBind = (importDir->TimeDateStamp == 0) ? FALSE : TRUE;
while (!isBind)
{
//判断FirstThunk是否结束
if (*pFirstThunk == 0x00)
{
break;
}
//获取导入表DLL名
LPSTR lpszNameOfDll = (LPSTR)(importDir->Name + (DWORD)lpImageBuff);
//加载DLL模块
hModule = LoadLibraryA(lpszNameOfDll);
DWORD FirstThunk = *pFirstThunk;
//判断OriginalFirstThunk是否指向函数名
if (FirstThunk >> 31 != 0x01)
{
if (FirstThunk == (DWORD)lpsrcFuncAddr || FirstThunk == (DWORD)lpdstFuncAddr)
{
//设置Hook
if (isSet)
{
*pFirstThunk = (DWORD)lpdstFuncAddr;
return;
}
//卸载Hook
else
{
//DWORD* FirstThunkOfINT = (DWORD*)(importDir->OriginalFirstThunk + (DWORD)lpImageBuff);
//importByName = (PIMAGE_IMPORT_BY_NAME)(*FirstThunkOfINT + (DWORD)lpImageBuff);
//printf("%s\n", (CHAR*)importByName->Name);
//*pFirstThunk = (DWORD)GetProcAddress(hModule, (CHAR*)importByName->Name);
*pFirstThunk = (DWORD)lpsrcFuncAddr;
return;
}
}
}
pFirstThunk++;
}
importDir++;
}
}
}
// 检查函数是否在IAT表中存在, 通过函数名检查, 对于未导出函数而言,无法实现检测
LPVOID GetProcAddressByProcName(LPSTR lpszFuncName)
{
// 导入表中的Dll模块句柄
HMODULE hModule;
//目标进程的内存镜像
LPVOID lpImageBuff = GetModuleHandle(NULL);
//获取PE信息
GetPEHeader(lpImageBuff);
//指向导入表
dataDir += 1;
if (dataDir != 0x00)
{
PIMAGE_IMPORT_DESCRIPTOR importDir = (PIMAGE_IMPORT_DESCRIPTOR)(dataDir->VirtualAddress + (DWORD)lpImageBuff);
//遍历导入表
while (*(DWORD*)importDir != 0x0)
{
//遍历OriginalFirstThunk, IAT表
DWORD* pOriginalFirstThunk = (DWORD*)(importDir->OriginalFirstThunk + (DWORD)lpImageBuff);
while (*pOriginalFirstThunk != 0x00)
{
DWORD OriginalFirstThunk = *pOriginalFirstThunk;
//判断OriginalFirstThunk是否指向函数名
if (OriginalFirstThunk >> 31 != 0x01)
{
//指向函数名
PIMAGE_IMPORT_BY_NAME importByName = (PIMAGE_IMPORT_BY_NAME)(OriginalFirstThunk + (DWORD)lpImageBuff);
if (!strcmp((LPSTR)(importByName->Name), lpszFuncName))
{
//获取导入表DLL名
LPSTR lpszNameOfDll = (LPSTR)(importDir->Name + (DWORD)lpImageBuff);
//加载DLL模块
hModule = LoadLibrary(lpszNameOfDll);
return GetProcAddress(hModule, (CHAR*)importByName->Name);
}
}
pOriginalFirstThunk++;
}
importDir++;
}
}
return NULL;
}
// 通过函数名获取函数地址
BOOL CheckFuncIsExistInIAT(LPSTR lpszFuncName)
{
//目标进程的内存镜像
LPVOID lpImageBuff = GetModuleHandle(NULL);
//获取PE信息
GetPEHeader(lpImageBuff);
//指向导入表
dataDir += 1;
if (dataDir != 0x00)
{
PIMAGE_IMPORT_DESCRIPTOR importDir = (PIMAGE_IMPORT_DESCRIPTOR)(dataDir->VirtualAddress + (DWORD)lpImageBuff);
//遍历导入表
while (*(DWORD*)importDir != 0x0)
{
//遍历OriginalFirstThunk, IAT表
DWORD* pOriginalFirstThunk = (DWORD*)(importDir->OriginalFirstThunk + (DWORD)lpImageBuff);
while (*pOriginalFirstThunk != 0x00)
{
DWORD OriginalFirstThunk = *pOriginalFirstThunk;
//判断OriginalFirstThunk是否指向函数名
if (OriginalFirstThunk >> 31 != 0x01)
{
//指向函数名
PIMAGE_IMPORT_BY_NAME importByName = (PIMAGE_IMPORT_BY_NAME)(OriginalFirstThunk + (DWORD)lpImageBuff);
if (!strcmp((LPSTR)importByName->Name, lpszFuncName))
return TRUE;
}
pOriginalFirstThunk++;
}
importDir++;
}
}
return FALSE;
}
LPVOID AddrTranslation(LPVOID lpFuncAddr)
{
//检测程序是否开启增量链接
if (*(BYTE*)lpFuncAddr == 0xe9)
{
//地址转换, 将jmp func指令地址转化为真正的函数地址
return (LPVOID)(*(DWORD*)((DWORD)lpFuncAddr + 1) + (DWORD)lpFuncAddr + 5);
}
else
return lpFuncAddr;
}
VOID __declspec(naked)InlineHook()
{
__asm
{
pushad
pushfd
mov reg.EAX, eax
mov reg.ECX, ecx
mov reg.EDX, edx
mov reg.EBX, ebx
mov eax, [esp + 0x10]
mov reg.ESP, eax
mov reg.EBP, ebp
mov reg.ESI, esi
mov reg.EDI, edi
mov eax, [esp]
mov reg.EFL, eax
mov eax, [esp + 4 * 10]
mov lpszParam, eax
}
//打印寄存器的值
ZeroMemory(szBuff, 100);
sprintf(szBuff, "eax: %x, ecx: %x, edx: %x, ebx: %x, esp: %x, ebp: %x, esi: %x, edi: %x, elf: %x", reg.EAX, reg.ECX, reg.EDX, reg.EBX, reg.ESP, reg.EBP, reg.ESI, reg.EDI, reg.EFL);
OutputDebugString(szBuff);
//打印函数参数
ZeroMemory(szBuff, 100);
sprintf(szBuff, "函数参数: %s\n", lpszParam);
OutputDebugString(szBuff);
//code数组的地址, 用于jmp回跳
dwCodeAddr = (DWORD)&code;
__asm
{
popfd
popad
jmp dwCodeAddr
}
}
BOOL SetInlineHook(LPVOID lpdstFuncAddr, LPVOID lpsrcFuncAddr, DWORD codeLen)
{
//地址转换, 将jmp SayHello指令地址转化为真正的函数地址
dwdstFuncAddr = (DWORD)AddrTranslation(lpdstFuncAddr);
dwsrcFuncAddr = (DWORD)AddrTranslation(lpsrcFuncAddr);
//将原代码的硬编码存储在code数组中
dwcodeLength = codeLen;
memcpy(&code, (LPVOID)dwsrcFuncAddr, dwcodeLength);
//计算jmp的硬编码
BYTE shellCode[5] = {
0xe9, 0x00, 0x00, 0x00, 0x00
};
DWORD jmpAddr = dwdstFuncAddr - (dwsrcFuncAddr + 5);
memcpy((LPVOID)((DWORD)&shellCode + 1), &jmpAddr, 4);
//修改页面属性
DWORD flOldProtect;
if (!(VirtualProtectEx(GetCurrentProcess(), (LPVOID)dwsrcFuncAddr, dwcodeLength, PAGE_EXECUTE_READWRITE, &flOldProtect) &&
VirtualProtectEx(GetCurrentProcess(), (LPVOID)&code, sizeof(code), PAGE_EXECUTE_READWRITE, &flOldProtect)))
{
OutputDebugString("页面属性设置失败!\n");
return FALSE;
}
//将shellCode写入代码中
memset((LPVOID)dwsrcFuncAddr, 0x90, dwcodeLength);
memcpy((LPVOID)dwsrcFuncAddr, &shellCode, sizeof(shellCode));
//jmp跳转至code执行被Hook的代码
//原函数返回地址
dwRet = dwsrcFuncAddr - (DWORD)&code - 5;
//设置返回ShellCode
memset((LPVOID)((DWORD)&shellCode + 1), 0, sizeof(shellCode) - 1);
memcpy((LPVOID)((DWORD)&shellCode + 1), &dwRet, sizeof(DWORD));
memcpy((LPVOID)((DWORD)&code + dwcodeLength), &shellCode, sizeof(shellCode));
return TRUE;
}
BOOL UnsetInlineHook(LPVOID lpsrcFuncAddr, DWORD codeLen)
{
//恢复被Hook函数的硬编码
memcpy((LPVOID)dwsrcFuncAddr, &code, codeLen);
//恢复代码段的页属性
DWORD flOldProtect;
if (!VirtualProtectEx(GetCurrentProcess(), (LPVOID)dwsrcFuncAddr, dwcodeLength, PAGE_EXECUTE_READ, &flOldProtect))
{
OutputDebugString("页面属性恢复失败!\n");
return FALSE;
}
return TRUE;
}
//远程调用函数,测试
VOID Excuteor()
{
typedef VOID(*typedef_SayHello)(LPSTR);
typedef_SayHello SayHello = (typedef_SayHello)0x004010F0;
SayHello("kaka");
}
VOID MySendMessage(Proc_Struct* lpProcStruct)
{
ptr = lpProcStruct;
}
VOID MsgProc()
{
OutputDebugString("MsgProc.\n");
while(TRUE)
{
// 避免消耗性能, 可能会造成响应延迟
Sleep(100);
//检查ptr指针是否为空
if(!ptr)
continue;
switch(ptr->dwFlags)
{
//卸载DLL
case MSG_Exit:
{
UnloadDll(hModule);
break;
}
//函数监控
case MSG_Listenor:
{
//IAT Hook
if (CheckFuncIsExistInIAT(ptr->szSrcFuncName))
{
//设置IATHook
if (!CheckHookIsSet)
{
ptr->dwsrcFuncAddr = (DWORD)GetProcAddressByProcName(ptr->szSrcFuncName);
dwsrcFuncAddr = ptr->dwsrcFuncAddr;
IATHook(MyMessageBox, (LPVOID)ptr->dwsrcFuncAddr, TRUE);
}
//卸载IATHook
else
{
IATHook(MyMessageBox, (LPVOID)ptr->dwsrcFuncAddr, FALSE);
}
}
//Inline Hook
else
{
//设置InlineHook
if(!CheckHookIsSet)
{
// 将存储硬编码的Code数组初始化
dwcodeLength = 6; //要覆盖的代码字节数
ZeroMemory(&code, sizeof(code));
SetInlineHook(InlineHook, (LPVOID)0x004010F0, dwcodeLength);
}
else
{
UnsetInlineHook((LPVOID)0x004010F0, dwcodeLength);
}
}
CheckHookIsSet = !CheckHookIsSet;
break;
}
//远程调用
case MSG_Excuteor:
{
Excuteor();
break;
}
default:
break;
}
ptr = NULL;
}
}
// 初始化函数, 创建远程线程指向处理函数MsgProc
BOOL Init(LPSTR lpWindowName, LPSTR lpDllPath)
{
HANDLE hProcess = NULL; //远程进程句柄
HANDLE hThread = NULL; //远程线程句柄
DWORD dwPid = 0x00;
DWORD dwRet; // 远程线程返回值
HWND hwnd = FindWindow(NULL, lpWindowName);
GetWindowThreadProcessId(hwnd, &dwPid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
// 进行对目标进程的Dll注入
LoadDll(lpWindowName, lpDllPath);
// 创建远程线程指向指令处理函数
hThread = CreateRemoteThread(hProcess, NULL, 0, (unsigned long (__stdcall *)(void *))MsgProc, NULL, 0, NULL);
if (hThread)
{
OutputDebugString("线程创建成功!\n");
//WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwRet);
goto Exit;
}
else
{
OutputDebugString("线程创建失败!\n");
CloseHandle(hProcess);
return FALSE;
}
Exit:
//关闭句柄
CloseHandle(hProcess);
if (dwRet)
{
OutputDebugString("线程执行成功!\n");
return TRUE;
}
else
{
OutputDebugString("线程执行失败!\n");
return FALSE;
}
}
测试程序
#include <Windows.h>
#include <stdio.h>
struct Proc_Struct
{
DWORD dwFlags;
/* InlineHook的参数 */
DWORD dwdstFuncAddr; //目的函数地址
DWORD dwsrcFuncAddr; //源函数地址
CHAR szDstFuncName[16]; //目的函数名
CHAR szSrcFuncName[16]; //源函数名
DWORD dwcodeLength; //覆盖目标代码段数据长度
};
int main(int argc, CHAR* argv[])
{
// typedef BOOL(*typedef_SetGlobalHook)(int idHook, LPSTR lpszWindowName);
// typedef BOOL(*typedef_UnsetGlobalHook)();
typedef BOOL(*typedef_Write)(LPSTR lpszBuff, DWORD dwBuffLen);
typedef DWORD(*typedef_Read)(LPSTR lpszBuff, DWORD dwBuffLen);
typedef Proc_Struct*(*typedef_CreateProcStruct)();
typedef VOID(*typedef_MySendMessage)(Proc_Struct* lpProcStruct);
typedef BOOL(*typedef_Init)(LPSTR lpWindowName, LPSTR lpDllPath);
HMODULE hDll = NULL;
// typedef_SetGlobalHook SetGlobalHook = NULL;
// typedef_UnsetGlobalHook UnsetGlobalHook = NULL;
typedef_Write Write;
typedef_Read Read;
typedef_CreateProcStruct CreateProcStruct;
typedef_MySendMessage MySendMessage;
typedef_Init Init;
DWORD dwBuffLen;
BYTE szBuff[100] = {
0};
BOOL bRet = FALSE;
//LPSTR lpWindowName = "Win32App";
LPSTR lpDllPath = "C:\\vc6++\\MyProjects\\GlobalHook\\Debug\\GlobalHook.dll";
LPSTR lpWindowName = "mfc";
LPSTR lpszBuff;
hDll = LoadLibrary(lpDllPath);
if (NULL == hDll)
{
printf("LoadLibrary Error[%d]\n", ::GetLastError());
return 0;
}
CreateProcStruct = (typedef_CreateProcStruct)(GetProcAddress(hDll, "CreateProcStruct"));
MySendMessage = (typedef_MySendMessage)GetProcAddress(hDll, "MySendMessage");
Init = (typedef_Init)(GetProcAddress(hDll, "Init"));
do
{
Init(lpWindowName, lpDllPath);
Proc_Struct* lpProcStruct = CreateProcStruct();
strcpy(lpProcStruct->szSrcFuncName, "MessageBoxA");
lpProcStruct->dwFlags = 1;
MySendMessage(lpProcStruct); //SetHook
MySendMessage(lpProcStruct); //UnsetHook
lpProcStruct->dwFlags = 0;
MySendMessage(lpProcStruct); //UnloadDll
}while(FALSE);
FreeLibrary(hDll);
return 0;
}
效果图
设置 IATHook
:
卸载 IATHook
: