首页
社区
课程
招聘
[旧帖] 关于X64下的EAT hook 0.00雪花
发表于: 2013-5-22 00:35 5526

[旧帖] 关于X64下的EAT hook 0.00雪花

2013-5-22 00:35
5526
对一个64位的程序的kernelbase.dll的某函数做eat hook,地址偏移如何计算啊?
代码如下,编译为x64,程序crash,环境win7 x64
BOOL Set_EAT_Hook(LPCWSTR lpModuleName,LPCSTR lpFuncName,LPVOID lpHookFunction,LPVOID* lpTrueFunction)
{
	__try
	{
		LPVOID pBase = NULL;
		pBase = GetModuleHandleW(lpModuleName);
		if (NULL == pBase)
		{
			pBase = LoadLibraryW(lpModuleName);
			if (NULL == pBase)
			{
				return FALSE;
			}
		}
		PIMAGE_DOS_HEADER pDosHeader = NULL;
		PIMAGE_NT_HEADERS pNtHeader = NULL;
		PIMAGE_OPTIONAL_HEADER pOpHeader = NULL;
		PIMAGE_EXPORT_DIRECTORY pExportDes = NULL;
		pDosHeader = (PIMAGE_DOS_HEADER)pBase;
		if (IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
		{
			return FALSE;
		}
		pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pBase + pDosHeader->e_lfanew);
		if (IMAGE_NT_SIGNATURE != pNtHeader->Signature)
		{
			return FALSE;
		}
		pOpHeader = (PIMAGE_OPTIONAL_HEADER)(&pNtHeader->OptionalHeader);
		if (NULL == pOpHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
			|| 0 == pOpHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
		{
			return FALSE;
		}
		pExportDes = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)pBase + pOpHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
		PUCHAR pFuncName = NULL;
		PULONG pAddressOfFunctions = (PULONG)((PBYTE)pBase + pExportDes->AddressOfFunctions); 
		PULONG pAddressOfNames = (PULONG)((PBYTE)pBase + pExportDes->AddressOfNames); 
		//pExportDes->AddressOfNameOrdinals是一个DWORD的数值,指向一个word类型的数值
		PUSHORT pAddressOfNameOrdinals = (PUSHORT)((PBYTE)pBase + pExportDes->AddressOfNameOrdinals); 

		ULONG uMax = pExportDes->NumberOfNames;
		for (ULONG uLoop = 0; uLoop <uMax;  uLoop++)
		{
			USHORT index = pAddressOfNameOrdinals[uLoop];//得到在ENT里面的索引
			pFuncName = (PUCHAR)( (PBYTE)pBase + pAddressOfNames[uLoop]);//函数名字
			if(!_stricmp((const char*)pFuncName,lpFuncName))
			{
				//取函数地址的防范跟函数名字不一样
				LPVOID lpOldAddr = (LPVOID)((PBYTE)pBase + pAddressOfFunctions[index]);
				*lpTrueFunction = lpOldAddr;
				MEMORY_BASIC_INFORMATION mbi;
				RtlZeroMemory(&mbi,sizeof(MEMORY_BASIC_INFORMATION));
				VirtualQueryEx(GetCurrentProcess(),&pAddressOfFunctions[index],&mbi,sizeof(MEMORY_BASIC_INFORMATION));
				VirtualProtectEx(GetCurrentProcess(),mbi.BaseAddress,mbi.RegionSize,PAGE_READWRITE,&mbi.Protect);
				pAddressOfFunctions[index] = (ULONG)((PBYTE)lpHookFunction - (PBYTE)pBase);//这个在X64下,好像差值超过一个dword的大小,怎么办
				ULONG uOldProtect;
				VirtualProtectEx(GetCurrentProcess(),mbi.BaseAddress,mbi.RegionSize,mbi.Protect,&uOldProtect);
				break;
			}
		}
		return TRUE;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		DWORD DwException = GetExceptionCode();
		WCHAR szDbg[MAX_PATH] = {0};
		swprintf_s(szDbg,L"EATHook except code = 0x%08lx\n",DwException);
		OutputDebugStringW(szDbg);
		return FALSE;
	}
}

typedef BOOL (WINAPI* P_GetVersionExW)(
				 _Inout_  LPOSVERSIONINFOW lpVersionInfo
				 );

P_GetVersionExW g_pGetVersionExW = NULL;

BOOL WINAPI Fake_GetVersionExW(
				       _Inout_  LPOSVERSIONINFOW lpVersionInfo
				       )
{
	OutputDebugStringW(L"Fake_GetVersionExW\r\n"); 
	return g_pGetVersionExW(lpVersionInfo);
}

int _tmain(int argc, _TCHAR* argv[])
{
	BOOL bRet4 = Set_EAT_Hook(L"kernelbase.dll","GetVersionExW",Fake_GetVersionExW,(LPVOID*)&g_pGetVersionExW);
	P_GetVersionExW pVer = (P_GetVersionExW)GetProcAddress(GetModuleHandleW(L"kernelbase.dll"),"GetVersionExW");
	OSVERSIONINFOW osvi;
	ZeroMemory(&osvi, sizeof(OSVERSIONINFOW));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
	pVer(&osvi);
	return 0;
}


pAddressOfFunctions[index] = (ULONG)((PBYTE)lpHookFunction - (PBYTE)pBase);
这个在X64下,好像差值超过一个dword的大小,怎么办

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 778
活跃值: (208)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
2
你把你程序的加载基址设置高一点不就行了,就算kernelbase.dll再大,也不可能超过一个DWORD,如果你不是kernelbase.dll模块,可能就会差点
2013-5-22 08:46
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
什么意思,要是注入到别人的进程,怎么改基址?
2013-5-22 09:48
0
雪    币: 778
活跃值: (208)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
4
就是在编译器里面设置啊,把基址设置成和你要HOOK的DLL差不多地址,这样你的HOOK函数一个DWORD就够了。
或者你把HOOK函数的二进制提取出来,直接在DLL的附近分配一块内存,使DLL的基址和你分配的基址之间的偏移不大于一个DWORD.
2013-5-22 11:04
0
雪    币: 778
活跃值: (208)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
5
使用inline钩子的话,完全不用担心这个问题
2013-5-22 11:13
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我就是自己写着玩玩EAT HOOK
2013-5-22 12:22
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
大牛们呢,sos 啊~~
2013-5-25 12:48
0
雪    币: 11
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2013-6-4 13:56
0
游客
登录 | 注册 方可回帖
返回
//