x64 Theory Help?

closed account (G309216C)
Hi,

I have successfully jumped code segments in order to switch architecture during run-time.This means I only have use of ntdll.dll after switching architecture thus making me only stuck in using Native functions and exporting x64 bit function using a custom made function then using typedef in order to assign a new function exactly same as the native functions.

This is least of my worries, I have exported:
GetModuleHandle using x86 version of GetModuleHandle, but it looks for the module name in the list of loaded x64 libraries. Usually x86 processes under WOW64
layer have four x64 libraries: ntdll.dll, wow64.dll, wow64cpu.dll and wow64win.dll

GetProcAddress internally it uses x64 version of LdrGetProcedureAddress() from NTDLL.

VirtualQueryEx internally it uses x64 version of NtQueryVirtualMemory() from NTDLL.

VirtualAllocEx internally it uses x64 version of NtAllocateVirtualMemory() from NTDLL.

VirtualFreeEx internally it uses x64 version of NtFreeVirtualMemory() from NTDLL.

ReadProcessMemory internally it uses x64 version of NtReadVirtualMemory() from NTDLL.

WriteProcessMemory internally it uses x64 version of NtWriteVirtualMemory() from NTDLL.

CreateRemoteThread internally it uses x64 version of NtCreateThreadEx() & NtCreateThread() from NTDLL.


As you may notice I got all my functions exported needed for Code Injection and DLL injection but the thing is I do not know about how NT functions for x64 look like. I made this hook but it only works for x86 rather than x64:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef NTSTATUS (NTAPI *szZwResumeThread)(IN HANDLE ThreadHandle, OUT PULONG SuspendCount);
typedef NTSTATUS (NTAPI *vZwClose)(IN HANDLE ClHandle);
szZwResumeThread oldZwResumeThread;
int HookNTfunction(__in LPVOID szKernelFunction, __in LPVOID szNewFunction, __out LPVOID* szOldStb) {

	if ( *(BYTE*)(szKernelFunction) != 0xB8  )
		return -2;

	DWORD  szOldRights = 0;
	LPVOID szStubTemp  = VirtualAlloc(0, 1024, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
	
	if ( szStubTemp == 0 ){return -3;}

	if ( VirtualProtect(szKernelFunction, 5, PAGE_EXECUTE_READWRITE, &szOldRights) == 0 ){VirtualFree(szStubTemp, 0, MEM_RELEASE);return -4;}

	
	*(BYTE*)(szStubTemp)                   = 0xB8; 
	*(DWORD*)((LPBYTE)szStubTemp + 1)      = *(DWORD*)((LPBYTE)szNewFunction + 1);
	*(BYTE*)((LPBYTE)szStubTemp +  5)      = 0x68;
	*(DWORD*)((LPBYTE)szStubTemp + 6)      = (DWORD)( (LPBYTE)szKernelFunction + 5 );
	*(BYTE*)((LPBYTE)szStubTemp +  10)     = 0xC3;
	*(BYTE*)(szKernelFunction)              = 0xE9;
	*(DWORD*)((LPBYTE)szKernelFunction + 1) = ( (DWORD)szNewFunction - ((DWORD)szKernelFunction + 5) );	
	VirtualProtect(szKernelFunction, 5, szOldRights, &szOldRights);
	*szOldStb = szStubTemp;
	return 0L; //ERROR_SUCCESS 
}


You may notice I am hooking ZwResumeThread() but it is a Ring0 function but on Usermode ZW and NT functions lie in the same memory location thus hooking ZW gives us more power and we can get the input and output directly from the lowest level in Ring3 aka Ntdll.KiSystemFastCall.

Back on question, the above code only works on x86 but when I try this on x64 bit application nothing happens. Does anyone know how x64 functions can be hooked. I do not want to use libraries; I need only a function to hook NT function as when performing x64 code injection after passing through code segment change it becomes impossible to redirect EIP to any functions without changing that too into x64 as well thus hooking it directly without using a function would be easier as I do not need to change two functions into x64.

I just need someone tell me how NT functions look like on x64. If you are nice can someone answer me if the x64 NT functions have Hot-patch Prologue or is it like x86 bit NT functions which does not have Hot-Patch Prologue.

THANKS IN ADVANCE!

p.s:
Can someone with decent knowledge with WinAPI functions answer my question because last time some on here (not naming their name) feed-ed me wrong information, which caused the Windows to delete few system files.


closed account (G309216C)
Anyone have a slight clue regarding my question.
Hi,
I see You still put relative 32-bit jump instruction at the begin of hooked function:

1
2
db 0e9h ; jmp $ + delta - 5
dd delta


On x64 You need rather absolute 64-bit unconditional jump.
Something like that:

1
2
3
 db 49h 0bbh        ; movq r11, <absolute 64-bit address>
 dq value           ;
 db 41h 0ffh 0e3h   ; jmp qword ptr [r11]


Hook code in C may looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
//
// orygEntry = 64-bit pointer to original entry point
// newEntry = 64-bit pointer to our function, which we want to be called
//

  orygEntry[0] = 0x49;
  orygEntry[1] = 0xBB;

  memcpy(orygEntry + 2, &newEntry, 8);
  
  orygEntry[10] = 0x41;
  orygEntry[11] = 0xff;
  orygEntry[12] = 0xe3;


Did You try it?
Last edited on
closed account (G309216C)
Hi,

I have not yet tried but what is the size of JMP size in x64 mode, in x86 the size is 5 bytes therefore allocating 5 bytes in target function is enough whereas I do not know how much space I need to allocate in Target Function x64.

Thanks!
Please look at code above - You can calculate it by own:

1
2
3
4
 db 49h 0bbh        ; movq r11, <absolute 64-bit address> = 2 x 1 byte
 dq value           ;                                     = 1 x 8 bytes 
 db 41h 0ffh 0e3h   ; jmp qword ptr [r11]                 = 3 x 1 byte
                    ;                             total   = 13 bytes


So, in x64 You need 13 bytes.
Last edited on
closed account (G309216C)
Hi,

This is all I needed thanks , I will get started and if any help occurs I will PM you.

Topic archived. No new replies allowed.