hook模板x86/x64通用版(4)--CHook.cpp说明

因为注释比较齐全,所以同样不多说别的了。

#include "StdAfx.h"
#include "Hook.h"

//导入bea反汇编引擎
#define BEA_ENGINE_STATIC  
#define BEA_USE_STDCALL    
#include "../beaEngine/headers/BeaEngine.h"
#ifdef _WIN64
#pragma comment(lib, "../beaEngine/win64/lib/BeaEngineCheetah64.lib")
#pragma comment(linker,"/nodefaultlib:crt64.lib")
#else
#pragma comment(lib, "../beaEngine/win32/lib/BeaEngineCheetah.lib")
#pragma comment(linker,"/nodefaultlib:crt.lib")
#endif//BeaEngine end

//静态成员初始化
BYTE* CHook::m_szRet = 0;
//中转函数的shellcode
#ifdef _WIN64
BYTE CHook::m_szTransferFunction[TRANSFER_FUNC_SIZE] = {
0x50 , 0x51 , 0x52 , 0xB9 , 0x00 , 0x00 , 0x00 , 
0x00 , 0x48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xea , 
0x68 , 0x48 , 0x83 , 0xec , 0x20 , 0xE8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 
0x04 , 0x24 , 0x12 , 0x68 , 0x00 , 0x00 , 0x00 , 
0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 
0x00 , 0x00 , 0xC3 , 0x48 , 0x83 , 0xc4 , 0x20 ,0x53 , 0x55 , 0x54 , 0x56 , 
0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 
0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 
0x56 , 0x41 , 0x57 , 0xE8 , 0x00 , 0x00 , 0x00 , 
0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x00 , 
0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 
0x00 , 0x00 , 0x00 , 0x00 , 0xC3 , 0x41 , 0x5F , 
0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 
0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 
0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 
0x58 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x9c , 0x50 , 0x51 , 0x52 , 0x48 , 0x83 , 0xec , 0x20 , 0xB9 , 
0x00 , 0x00 , 0x00 , 0x00 , 0x48 , 0x31 , 0xD2 , 
0xE8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 
0x24 , 0x12 , 0x68 , 0x00 , 0x00 , 0x00 , 0x00 , 
0xC7 , 0x44 , 0x24 , 0x04 , 0x00 , 0x00 , 0x00 , 
0x00 , 0xC3 , 0x48 , 0x83 , 0xc4 , 0x20 , 0x5A , 0x59 , 0x58 , 0x9d , 0x68 , 0x00 , 
0x00 , 0x00 , 0x00 , 0xC7 , 0x44 , 0x24 , 0x04 , 
0x00 , 0x00 , 0x00 , 0x00 , 0xC3
};
BYTE CHook::m_szTransferFunction_ForCall[TRANSFER_FUNC_FOR_CALL_SIZE] = {
0x50 , 0x51 , 0x52 , 0x\
B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\
48 , 0x87 , 0x54 , 0x24 , 0x18 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\
E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
48 , 0x83 , 0xC4 , 0x20 , 0x\
B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\
48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xEA , 0x68 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\
E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
48 , 0x83 , 0xC4 , 0x20 , 0x53 , 0x55 , 0x54 , 0x56 , 0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 0x56 , 0x41 , 0x57 , 0x\
E8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
41 , 0x5F , 0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 0x58 , 0x48 , 0x83 , 0xC4 , 0x08 , 0x\
68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0x\
90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x\
50 , 0x51 , 0x52 , 0x\
B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\
48 , 0x89 , 0xE2 , 0x48 , 0x83 , 0xEA , 0x68 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\
E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
48 , 0x83 , 0xC4 , 0x20 , 0x53 , 0x55 , 0x54 , 0x56 , 0x57 , 0x41 , 0x50 , 0x41 , 0x51 , 0x41 , 0x52 , 0x41 , 0x53 , 0x41 , 0x54 , 0x41 , 0x55 , 0x41 , 0x56 , 0x41 , 0x57 , 0x\
E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
41 , 0x5F , 0x41 , 0x5E , 0x41 , 0x5D , 0x41 , 0x5C , 0x41 , 0x5B , 0x41 , 0x5A , 0x41 , 0x59 , 0x41 , 0x58 , 0x5F , 0x5E , 0x5C , 0x5D , 0x5B , 0x5A , 0x59 , 0x\
B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\
48 , 0x83 , 0xEC , 0x20 , 0x\
E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
48 , 0x83 , 0xC4 , 0x20 , 0x48 , 0x87 , 0x04 , 0x24 , 0x50 , 0x51 , 0x52 , 0x48 , 0x83 , 0xEC , 0x20 , 0x\
B9 , 0x78 , 0x56 , 0x34 , 0x12 , 0x\
48 , 0x31 , 0xD2 , 0x\
E8 , 0x20 , 0x00 , 0x00 , 0x00 , 0x83 , 0x04 , 0x24 , 0x12 , 0x68 , 0x78 , 0x56 , 0x34 , 0x12 , 0xC7 , 0x44 , 0x24 , 0x04 , 0x21 , 0x43 , 0x65 , 0x87 , 0xC3 , 0x\
48 , 0x83 , 0xC4 , 0x20 , 0x5A , 0x59 , 0x58 , 0xC3
};
#else
BYTE CHook::m_szTransferFunction[TRANSFER_FUNC_SIZE] = {
0x50 , 0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 
0x68 , /*[pos:0x7]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0xc]*/0x00 , 0x00 , 0x00 , 0x00 , 
0x58 , 0x60 , 
0xE8 , /*[pos:0x13]*/0x00 , 0x00 , 0x00 , 0x00 , 
0x61 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x50 , 0x6A , 0x00 , 
0x68 , /*[pos:0x3a]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0x3f]*/0x00 , 0x00 , 0x00 , 0x00 , 
0x58 , 
0xE9 , /*[pos:0x45]*/0x00 , 0x00 , 0x00 , 0x00
};

