www.pudn.com > API Hook 工具相关代码 apihooktest.rar > HookProcess.cpp
// HookProcess.cpp: implementation of the CHookProcess class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HookProcess.h"
#include "imagehlp.h"
#pragma comment(lib, "imagehlp.lib")
CHookProcess::CHookProcess()
{
}
CHookProcess::~CHookProcess()
{
}
BOOL CHookProcess::HookProcess(HANDLE hProcess, char* pszFileExe, char* pszFileDll)
{
BYTE szBuf[1024*8];
DWORD dwTemp(0);
DWORD dwOldProtect(0);
DWORD dwOldEntryPoint(0);
//得到入口地址(dwOldEntryPoint)
dwOldEntryPoint = GetProcessEntryPoint(pszFileExe);
//在目标进程空间中分配一段内存
//内存中个格式
// DllFile(strlen(pszFileDll) ) + 0(1 Byte) + 旧的入口代码(10 Byte) + 新入口代码(n<10)
LPBYTE pAllocNew = (LPBYTE)AllocBufAfterBaseAdr(hProcess, (LPVOID)dwOldEntryPoint, 1024);
if(pAllocNew == NULL)
{
return FALSE;
}
int nPos = 0;
//将Dll文件路径拷贝过去
{
if(!WriteProcessMemorySafe(hProcess, &pAllocNew[nPos], pszFileDll, strlen(pszFileDll) + 1))
{
return FALSE;
}
nPos += (strlen(pszFileDll) + 1);
}
//将旧的入口代码 10 字节 拷贝过去
{
if(!ReadProcessMemorySafe(hProcess, (LPVOID)dwOldEntryPoint, &szBuf[0], 10, &dwTemp))
{
return FALSE;
}
if(!WriteProcessMemorySafe(hProcess, &pAllocNew[nPos], (LPVOID)&szBuf[0], 10))
{
return FALSE;
}
nPos += 10;
}
//写入汇编硬代码
//主要任务是 LoadLibrary(DllFile) 然后 Jmp 到旧原来的入口处
/*
push adrDllPath
mov eax, &LoadLibrary
call eax
//拷贝我们保存下来的旧的入口代码回去(10 Byte),然后jmp过去
mov eax, adrOldCode
mov ebx, adrEntryPoint
mov cl, byte ptr[eax]
mov byte ptr[ebx], cl
add eax, 2
add ebx, 2
mov cx, word ptr[eax]
mov word ptr[ebx], cx
... (公加5次)
mov eax, adrEntryPoint
jmp eax
偶得汇编很差,没用什么循环,10个字节,每次2个,共复制了5遍,(不要笑哦 -_-!)
*/
{
int nAsmPos = 0;
//push DllFilePahtAdr
szBuf[nAsmPos++] = 0x68;
*(DWORD*)&szBuf[nAsmPos] = (DWORD)pAllocNew;
nAsmPos += 4;
//mov eax, &LoadLibrary
HMODULE hKernel = GetModuleHandle("kernel32.dll");
if(hKernel == NULL)
{
return FALSE;
}
DWORD dwLoadLibFun = (DWORD)GetProcAddress(hKernel, "LoadLibraryA");
if(dwLoadLibFun == 0)
{
return FALSE;
}
szBuf[nAsmPos++] = 0xB8;
*(DWORD*)&szBuf[nAsmPos] = dwLoadLibFun;
nAsmPos += 4;
//call eax
szBuf[nAsmPos++] = 0xFF;
szBuf[nAsmPos++] = 0xD0;
//mov eax, adrOldCode
dwTemp = strlen(pszFileDll) + 1 + (DWORD)pAllocNew;
szBuf[nAsmPos++] = 0xB8;
*(DWORD*)&szBuf[nAsmPos] = dwTemp;
nAsmPos += 4;
//mov ebx, adrEntryPoint
szBuf[nAsmPos++] = 0xBB;
*(DWORD*)&szBuf[nAsmPos] = dwOldEntryPoint;
nAsmPos += 4;
//共拷贝2字节
//mov cx, word ptr[eax]
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x8B;
szBuf[nAsmPos++] = 0x08;
//mov word ptr[ebx], cx
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x89;
szBuf[nAsmPos++] = 0x0B;
//共拷贝4字节
//add eax, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC0;
szBuf[nAsmPos++] = 0x02;
//add ebx, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC3;
szBuf[nAsmPos++] = 0x02;
//mov cx, word ptr[eax]
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x8B;
szBuf[nAsmPos++] = 0x08;
//mov word ptr[ebx], cx
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x89;
szBuf[nAsmPos++] = 0x0B;
//共拷贝6字节
//add eax, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC0;
szBuf[nAsmPos++] = 0x02;
//add ebx, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC3;
szBuf[nAsmPos++] = 0x02;
//mov cx, word ptr[eax]
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x8B;
szBuf[nAsmPos++] = 0x08;
//mov word ptr[ebx], cx
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x89;
szBuf[nAsmPos++] = 0x0B;
//共拷贝8字节
//add eax, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC0;
szBuf[nAsmPos++] = 0x02;
//add ebx, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC3;
szBuf[nAsmPos++] = 0x02;
//mov cx, word ptr[eax]
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x8B;
szBuf[nAsmPos++] = 0x08;
//mov word ptr[ebx], cx
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x89;
szBuf[nAsmPos++] = 0x0B;
//共拷贝10字节
//add eax, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC0;
szBuf[nAsmPos++] = 0x02;
//add ebx, 2
szBuf[nAsmPos++] = 0x83;
szBuf[nAsmPos++] = 0xC3;
szBuf[nAsmPos++] = 0x02;
//mov cx, word ptr[eax]
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x8B;
szBuf[nAsmPos++] = 0x08;
//mov word ptr[ebx], cx
szBuf[nAsmPos++] = 0x66;
szBuf[nAsmPos++] = 0x89;
szBuf[nAsmPos++] = 0x0B;
//mov eax, adrEntryPoing
szBuf[nAsmPos++] = 0xB8;
*(DWORD*)&szBuf[nAsmPos] = dwOldEntryPoint;
nAsmPos += 4;
//jmp eax
szBuf[nAsmPos++] = 0xFF;
szBuf[nAsmPos++] = 0xE0;
if(!WriteProcessMemorySafe(hProcess, &pAllocNew[nPos], &szBuf[0], nAsmPos))
{
return FALSE;
}
}
//将旧的入口代码 变成一个 jmp 跳到我们的代码中
/*
* mov eax, adr
* jmp eax
*/
{
DWORD dwAdr = 11 + strlen(pszFileDll) + (DWORD)&pAllocNew[0];
int nPos = 0;
szBuf[nPos++] = 0xB8;
*(DWORD*)&szBuf[nPos] = dwAdr;
nPos += 4;
szBuf[nPos++] = 0xFF;
szBuf[nPos++] = 0xE0;
if(!WriteProcessMemorySafe(hProcess, (LPVOID)dwOldEntryPoint, &szBuf[0], nPos))
{
return FALSE;
}
VirtualProtectEx(hProcess, (LPVOID)dwOldEntryPoint, 10, PAGE_READWRITE, &dwTemp);
}
return TRUE;
}
DWORD CHookProcess::GetProcessEntryPoint(char* pszFileExe)
{
PLOADED_IMAGE pImage = ImageLoad(pszFileExe, NULL);
if(pImage == NULL)
{
return 0L;
}
DWORD dwAdr = pImage->FileHeader->OptionalHeader.AddressOfEntryPoint + pImage->FileHeader->OptionalHeader.ImageBase;
ImageUnload(pImage);
return dwAdr;
}
LPVOID CHookProcess::AllocBufAfterBaseAdr(HANDLE hProcess, LPVOID pBase, int nSize)
{
//在目标进程空间中分配一段内存
LPBYTE pAllocNew = NULL;
LPBYTE pBase1 = (LPBYTE)pBase;
int nCount = 100000;
for(nCount = 0; nCount < 100000 && pAllocNew == NULL; nCount--)
{
pBase1 += 8*1024;
pAllocNew = (LPBYTE)VirtualAllocEx(hProcess, pBase1, nSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
}
return pAllocNew;
}
BOOL CHookProcess::WriteProcessMemorySafe(HANDLE hProcess, LPVOID pDes, LPVOID pSrc, int nSize)
{
DWORD dwOldProtect(0);
DWORD dwWrite(0);
try
{
if(!VirtualProtectEx(hProcess, pDes, nSize, PAGE_READWRITE, &dwOldProtect))
{
return FALSE;
}
if(!WriteProcessMemory(hProcess, pDes, pSrc, nSize, &dwWrite) ||
dwWrite != (DWORD)nSize)
{
return FALSE;
}
VirtualProtectEx(hProcess, pDes, nSize, dwOldProtect, &dwOldProtect);
}
catch(...)
{
return FALSE;
}
return TRUE;
}
BOOL CHookProcess::ReadProcessMemorySafe(HANDLE hProcess, LPCVOID lpBaseAdr, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberofBytesRead)
{
DWORD dwOldProtect(0);
DWORD dwWrite(0);
try
{
if(!VirtualProtectEx(hProcess, (void*)lpBaseAdr, nSize, PAGE_READWRITE, &dwOldProtect))
{
return FALSE;
}
if(!ReadProcessMemory(hProcess, lpBaseAdr, lpBuffer, nSize, lpNumberofBytesRead))
{
return FALSE;
}
VirtualProtectEx(hProcess, (void*)lpBaseAdr, nSize, dwOldProtect, &dwOldProtect);
}
catch(...)
{
return FALSE;
}
return TRUE;
}