Skip to content

Instantly share code, notes, and snippets.

@Little-Ki
Last active October 25, 2020 03:18
Show Gist options
  • Select an option

  • Save Little-Ki/c841eff8eac9f63d18c12d1d2e64c2d9 to your computer and use it in GitHub Desktop.

Select an option

Save Little-Ki/c841eff8eac9f63d18c12d1d2e64c2d9 to your computer and use it in GitHub Desktop.
[Code] [Kernel] Bypass process, thread and image load notify routines
// When you tried to create thread in process, the anti cheat will detect it, the one reason is it uses PsSetCreateThreadNotifyRoutine.
// Then ac uses PsSetLoadImageNotifyRoutine to block loading of blacklisted drivers.
// PsSetLoadImageNotifyRoutine is not being used to block DLL injection.
// However, we can bypass both of these notifications by modifying a kernel variable: PspNotifyEnableMask. Why?
// PspCallThreadNotifyRoutines is a kernel function, this function iterating the installed notification routines and calling them.
// By analysis it in IDA, we can find a symbol named PspNotifyEnableMask, just fill it with zero will skip calling of any notification routines.
// But it's not clean way to do it and will also block process creation routines which is not a good thing (any process you start when PsSetCreateProcessNotifyRoutine is bypassed will not have ability to connect to internet).
// By look at function PsSetCreateThreadNotifyRoutine itself, we will see:
// _interlockedbittestandset((volatile signed __int32 *)&PspNotifyEnableMask, 4u);
// _interlockedbittestandset((volatile signed __int32 *)&PspNotifyEnableMask, 3u);
// This function will set target bit to 1.
// By setting bits 3 and 4 to 0 Windows thinks there are no thread creation notify routines installed and simply skips them.
// Now take a look at PsSetLoadImageNotifyRoutine and you will see this:
// _interlockedbittestandset((volatile signed __int32 *)&PspNotifyEnableMask, 0);
// By setting the bit 0 we can disable loadimage notifications. If you want to disable createprocess notifications, modify bits 1 & 2.
// 0 = LoadImage
// 1-2 = CreateProcess
// 3-4 = CreateThread
// PspNotifyEnableMask is not exported, just using AOB scan we can find it.
ULONG64 GetNotifyVarAddress()
{
ULONG64 i = 0;
PULONG64 pAddrOfFnc = 0;
UNICODE_STRING fncName;
RtlInitUnicodeString( &fncName, L"PsSetLoadImageNotifyRoutine" );
ULONG64 fncAddr = (ULONG64) MmGetSystemRoutineAddress( &fncName );
if ( fncAddr )
{
fncAddr += 0x50;
for ( i = fncAddr; i < fncAddr + 0x15; i++ )
{
if ( *(UCHAR *) i == 0x8B && *(UCHAR *) (i + 1) == 0x05 )
{
LONG OffsetAddr = 0;
memcpy( &OffsetAddr, (UCHAR *) (i + 2), 4 );
pAddrOfFnc = (ULONG64 *) (OffsetAddr + i + 0x6);
break;
}
}
return (ULONG64) pAddrOfFnc;
}
return 0;
}
// End: You can now load blacklisted drivers (WIN64AST for example) and create threads inside the game (as long as you have a handle).
// However please remember drivers and threads can be enumerated afterwards so simply getting rid of the notifications is not very useful. This method is patchguard safe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment