进程函数监控项目

简介

该项目的目的是向特定进程中注入DLL,实现对目标进程中的特定函数进行监控,可以实现的特定函数的Hook(获取该函数的参数,不影响该函数的正常执行)、以及远程调用。
该项目的进程间通信是通过 DLL 共享节实现的。


该项目存在的缺点:

  1. 无法直接通过 DLL 中的函数获取被注入进程中的自定义函数地址(程序编写者自己写的函数地址),只能使用地址数值进行 InlineHook 和远程调用。
  2. IATHookInlineHooK、远程函数调用,由于无法知道函数的参数个数和类型,只能对特定函数进行Hook,并且每个函数都需要有自己的 Hook 函数。

该项目可完善的方向:

  1. 只能通过 GetProcAddress 函数获取到API函数地址, 如何实现实现获取该进程的自定义函数地址?
  2. 创建一个列表框,通过 PID 和函数名检查该函数是否被使用, 并将该函数添加进入被监控的函数列表中,以实现对该列表的管理 (日后优化)
  3. Hook 函数的管理——通过结构体管理,,每个函数拥有一个结构体,结构体存储在 DLL 共享节中结构体缓冲区中
  4. 调用者只需传入要 Hook 远程调用的函数名, 其余操作由 DLL 中的函数完成
  5. 实现 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
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值