BYTE CHook::m_szTransferFunction_ForCall[TRANSFER_FUNC_FOR_CALL_SIZE] = {
0x87 , 0x04 , 0x24 , 0x50 , 
0x68 , /*[pos:0x5]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0xa]*/0xC9 , 0xFB , 0xD1 , 0x76 , 
0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 
0x68 , /*[pos:0x14]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0x19]*/0xBA , 0xFB , 0xD1 , 0x76 , 
0x58 , 0x60 , 
0xE8 , /*[pos:0x20]*/0x2F , 0xE7 , 0xFF , 0xFF , 
0x61 , 
0x68 , /*[pos:0x26]*/0x00 , 0x00 , 0x00 , 0x00 , 
/*[pos:0x2a]*/0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 0x90 , 
/*[pos:0x48]*/0x50 , 0x54 , 0x83 , 0x2C , 0x24 , 0x1C , 
0x68 , /*[pos:0x4f]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0x54]*/0x7F , 0xFB , 0xD1 , 0x76 , 
0x58 , 0x60 , 
0xE8 , /*[pos:0x5b]*/0xF4 , 0xE6 , 0xFF , 0xFF , 
0x61 , 0x50 , 
0x68 , /*[pos:0x62]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0x67]*/0xC8 , 0xF8 , 0xD1 , 0x76 , 
0x87 , 0x04 , 0x24 , 0x50 , 0x6A , 0x00 , 
0x68 , /*[pos:0x72]*/0x00 , 0x00 , 0x00 , 0x00 , 
0xE8 , /*[pos:0x77]*/0x5C , 0xFB , 0xD1 , 0x76 , 
0x58 , 0xC3
};
#endif

//dllmain中创建线程dwWaitThread,调用MyEntry.cpp的StartHook函数
//在暴露给用户的MyEntry.cpp中隐藏起来这些东西。
extern void WINAPI StartHook();

DWORD WINAPI dwWaitThread( LPVOID lpArgs )
{
	StartHook();
	return 0;
}

//写jmp的x86版本函数
void CHook::WriteJMP_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo)
{
	DWORD_PTR dwAdr = dwFrom;

	DWORD dwOldP;
	VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);

	*(BYTE*)dwAdr = 0xE9;
	dwAdr+=1;
	*(DWORD*)dwAdr = dwTo - (dwFrom + 5);
}
//写call的x86版本函数
void CHook::WriteCall_x86(DWORD_PTR dwFrom , DWORD_PTR dwTo)
{
	DWORD_PTR dwAdr = dwFrom;

	DWORD dwOldP;
	VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);

	*(BYTE*)dwAdr = 0xE8;
	dwAdr+=1;
	*(DWORD*)dwAdr = dwTo - (dwFrom + 5);
}

