A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about user-mode development.
 #10572  by __fastcall
 Sat Dec 24, 2011 7:20 pm
I'm using this code bellow to write a jmp and detour my functions and its working like a charm. But how do i need to modify the code to get it working under x64 ?
Code: Select all
DWORD cHook::HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);
	BYTE jmp[5] = { 0xe9,	//jmp
		0x00, 0x00, 0x00, 0x00//,	//address
		//0xc3
	};	//retn

	ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 5, 0);

	DWORD dwCalc = ((DWORD)lpFunction - dwAddr - 5);	//((to)-(from)-5)

	memcpy(&jmp[1], &dwCalc, 4);	//build the jmp

	WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 5, 0);

	return dwAddr;
}

BOOL cHook::UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);

	if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 5, 0))
		return TRUE;

	return FALSE;
}
My Port ( not working -.-' )
Code: Select all
DWORD cHook::HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);
	BYTE jmp[10] = { 0xe9,	//jmp
		0x00, 0x00, 0x00, 0x00 ,
		0x00 , 0x00 , 0x00 , 0x00 ,//,	//8byte address
		0xc3
	};	

	ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 9, 0);

	DWORD64 dwCalc = ((DWORD)lpFunction - dwAddr - 10);	//((to)-(from)-9)

	memcpy(&jmp[1], &dwCalc, 8);	//build the jmp

	WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 10, 0);

	return dwAddr;
}

BOOL cHook::UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);

	if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 10, 0))
		return TRUE;

	return FALSE;
}
 #10574  by xdeadcode
 Sun Dec 25, 2011 12:04 am
Hi,

During porting code from x86 to x64 you have to be careful with checking all types, e.g
function:
Code: Select all
FARPROC WINAPI GetProcAddress(
  __in  HMODULE hModule,
  __in  LPCSTR lpProcName
);
is using following type FARPROC as return type, It's definition you can find in windef.h header file.
Code: Select all
#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();
typedef INT_PTR (NEAR WINAPI *NEARPROC)();
typedef INT_PTR (WINAPI *PROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
typedef int (NEAR WINAPI *NEARPROC)();
typedef int (WINAPI *PROC)();
#endif  // _WIN64
You have to be familiar with types like ULONG_PTR, PULONG and so on.
Update your code to check GetProcAddress against null. Is it actually returning something in dwAddr? (In this particular case I assume it is not).
 #10575  by __fastcall
 Sun Dec 25, 2011 1:37 am
My function has changed opcode and now im going to get the dwAddr value.
Code: Select all
DWORD cHook::HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);
	BYTE jmp[14] = { 
		0xFF, 0x25 , //JMP [0x00+RIP];
		0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 // address
		};	

	ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 14, 0);

	DWORD64 dwCalc = ((DWORD)lpFunction - dwAddr - 14);	//((to)-(from)-9)

	memcpy(&jmp[6], &dwCalc, 8);	//build the jmp

	WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 14, 0);

	return dwAddr;
}

BOOL cHook::UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup)
{
	DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandleA(lpModule), lpFuncName);

	if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 14, 0))
		return TRUE;

	return FALSE;
}

I've checked with
Code: Select all
if (dwAddr == NULL)
	{
		MessageBoxA(0 , "Call failed." , "" , 64 );
	}
wether the GetProcAddress call fails but it doesn't show the MessageBox, so dwAddr should be the Address i wanna jump too.
 #10600  by EP_X0FF
 Mon Dec 26, 2011 3:18 pm
Refer to xdeadcode post for solution. Your code is incorrect and your assumptions are wrong.

Pointers are pointers, DWORD's are DWORD's. Feel the difference first.
 #10627  by __fastcall
 Wed Dec 28, 2011 2:00 am
EP_X0FF wrote:Refer to xdeadcode post for solution. Your code is incorrect and your assumptions are wrong.

Pointers are pointers, DWORD's are DWORD's. Feel the difference first.
ok i will do my best.