c# 写的 CULHook(含原版C++的),高手帮忙看下问题
c++
class CULHook{
public:
CULHook(LPSTR pszModName,LPSTR pszFuncName,PROC pfnHook);
~CULHook();
void Unhook();
void Rehook();
protected:
PROC m_pfnOrig;
BYTE m_btNewBytes[8];
BYTE m_btOldBytes[8];
HMODULE m_hModule;
};
CULHook::CULHook(LPSTR pszModName,LPSTR pszFuncName,PROC pfnHook){
BYTE btNewBytes[8]={0xB8,0x00,0x00,0x40,0x00,0xFF,0xE0,0x00};
memcpy(m_btNewBytes,btNewBytes,8);
*(DWORD *)(m_btNewBytes+1)=(DWORD)pfnHook;
m_hModule=::LoadLibrary(pszModName);
if(m_hModule==NULL){
m_pfnOrig=NULL;
return;
}
m_pfnOrig=::GetProcAddress(m_hModule,pszFuncName);
if(m_pfnOrig!=NULL){
DWORD dwOldProtect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(m_pfnOrig,&mbi,sizeof(mbi));
::VirtualProtect(m_pfnOrig,8,PAGE_READWRITE,&dwOldProtect);
memcpy(m_btOldBytes,m_pfnOrig,8);
::WriteProcessMemory(::GetCurrentProcess(),(void *)m_pfnOrig,
m_btNewBytes,sizeof(DWORD)*2,NULL);
::VirtualProtect(m_pfnOrig,8,mbi.Protect,0);
}
}
c#
private IntPtr apiAddress; //目标API函数地址
private IntPtr dllModule; //新构建的8字节
private byte[] btNewBytes = new byte[8]; //原来的8字节
private byte[] btOldBytes = new byte[8]; //目标API所属模块
//……
public CULHook(string moduleName, string apiName, IntPtr myFunAddress)
{
byte[] newBytes = new byte[8] { 0xB8, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xE0, 0x00 };
Buffer.BlockCopy(newBytes, 0, btNewBytes, 0, 8);
byte[] temp = new byte[8];
Marshal.Copy(myFunAddress, temp, 0, 8);
Buffer.BlockCopy(temp, 0, btNewBytes, 1, 4);
//加载模块,获取api函数地址
dllModule = LoadLibrary(moduleName);
if (dllModule == IntPtr.Zero)
{
apiAddress = IntPtr.Zero;
return;
}
apiAddress = GetProcAddress(dllModule, apiName);
//修改api函数的前8个字节,使其指向我们的函数
if (apiAddress != IntPtr.Zero)
{
int oldProtect;
MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
VirtualQuery(apiAddress, ref mbi, Marshal.SizeOf(mbi));
VirtualProtect(apiAddress, 8, 0x40, out oldProtect);//0x40 : PAGE_EXECUTE_READWRITE
//保存原来的执行代码
Marshal.Copy(apiAddress, temp, 0, 8);
Buffer.BlockCopy(temp, 0, btOldBytes, 0, 8);
//写入新执行代码
WriteProcessMemory(GetCurrentProcess(), apiAddress, btNewBytes, sizeof(int) * 2, IntPtr.Zero);
VirtualProtect(apiAddress, 8, mbi.Protect, out oldProtect);
}
}