//类构造函数
CHook::CHook(void* pOriginAdr , void* pNewHook)
{
	Init();
	SetHook(pOriginAdr , pNewHook);
}

CHook::CHook(void* pOriginAdr , void* pNewHook , void* pHookAfterCall)
{
	Init();
	SetHook(pOriginAdr , pNewHook , pHookAfterCall);
}
//析构函数
CHook::~CHook(void)
{
//等待hook函数走完再析构和释放
	if (m_szMyTransfer)
	{
		while (TlsGetValue(m_dwTlsIndexForRegister))
		{
			Sleep(500);
		}
		RemoveHook();
		delete[] m_szMyTransfer;
	}
	TlsFree(m_dwTlsIndexForRegister);
	TlsFree(m_dwTlsIndexForRetAdr);
}


//获取hook点现场
ST_REGISTER* CHook::GetRegOnHookPoint()
{
	return (ST_REGISTER*)TlsGetValue(m_dwTlsIndexForRegister);
}

void CHook::Init()
{
//初始化两个Tls变量
	m_dwTlsIndexForRetAdr = TlsAlloc();
	TlsSetValue(m_dwTlsIndexForRetAdr , 0);
	m_dwTlsIndexForRegister = TlsAlloc();
	TlsSetValue(m_dwTlsIndexForRegister , 0);

//初始化“直接返回”的函数体,一字节0xc3
	DWORD dwOld;
	if (!m_szRet)
	{
		m_szRet = new BYTE[1];
		*m_szRet = 0xc3;
		VirtualProtect(m_szRet , 100 , PAGE_EXECUTE_READWRITE , &dwOld);
	}
}

//设置普通hook
BOOL CHook::SetHook( void* pOriginAdr , void* pNewHook )
{
//创建一块内存区域用于存放shellcode
	DWORD dwOld;
	m_szMyTransfer = new BYTE[TRANSFER_FUNC_SIZE];
	memcpy(m_szMyTransfer , m_szTransferFunction , TRANSFER_FUNC_SIZE);
	VirtualProtect(m_szMyTransfer , 100 , PAGE_EXECUTE_READWRITE , &dwOld);
//shellcode中需要修正的位置保存成数组,方便编译
#ifdef _WIN64
	unsigned int szOffset[] = {0x4 , 0x13 , 0x43 , 0x72 , 0x99 , 0xa0 , 0xbf};
#else
	unsigned int szOffset[] = {0x7 , 0xc-1 , 0x13-1 , 0x18 , 0x3a , 0x3f-1 , 0x45-1};
#endif

	BOOL bRet = FALSE;
	HMODULE hMod = GetModuleHandle(_T("Kernel32.dll"));
	FARPROC pFunc_TlsSetValue = GetProcAddress(hMod , "TlsSetValue");

//把hook位置被破坏的指令保存到m_szMyTransfer + szOffset[3]这个地址,中转函数会执行这部分指令
	int dwCodeLen = TransplantCode(pOriginAdr , m_szMyTransfer + szOffset[3]);

//如果允许破坏的空间足够大
	if (dwCodeLen >= JMP_CODE_LEN)
	{
	//保存hook地址
		m_pOrigin_Adr = pOriginAdr;
	//保存破坏的空间大小
		m_nOrigin_CodeLen = dwCodeLen;
	//申请空间,保存被破坏的指令字节
		m_pOldCode = new BYTE[dwCodeLen];
		memcpy(m_pOldCode , pOriginAdr , dwCodeLen);

	//修正shellcode中的各种偏移
		*(DWORD32*)(m_szMyTransfer + szOffset[0]) = m_dwTlsIndexForRegister;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[1]) , (DWORD_PTR)pFunc_TlsSetValue);
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[2]) , (DWORD_PTR)pNewHook);
// 		memcpy((LPVOID)(m_szMyTransfer + szOffset[3]) , (LPVOID)pOriginAdr , dwCodeLen);
		*(DWORD32*)(m_szMyTransfer + szOffset[4]) = m_dwTlsIndexForRegister;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[5]) , (DWORD_PTR)pFunc_TlsSetValue);
		WriteJMP((DWORD_PTR)(m_szMyTransfer + szOffset[6]) , (DWORD_PTR)pOriginAdr + dwCodeLen);
		WriteJMP((DWORD_PTR)pOriginAdr , (DWORD_PTR)m_szMyTransfer);

		bRet = TRUE;
	}
	else
	{
		m_szMyTransfer = 0;
		m_pOrigin_Adr = 0;
		MessageBox(0 , _T("hook点异常,指令无法识别或含有跳转指令") , _T("hook失败") , MB_OK);
	}

	return bRet;
}

BOOL CHook::SetHook( void* pOriginAdr , void* pNewHook , void* pHookAfterCall )
{
//创建一块内存区域用于存放shellcode
	DWORD dwOld;
	m_szMyTransfer = new BYTE[TRANSFER_FUNC_FOR_CALL_SIZE];
	memcpy(m_szMyTransfer , m_szTransferFunction_ForCall , TRANSFER_FUNC_FOR_CALL_SIZE);
	VirtualProtect(m_szMyTransfer , 100 , PAGE_EXECUTE_READWRITE , &dwOld);
//shellcode中需要修正的位置保存成数组,方便编译
#ifdef _WIN64
	unsigned int szOffset[] = {0x4 , 0x11 , 0x2d , 0x3c , 0x6c , 0x9b+4 , 0xc8+4 , 
		0xa8+4 , 0xcc+4 , 0xdb+4 , 0x10b+4 , 0x13a+4 , 0x142+4 , 0x169+4 , 0x170+4};
#else
	unsigned int szOffset[] = {0x5 , 0xa-1 , 0x14 , 0x19-1 , 0x20-1 , 0x26 , 0x48 , 
		0x2a , 0x4f , 0x54-1 , 0x5b-1 , 0x62 , 0x67-1 , 0x72 , 0x77-1};
#endif

	BOOL bRet = FALSE;
	if (!pNewHook && !pHookAfterCall)
	{
		return bRet;
	}

	HMODULE hMod = GetModuleHandle(_T("Kernel32.dll"));
	FARPROC pFunc_TlsSetValue = GetProcAddress(hMod , "TlsSetValue");
	FARPROC pFunc_TlsGetValue = GetProcAddress(hMod , "TlsGetValue");

//用户回调函数分为函数执行前和函数执行后,如果某个回调函数设置为null,则替换为m_szRet这个直接c3返回的函数
	void* pBefore = pNewHook;
	void* pAfter = pHookAfterCall;
	if (!pBefore)
	{
		pBefore = m_szRet;
	}
	if (!pAfter)
	{
		pAfter = m_szRet;
	}

//把hook位置被破坏的指令保存到m_szMyTransfer + szOffset[3]这个地址,中转函数会执行这部分指令
	int dwCodeLen = TransplantCode(pOriginAdr , m_szMyTransfer + szOffset[7]);

//如果允许破坏的空间足够大
	if (dwCodeLen >= JMP_CODE_LEN)
	{
	//保存hook地址
		m_pOrigin_Adr = pOriginAdr;
	//保存破坏的空间大小
		m_nOrigin_CodeLen = dwCodeLen;
	//申请空间,保存被破坏的指令字节
		m_pOldCode = new BYTE[dwCodeLen];
		memcpy(m_pOldCode , pOriginAdr , dwCodeLen);

	//修正shellcode中的各种偏移
		*(DWORD32*)(m_szMyTransfer + szOffset[0]) = m_dwTlsIndexForRetAdr;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[1]) , (DWORD_PTR)pFunc_TlsSetValue);
		*(DWORD32*)(m_szMyTransfer + szOffset[2]) = m_dwTlsIndexForRegister;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[3]) , (DWORD_PTR)pFunc_TlsSetValue);
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[4]) , (DWORD_PTR)pBefore);
#ifdef _WIN64
		BYTE szTmp = *(m_szMyTransfer + szOffset[7]);
		WriteJMP((DWORD_PTR)m_szMyTransfer+szOffset[5] , (DWORD_PTR)m_szMyTransfer+szOffset[6]);
		*(m_szMyTransfer + szOffset[7]) = szTmp;
#else
 		*(DWORD32*)(m_szMyTransfer + szOffset[5]) = (DWORD)m_szMyTransfer+szOffset[6];
#endif
// 		memcpy((LPVOID)(m_szMyTransfer + szOffset[7]) , (LPVOID)pOriginAdr , dwCodeLen);
		WriteJMP((DWORD_PTR)m_szMyTransfer+szOffset[7]+dwCodeLen , (DWORD_PTR)(DWORD_PTR)pOriginAdr + dwCodeLen);
		*(DWORD32*)(m_szMyTransfer + szOffset[8]) = m_dwTlsIndexForRegister;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[9]) , (DWORD_PTR)pFunc_TlsSetValue);
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[10]) , (DWORD_PTR)pAfter);
		*(DWORD32*)(m_szMyTransfer + szOffset[11]) = m_dwTlsIndexForRetAdr;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[12]) , (DWORD_PTR)pFunc_TlsGetValue);
		*(DWORD32*)(m_szMyTransfer + szOffset[13]) = m_dwTlsIndexForRegister;
		WriteCall((DWORD_PTR)(m_szMyTransfer + szOffset[14]) , (DWORD_PTR)pFunc_TlsSetValue);
		WriteJMP((DWORD_PTR)pOriginAdr , (DWORD_PTR)m_szMyTransfer);

		bRet = TRUE;
	}
	else
	{
		m_szMyTransfer = 0;
		m_pOrigin_Adr = 0;
		MessageBox(0 , _T("hook点异常,指令无法识别或含有跳转指令") , _T("hook失败") , MB_OK);
	}

	return bRet;

}

int CHook::TransplantCode( void* pOriginAdr , BYTE* pDestAdr )
{
//初始化bea引擎
	DISASM MyDisasm;
	memset (&MyDisasm, 0, sizeof(DISASM));
#if defined(_WIN64)
	MyDisasm.Archi = 64;
#else
	MyDisasm.Archi = 0;
#endif

//以hook点pOriginAdr开始识别指令
	MyDisasm.EIP = (UIntPtr)pOriginAdr;
	DWORD dwCodeLen = 0;
	while (1)
	{
	//调用Disasm解析指令
		int nLen = Disasm(&MyDisasm);
	//无法识别就滚蛋
		if (nLen == UNKNOWN_OPCODE) 
			break;

	//含有跳转也滚蛋
		if (MyDisasm.Instruction.BranchType == RetType)
			break;

	//记录识别的长度
		dwCodeLen += nLen;

	//迁移当前指令到中转函数的空间中
		memcpy(pDestAdr , (void*)MyDisasm.EIP, nLen);

	//这个判断目前似乎只有x64才会产生作用
	//用于识别类似于mov [eip+xxx],register这样的指令
	//即以eip为原点偏移的指令,jmp其实也是,不过跳转指令在上面已经被pass了
		if (nLen > 4 && MyDisasm.Instruction.AddrValue)
		{
		//计算指令中的偏移数据
			DWORD32* pArg = (DWORD32*)(MyDisasm.EIP + nLen - 4);
		//如果确实是以eip为偏移的指令
			if (*pArg + nLen + MyDisasm.EIP == MyDisasm.Instruction.AddrValue)
			{
			//计算迁移后的实际eip为原点的偏移数据
				DWORD32* pNewArg = (DWORD32*)(pDestAdr + nLen - 4);
			//修正偏移数据
				*pNewArg = MyDisasm.Instruction.AddrValue - nLen - (DWORD_PTR)pDestAdr;
			}
		}

		pDestAdr += nLen;
		MyDisasm.EIP  += nLen;

	//如果空间已经足够就中断
		if (dwCodeLen >= JMP_CODE_LEN)
		{
			break;
		}

	};
	return dwCodeLen;
}

//写jmp的x64版本函数
void CHook::WriteJMP_x64( DWORD_PTR dwFrom , DWORD_PTR dwTo )
{
	DWORD_PTR dwAdr = dwFrom;

	DWORD dwOldP;
	VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);

	*(BYTE*)dwAdr = 0x68;
	dwAdr+=1;
	*(DWORD32*)dwAdr = DWORD32(dwTo & 0xffffffff);
	dwAdr+=4;
	*(DWORD32*)dwAdr = DWORD32(0x042444c7);
	dwAdr+=4;
	*(DWORD32*)dwAdr = DWORD32(dwTo >> 32);
	dwAdr+=4;
	*(BYTE*)dwAdr = 0xc3;
/*
push 地址的低32位
mov dword ptr ss:[rsp+4],地址的高32位
ret
*/

//14 bytes
}

//写call的x64版本函数
void CHook::WriteCall_x64( DWORD_PTR dwFrom , DWORD_PTR dwTo )
{
	DWORD_PTR dwAdr = dwFrom;

	DWORD dwOldP;
	VirtualProtect((LPVOID)dwAdr , 0x100 , PAGE_EXECUTE_READWRITE , &dwOldP);

	*(BYTE*)dwAdr = 0xE8;
	dwAdr+=1;
	*(DWORD*)dwAdr = DWORD32(0);
	dwAdr+=4;
	*(DWORD32*)dwAdr = DWORD32(0x12240483);
	dwAdr+=4;
	*(BYTE*)dwAdr = 0x68;
	dwAdr+=1;
	*(DWORD32*)dwAdr = DWORD32(dwTo & 0xffffffff);
	dwAdr+=4;
	*(DWORD32*)dwAdr = DWORD32(0x042444c7);
	dwAdr+=4;
	*(DWORD32*)dwAdr = DWORD32(dwTo >> 32);
	dwAdr+=4;
	*(BYTE*)dwAdr = 0xc3;
/*
call @next   //e8 00 00 00 00
@next:
add dword ptr ss:[rsp],12
push 地址的低32位
mov dword ptr ss:[rsp+4],地址的高32位
ret
*/

//23 bytes
}

//移除hook的线程
//严格来说,也许应该遍历所有线程,保证没有线程运行到hook位置和中转函数
//然后冻结线程,再移除hook,这样才正规和安全
//然而我不会
DWORD WINAPI RemoveHook_Thread(LPVOID lpParam )
{
	CHook *pHook = (CHook*)lpParam;
//当GetRegOnHookPoint获取hook现场返回0时候,说明基本执行完毕了
	while (pHook->GetRegOnHookPoint())
	{
		Sleep(500);
	}
//正式移除hook
	pHook->RemoveHook_unsafe();
	return 0;
}

BOOL CHook::RemoveHook()
{
	if (TlsGetValue(m_dwTlsIndexForRegister))
	{
		CreateThread(0 , 0 , RemoveHook_Thread , this , 0 , 0);
	}
	else
	{
		RemoveHook_unsafe();
	}
	return TRUE;
}

BOOL CHook::RemoveHook_unsafe()
{
//恢复hook点
	memcpy((LPVOID)m_pOrigin_Adr , (LPVOID)m_pOldCode , m_nOrigin_CodeLen);
//释放保存的指令
	delete[] m_pOldCode;
//释放中转函数
	delete[] m_szMyTransfer;
	return TRUE;
}


apache-atlas-2.1.0-hive-hook.tar.gz是Apache Atlas项目中的一个软件包。Apache Atlas是一个开源的数据治理和元数据框架,用于收集、集成、索引和搜索数据资产。它提供了一个统一的视图来管理企业中的所有数据资产,包括表、列、模式、实体和关系等。而apache-atlas-2.1.0-hive-hook.tar.gz是Atlas项目为了与Hive集成而提供的一个插件。 Hive是一个构建在Hadoop之上的数据仓库基础设施工具,用于处理大规模的结构化数据。它提供了类似于SQL的查询和分析功能,可以将数据批量导入、导出和查询。通过与Apache Atlas的集成,可以实现对Hive中数据资产的元数据管理和治理。 在实际的应用中,apache-atlas-2.1.0-hive-hook.tar.gz可以被部署到Hive的服务器上,并与Hive的插件机制进行集成。通过配置Hive的元数据存储URL、用户名和密码等信息,Atlas可以自动从Hive中提取元数据,并将其索引到Atlas的元数据仓库中。这样,用户可以在Atlas的界面中浏览和搜索Hive中的表、列和关系,并进行数据资产的管理和治理。 此外,apache-atlas-2.1.0-hive-hook.tar.gz还提供了一些其他功能,如基于分类标签的权限控制、数据血缘追踪、数据脱敏等。通过这些功能,用户可以更好地理解和管理Hive中的数据资产,提高数据治理的效率和质量。 总之,apache-atlas-2.1.0-hive-hook.tar.gz是Apache Atlas项目中用于与Hive集成的插件,通过它可以实现对Hive中数据资产的元数据管理和数据治理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值