Exetools  

Go Back   Exetools > General > Source Code

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 05-01-2026, 01:46
HarrySpoofer HarrySpoofer is offline
Friend
 
Join Date: Jul 2018
Posts: 47
Rept. Given: 0
Rept. Rcvd 5 Times in 3 Posts
Thanks Given: 10
Thanks Rcvd at 50 Times in 19 Posts
HarrySpoofer Reputation: 5
EXE to JPEG obfuscator

This is my MSVC source code that has never been posted anywhere else before.

It is a C code for a binary to JPEG file converter/obfuscator.

I find it useful to smuggle binary files (especially executable files) to various AI LLMs that do not allow binary file uploads but have no problem with uploads of JPEG files.
This is also useful for smuggling executable files past restrictive email attachment scanners.

After an executable file is obfuscated as a valid JPEG file and uploaded, it can get past the filters implemented by the control-freaks, tyrants and paranoid admins. Next, the AI LLM can be instructed to convert it back into an executable file, for e.g.: binary analysis and disassembly, which some AI LLMs are quite adept at.

Code:
#include stdio.h  //missing angle brackets (because exetools strips them)
#include stdlib.h //missing angle brackets (because exetools strips them)
#include string.h //missing angle brackets (because exetools strips them)
#include math.h //missing angle brackets (because exetools strips them)
#include tchar.h //missing angle brackets (because exetools strips them)
#include windows.h //missing angle brackets (because exetools strips them)

#define JPEG_SOI 0xFFD8
#define JPEG_APP0 0xFFE0
#define JPEG_DQT 0xFFDB
#define JPEG_SOF0 0xFFC0
#define JPEG_DHT 0xFFC4
#define JPEG_SOS 0xFFDA
#define JPEG_EOI 0xFFD9

// Hidden flag values in JFIF thumbnail width
#define FLAG_STANDARD 0  // Byte stuffing applied
#define FLAG_RAW 1       // Raw mode, no byte stuffing

typedef struct {
    HANDLE hFile;
    DWORD dwPos;
} FileContext;

BOOL WriteBytes(FileContext* ctx, const void* data, DWORD size) {
    DWORD written;
    if (!WriteFile(ctx->hFile, data, size, &written, NULL) || written != size) {
        return FALSE;
    }
    ctx->dwPos += written;
    return TRUE;
}

BOOL WriteByte(FileContext* ctx, unsigned char value) {
    return WriteBytes(ctx, &value, 1);
}

BOOL WriteBE16(FileContext* ctx, unsigned short value) {
    unsigned char bytes[2] = { (value >> 8) & 0xFF, value & 0xFF };
    return WriteBytes(ctx, bytes, 2);
}

BOOL WriteJFIFHeader(FileContext* ctx, int mode_flag) {
    if (!WriteBE16(ctx, JPEG_APP0)) return FALSE;
    if (!WriteBE16(ctx, 16)) return FALSE;
    if (!WriteBytes(ctx, "JFIF\0", 5)) return FALSE;
    if (!WriteByte(ctx, 1)) return FALSE; // Version 1
    if (!WriteByte(ctx, 1)) return FALSE; // Version 1
    if (!WriteByte(ctx, 1)) return FALSE; // Density units (dots per inch)
    if (!WriteBE16(ctx, 96)) return FALSE; // X density 96 DPI
    if (!WriteBE16(ctx, 96)) return FALSE; // Y density 96 DPI
    if (!WriteByte(ctx, mode_flag)) return FALSE; // Thumbnail width - HIDDEN FLAG
    if (!WriteByte(ctx, 0)) return FALSE; // Thumbnail height
    return TRUE;
}

BOOL WriteDQT(FileContext* ctx) {
    unsigned char lum_table[64] = {
        2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 5,
        3, 3, 3, 3, 3, 6, 4, 4, 3, 5, 7, 6, 7, 7, 7, 6,
        7, 7, 8, 9, 11, 9, 8, 8, 10, 8, 7, 7, 10, 13, 10, 10,
        11, 12, 12, 12, 12, 7, 9, 14, 15, 13, 12, 14, 11, 12, 12, 12
    };

    unsigned char chr_table[64] = {
        2, 2, 2, 3, 3, 3, 6, 3, 3, 6, 12, 8, 7, 8, 12, 12,
        12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
        12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
        12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
    };

    // Luminance
    if (!WriteBE16(ctx, JPEG_DQT)) return FALSE;
    if (!WriteBE16(ctx, 67)) return FALSE;
    if (!WriteByte(ctx, 0)) return FALSE;
    if (!WriteBytes(ctx, lum_table, 64)) return FALSE;

    // Chrominance
    if (!WriteBE16(ctx, JPEG_DQT)) return FALSE;
    if (!WriteBE16(ctx, 67)) return FALSE;
    if (!WriteByte(ctx, 1)) return FALSE;
    if (!WriteBytes(ctx, chr_table, 64)) return FALSE;

    return TRUE;
}

BOOL WriteSOF0(FileContext* ctx, int width, int height) {
    if (!WriteBE16(ctx, JPEG_SOF0)) return FALSE;
    if (!WriteBE16(ctx, 17)) return FALSE;
    if (!WriteByte(ctx, 8)) return FALSE;
    if (!WriteBE16(ctx, height)) return FALSE;
    if (!WriteBE16(ctx, width)) return FALSE;
    if (!WriteByte(ctx, 3)) return FALSE;

    if (!WriteByte(ctx, 1)) return FALSE;
    if (!WriteByte(ctx, 0x22)) return FALSE;
    if (!WriteByte(ctx, 0)) return FALSE; // Y: 2x2 subsampling

    if (!WriteByte(ctx, 2)) return FALSE;
    if (!WriteByte(ctx, 0x11)) return FALSE;
    if (!WriteByte(ctx, 1)) return FALSE; // Cb: 1x1 subsampling

    if (!WriteByte(ctx, 3)) return FALSE;
    if (!WriteByte(ctx, 0x11)) return FALSE;
    if (!WriteByte(ctx, 1)) return FALSE; // Cr: 1x1 subsampling

    return TRUE;
}

BOOL WriteDHT_DC(FileContext* ctx, int table_id) {
    unsigned char bits[16] = { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
    unsigned char vals[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    if (!WriteBE16(ctx, JPEG_DHT)) return FALSE;
    if (!WriteBE16(ctx, 31)) return FALSE;
    if (!WriteByte(ctx, table_id)) return FALSE;
    if (!WriteBytes(ctx, bits, 16)) return FALSE;
    if (!WriteBytes(ctx, vals, 12)) return FALSE;

    return TRUE;
}

BOOL WriteDHT_AC_Lum(FileContext* ctx) {
    unsigned char bits[16] = { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
    unsigned char vals[] = {
        0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
        0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
        0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
        0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
        0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
        0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
        0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
        0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
        0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
        0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
        0xf9, 0xfa
    };

    if (!WriteBE16(ctx, JPEG_DHT)) return FALSE;
    if (!WriteBE16(ctx, 181)) return FALSE;
    if (!WriteByte(ctx, 0x10)) return FALSE; // AC table 0
    if (!WriteBytes(ctx, bits, 16)) return FALSE;
    if (!WriteBytes(ctx, vals, 162)) return FALSE;

    return TRUE;
}

BOOL WriteDHT_AC_Chr(FileContext* ctx) {
    unsigned char bits[16] = { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
    unsigned char vals[] = {
        0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
        0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
        0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
        0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
        0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
        0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
        0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
        0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
        0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
        0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
        0xf9, 0xfa
    };

    if (!WriteBE16(ctx, JPEG_DHT)) return FALSE;
    if (!WriteBE16(ctx, 181)) return FALSE;
    if (!WriteByte(ctx, 0x11)) return FALSE; // AC table 1
    if (!WriteBytes(ctx, bits, 16)) return FALSE;
    if (!WriteBytes(ctx, vals, 162)) return FALSE;

    return TRUE;
}

BOOL WriteSOS(FileContext* ctx) {
    if (!WriteBE16(ctx, JPEG_SOS)) return FALSE;
    if (!WriteBE16(ctx, 12)) return FALSE;
    if (!WriteByte(ctx, 3)) return FALSE;

    if (!WriteByte(ctx, 1)) return FALSE;
    if (!WriteByte(ctx, 0x00)) return FALSE;

    if (!WriteByte(ctx, 2)) return FALSE;
    if (!WriteByte(ctx, 0x11)) return FALSE;

    if (!WriteByte(ctx, 3)) return FALSE;
    if (!WriteByte(ctx, 0x11)) return FALSE;

    if (!WriteByte(ctx, 0)) return FALSE;
    if (!WriteByte(ctx, 63)) return FALSE;
    if (!WriteByte(ctx, 0)) return FALSE;

    return TRUE;
}

DWORD WriteStuffedData(FileContext* ctx, unsigned char* data, DWORD size) {
    DWORD stuffed_size = 0;
    for (DWORD i = 0; i < size; i++) {
        if (!WriteByte(ctx, data[i])) return 0;
        stuffed_size++;
        if (data[i] == 0xFF) {
            if (!WriteByte(ctx, 0x00)) return 0;
            stuffed_size++;
        }
    }
    return stuffed_size;
}

void ReverseBuffer(unsigned char* buf, DWORD len) {
    unsigned char* left = buf;
    unsigned char* right = buf + len - 1;

    while (left < right) {
        *left ^= *right;
        *right ^= *left;
        *left ^= *right;
        left++;
        right--;
    }
}

BOOL ReadBE16(HANDLE hFile, unsigned short* value) {
    unsigned char bytes[2];
    DWORD read;
    if (!ReadFile(hFile, bytes, 2, &read, NULL) || read != 2) {
        return FALSE;
    }
    *value = (bytes[0] << 8) | bytes[1];
    return TRUE;
}

BOOL FindJFIFFlag(HANDLE hFile, int* flag, int force_raw) {
    LARGE_INTEGER pos;
    pos.QuadPart = 0;
    SetFilePointerEx(hFile, pos, NULL, FILE_BEGIN);

    unsigned short marker;
    if (!ReadBE16(hFile, &marker) || marker != JPEG_SOI) {
        return FALSE;
    }

    if (!ReadBE16(hFile, &marker) || marker != JPEG_APP0) {
        return FALSE;
    }

    unsigned short length;
    if (!ReadBE16(hFile, &length)) {
        return FALSE;
    }

    char jfif[5];
    DWORD read;
    if (!ReadFile(hFile, jfif, 5, &read, NULL) || read != 5) {
        return FALSE;
    }

    if (memcmp(jfif, "JFIF\0", 5) != 0) {
        return FALSE;
    }

    // Skip version (2 bytes), units (1 byte), densities (4 bytes)
    pos.QuadPart = 7;
    SetFilePointerEx(hFile, pos, NULL, FILE_CURRENT);

    unsigned char thumbnail_width;
    if (!ReadFile(hFile, &thumbnail_width, 1, &read, NULL) || read != 1) {
        return FALSE;
    }

    if (force_raw) {
        *flag = FLAG_RAW;
    }
    else {
        *flag = (thumbnail_width == FLAG_RAW) ? FLAG_RAW : FLAG_STANDARD;
    }

    return TRUE;
}

BOOL FindSOSOffset(HANDLE hFile, DWORD* sos_data_offset) {
    LARGE_INTEGER pos;
    pos.QuadPart = 2; // Skip SOI
    SetFilePointerEx(hFile, pos, NULL, FILE_BEGIN);

    unsigned short marker, length;
    while (ReadBE16(hFile, &marker)) {
        if (marker == JPEG_SOS) {
            if (!ReadBE16(hFile, &length)) return FALSE;
            // Skip SOS header
            pos.QuadPart = length - 2;
            SetFilePointerEx(hFile, pos, NULL, FILE_CURRENT);

            // Current position is start of scan data
            pos.QuadPart = 0;
            SetFilePointerEx(hFile, pos, &pos, FILE_CURRENT);
            *sos_data_offset = (DWORD)pos.QuadPart;
            return TRUE;
        }

        if (marker == JPEG_EOI || marker < 0xFF00) {
            return FALSE;
        }

        if (!ReadBE16(hFile, &length)) return FALSE;
        pos.QuadPart = length - 2;
        SetFilePointerEx(hFile, pos, NULL, FILE_CURRENT);
    }

    return FALSE;
}

BOOL FindEOIOffset(HANDLE hFile, DWORD* eoi_offset) {
    DWORD fileSize = GetFileSize(hFile, NULL);
    if (fileSize == INVALID_FILE_SIZE) return FALSE;

    if (fileSize < 2) return FALSE;

    LARGE_INTEGER pos;
    pos.QuadPart = fileSize - 2;
    SetFilePointerEx(hFile, pos, NULL, FILE_BEGIN);

    unsigned short marker;
    if (!ReadBE16(hFile, &marker) || marker != JPEG_EOI) {
        return FALSE;
    }

    *eoi_offset = fileSize - 2;
    return TRUE;
}

DWORD UnstuffData(unsigned char* stuffed, DWORD stuffed_size, unsigned char** unstuffed) {
    *unstuffed = (unsigned char*)malloc(stuffed_size);
    if (*unstuffed == NULL) return 0;

    DWORD out_pos = 0;
    for (DWORD i = 0; i < stuffed_size; i++) {
        (*unstuffed)[out_pos++] = stuffed[i];
        if (stuffed[i] == 0xFF && i + 1 < stuffed_size && stuffed[i + 1] == 0x00) {
            i++; // Skip the 0x00
        }
    }

    return out_pos;
}

int UnpackJPEG(LPCTSTR input_file, LPCTSTR output_file, int force_raw) {
    HANDLE hInput = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hInput == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Error: Could not open input file '%s'\n"), input_file);
        return 1;
    }

    int mode_flag;
    if (!FindJFIFFlag(hInput, &mode_flag, force_raw)) {
        _tprintf(_T("Error: Invalid JPEG file or missing JFIF header\n"));
        CloseHandle(hInput);
        return 1;
    }

    DWORD sos_offset, eoi_offset;
    if (!FindSOSOffset(hInput, &sos_offset)) {
        _tprintf(_T("Error: Could not find SOS marker\n"));
        CloseHandle(hInput);
        return 1;
    }

    if (!FindEOIOffset(hInput, &eoi_offset)) {
        _tprintf(_T("Error: Could not find EOI marker\n"));
        CloseHandle(hInput);
        return 1;
    }

    DWORD data_size = eoi_offset - sos_offset;
    if (data_size == 0) {
        _tprintf(_T("Error: No data found between SOS and EOI\n"));
        CloseHandle(hInput);
        return 1;
    }

    unsigned char* data_buffer = (unsigned char*)malloc(data_size);
    if (data_buffer == NULL) {
        _tprintf(_T("Error: Memory allocation failed\n"));
        CloseHandle(hInput);
        return 1;
    }

    LARGE_INTEGER pos;
    pos.QuadPart = sos_offset;
    SetFilePointerEx(hInput, pos, NULL, FILE_BEGIN);

    DWORD bytes_read;
    if (!ReadFile(hInput, data_buffer, data_size, &bytes_read, NULL) || bytes_read != data_size) {
        _tprintf(_T("Error: Failed to read scan data\n"));
        free(data_buffer);
        CloseHandle(hInput);
        return 1;
    }

    CloseHandle(hInput);

    unsigned char* final_data;
    DWORD final_size;

    if (mode_flag == FLAG_RAW) {
        final_data = data_buffer;
        final_size = data_size;
        _tprintf(_T("Mode detected: RAW (no byte stuffing)\n"));
    }
    else {
        _tprintf(_T("Mode detected: STANDARD (with byte stuffing)\n"));
        final_size = UnstuffData(data_buffer, data_size, &final_data);
        free(data_buffer);
        if (final_size == 0) {
            _tprintf(_T("Error: Unstuffing failed\n"));
            return 1;
        }
    }

    // Decrypt
    for (DWORD i = 0; i < final_size; i++) {
        final_data[i] -= 0x55;
    }

    // Reverse
    ReverseBuffer(final_data, final_size);

    HANDLE hOutput = CreateFile(output_file, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hOutput == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Error: Could not create output file '%s'\n"), output_file);
        free(final_data);
        return 1;
    }

    DWORD written;
    if (!WriteFile(hOutput, final_data, final_size, &written, NULL) || written != final_size) {
        _tprintf(_T("Error: Failed to write output file\n"));
        CloseHandle(hOutput);
        free(final_data);
        return 1;
    }

    CloseHandle(hOutput);
    free(final_data);

    _tprintf(_T("Successfully extracted binary data to: %s\n"), output_file);
    _tprintf(_T("Extracted data size: %lu bytes\n"), final_size);
    _tprintf(_T("SOS data offset: 0x%08lX (%lu)\n"), sos_offset, sos_offset);
    _tprintf(_T("EOI marker offset: 0x%08lX (%lu)\n"), eoi_offset, eoi_offset);

    return 0;
}

int PackToJPEG(LPCTSTR input_file, LPCTSTR output_file, int use_raw_mode) {
    HANDLE hInput = CreateFile(input_file, GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hInput == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Error: Could not open input file '%s'\n"), input_file);
        return 1;
    }

    DWORD input_size = GetFileSize(hInput, NULL);
    if (input_size == INVALID_FILE_SIZE || input_size == 0) {
        _tprintf(_T("Error: Invalid input file size\n"));
        CloseHandle(hInput);
        return 1;
    }

    unsigned char* buffer = (unsigned char*)malloc(input_size);
    if (buffer == NULL) {
        _tprintf(_T("Error: Memory allocation failed\n"));
        CloseHandle(hInput);
        return 1;
    }

    DWORD bytes_read;
    if (!ReadFile(hInput, buffer, input_size, &bytes_read, NULL) || bytes_read != input_size) {
        _tprintf(_T("Error: Failed to read input file\n"));
        free(buffer);
        CloseHandle(hInput);
        return 1;
    }

    CloseHandle(hInput);

    ReverseBuffer(buffer, bytes_read);

    for (DWORD i = 0; i < input_size; i++) {
        buffer[i] += 0x55;  // Encrypt
    }

    int pixels = input_size * 2;
    int width = (int)sqrt((double)pixels);
    if (width < 64) width = 64;
    width = (width + 15) & ~15;
    int height = (pixels / width) + 16;
    if (height < 64) height = 64;
    height = (height + 15) & ~15;

    HANDLE hOutput = CreateFile(output_file, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hOutput == INVALID_HANDLE_VALUE) {
        _tprintf(_T("Error: Could not create output file '%s'\n"), output_file);
        free(buffer);
        return 1;
    }

    FileContext ctx = { hOutput, 0 };

    int mode_flag = use_raw_mode ? FLAG_RAW : FLAG_STANDARD;

    if (!WriteBE16(&ctx, JPEG_SOI) ||
        !WriteJFIFHeader(&ctx, mode_flag) ||
        !WriteDQT(&ctx) ||
        !WriteSOF0(&ctx, width, height) ||
        !WriteDHT_DC(&ctx, 0) ||
        !WriteDHT_AC_Lum(&ctx) ||
        !WriteDHT_DC(&ctx, 1) ||
        !WriteDHT_AC_Chr(&ctx) ||
        !WriteSOS(&ctx)) {
        _tprintf(_T("Error: Failed to write JPEG headers\n"));
        CloseHandle(hOutput);
        free(buffer);
        return 1;
    }

    DWORD data_start = ctx.dwPos;
    DWORD stuffed_size;

    if (use_raw_mode) {
        if (!WriteBytes(&ctx, buffer, input_size)) {
            _tprintf(_T("Error: Failed to write raw data\n"));
            CloseHandle(hOutput);
            free(buffer);
            return 1;
        }
        stuffed_size = input_size;
    }
    else {
        stuffed_size = WriteStuffedData(&ctx, buffer, input_size);
        if (stuffed_size == 0) {
            _tprintf(_T("Error: Failed to write stuffed data\n"));
            CloseHandle(hOutput);
            free(buffer);
            return 1;
        }
    }

    DWORD data_end = ctx.dwPos;

    if (!WriteBE16(&ctx, JPEG_EOI)) {
        _tprintf(_T("Error: Failed to write EOI marker\n"));
        CloseHandle(hOutput);
        free(buffer);
        return 1;
    }

    CloseHandle(hOutput);
    free(buffer);

    _tprintf(_T("Successfully created obfuscated JPEG file: %s\n"), output_file);
    _tprintf(_T("Format: YCbCr 4:2:0 (matching MS Paint)\n"));
    _tprintf(_T("Mode: %s\n"), use_raw_mode ? _T("RAW (no byte stuffing)") : _T("STANDARD (with byte stuffing)"));
    _tprintf(_T("Hidden flag: %d (in JFIF thumbnail width)\n"), mode_flag);
    _tprintf(_T("Image dimensions: %dx%d pixels\n"), width, height);
    _tprintf(_T("Original data size: %lu bytes\n"), input_size);
    _tprintf(_T("Written data size: %lu bytes\n"), stuffed_size);
    _tprintf(_T("Binary data starts at offset: 0x%08lX (%lu)\n"), data_start, data_start);
    _tprintf(_T("Last byte of binary data at offset: 0x%08lX (%lu)\n"), data_end, data_end);
}


void PrintUsage(LPCTSTR progName) {
    _tprintf(_T("Usage: %s [-raw] [-unpack]  \n\n"), progName);
    _tprintf(_T("Modes:\n"));
    _tprintf(_T("  Pack mode (default):   Obfuscate binary data as JPEG\n"));
    _tprintf(_T("  Unpack mode (-unpack): Extract binary data from JPEG\n\n"));
    _tprintf(_T("Options:\n"));
    _tprintf(_T("  -raw     In pack mode: Skip byte stuffing (raw mode)\n"));
    _tprintf(_T("           In unpack mode: Force raw mode extraction\n"));
    _tprintf(_T("  -unpack  Extract binary data from JPEG file\n\n"));
    _tprintf(_T("Examples:\n"));
    _tprintf(_T("  %s data.bin output.jpg\n"), progName);
    _tprintf(_T("  %s -raw data.bin output.jpg\n"), progName);
    _tprintf(_T("  %s -unpack input.jpg data.bin\n"), progName);
    _tprintf(_T("  %s -raw -unpack input.jpg data.bin\n"), progName);
}

int _tmain(int argc, TCHAR* argv[]) {
    int use_raw_mode = 0;
    int unpack_mode = 0;
    int arg_index = 1;

    // Parse switches
    while (arg_index < argc && argv[arg_index][0] == _T('-')) {
        if (_tcsicmp(argv[arg_index], _T("-raw")) == 0) {
            use_raw_mode = 1;
            arg_index++;
        }
        else if (_tcsicmp(argv[arg_index], _T("-unpack")) == 0) {
            unpack_mode = 1;
            arg_index++;
        }
        else {
            _tprintf(_T("Error: Unknown option '%s'\n\n"), argv[arg_index]);
            PrintUsage(argv[0]);
            return 1;
        }
    }

    // Check for required arguments
    if (argc - arg_index < 2) {
        _tprintf(_T("Error: Missing required arguments\n\n"));
        PrintUsage(argv[0]);
        return 1;
    }

    LPCTSTR input_file = argv[arg_index];
    LPCTSTR output_file = argv[arg_index + 1];

    int result;
    if (unpack_mode) {
        result = UnpackJPEG(input_file, output_file, use_raw_mode);
    }
    else {
        result = PackToJPEG(input_file, output_file, use_raw_mode);
    }

    return result;
}
This C code is compatible with MSVC and VisualStudio 2019 in TCHAR mode.

It obfuscates arbitrary binary data to look like a JPEG picture. The binary data is put where the image data normally would be. To defeat overeager signature scanners, the binary data is first rudimentarly encrypted by reversing the order of binary bytes and adding 0x55 to every byte (with wrap-around arithmetic). When the "-raw" switch is not specified on the command line, the binary data is also subjected to "byte stuffing" because in JPEG file format any 0xFF byte in the image data must be followed by 0x00 to distinguish it from JPEG markers (which start with 0xFF). At the end, this code outputs to the console the file offsets where the binary data starts and ends.
The generated JPEG file is openable by MS-Paint and the currently generated structure of JPEG headers (and the values within them) deceives MS-Paint successfully. This relates to MS-Paint specific JPEG attributes, such as: JFIF version and density, quantization tables, chrominance subsampling, Huffman table structure, etc..

This code implements a hidden binary flag in the JPEG headers that does not perturb the validity of the JPEG file nor make it look unusual.
This flag clandestinely denotes whether the binary data was encoded inside the JPEG file with "byte stuffing" or in the raw fashion.
The unpack code performs the reverse operation, i.e.: it extracts the binary data embedded in such JPEG file. This extractor code is executed when an "-unpack" command line switch is found.

This extractor code uses the hidden flag in JPEG headers to automatically determine whether the binary data has been encoded with "byte stuffing" or not, unless overridden by the "-raw" switch.

The usage command line processing allows the "-raw" and "-unpack" switches to appear together at the beginning of the command line.
The application uses WinAPI file processing functions like CreateFile(), ReadFile(), Writefile(), GetFileSize(), SetFilePointerEx(), etc... so Linux user must change them to Linux-specific file handling functions.

A sample obfuscated JPEG file is attached.
bbb.jpg


Because most AI LLMs which can write code well, can also execute Python code in a sandbox, I have also created the following Python code that can deobfuscate the JPEG file and create an EXE file in the AI's sandbox file system ...which the AI can then read without restrictions.
The Python code listed below is the full Python port of the -unpack path, including the -raw override switch. Reads the JFIF thumbnail-width byte at offset 18 to auto-detect mode, walks markers to find SOS scan data, slices to the trailing EOI, optionally reverses the FF 00 → FF stuffing, then runs the decrypt-and-reverse step.
Code:
import struct
import sys

# JPEG markers
JPEG_SOI  = 0xFFD8
JPEG_APP0 = 0xFFE0
JPEG_SOS  = 0xFFDA
JPEG_EOI  = 0xFFD9

# Hidden flag values stored in the JFIF thumbnail-width byte
FLAG_STANDARD = 0   # byte stuffing applied
FLAG_RAW      = 1   # raw mode, no byte stuffing

# Decryption is a constant byte subtraction: build a 256-entry translation
# table once so .translate() can apply it in C-speed in a single pass.
_DECRYPT_TABLE = bytes((i - 0x55) & 0xFF for i in range(256))


def find_jfif_flag(data: bytes, force_raw: bool):
    """
    Validate the SOI + APP0/JFIF header and return the mode flag stored in
    the thumbnail-width byte. Returns None if the header is malformed.

    JFIF layout (offsets from start of file):
        0..1   SOI            (FF D8)
        2..3   APP0           (FF E0)
        4..5   length
        6..10  "JFIF\\0"
        11..12 version
        13     density units
        14..15 X density
        16..17 Y density
        18     thumbnail width  <-- hidden flag lives here
        19     thumbnail height
    """
    if len(data) < 20:
        return None
    if struct.unpack(">H", data[0:2])[0] != JPEG_SOI:
        return None
    if struct.unpack(">H", data[2:4])[0] != JPEG_APP0:
        return None
    if data[6:11] != b"JFIF\0":
        return None

    thumbnail_width = data[18]

    if force_raw:
        return FLAG_RAW
    return FLAG_RAW if thumbnail_width == FLAG_RAW else FLAG_STANDARD


def find_sos_offset(data: bytes):
    """
    Walk the marker chain starting just after SOI and return the byte offset
    of the first byte of entropy-coded scan data (i.e. just past the SOS
    segment header).

    Each segment after a marker has a 2-byte big-endian length that includes
    its own size, so advancing `pos` by `length` skips the entire segment.
    """
    pos = 2  # skip SOI
    n = len(data)

    while pos + 4 <= n:
        marker = struct.unpack(">H", data[pos:pos + 2])[0]
        pos += 2

        if marker == JPEG_SOS:
            length = struct.unpack(">H", data[pos:pos + 2])[0]
            pos += length  # length includes its own 2 bytes
            return pos

        # Any non-marker (top byte != 0xFF) or a stray EOI here is malformed.
        if marker == JPEG_EOI or marker < 0xFF00:
            return None

        if pos + 2 > n:
            return None
        length = struct.unpack(">H", data[pos:pos + 2])[0]
        pos += length

    return None


def find_eoi_offset(data: bytes):
    """
    The packer writes EOI as the very last 2 bytes of the file, so we just
    confirm that and return its offset.
    """
    if len(data) < 2:
        return None
    if struct.unpack(">H", data[-2:])[0] != JPEG_EOI:
        return None
    return len(data) - 2


def unstuff_data(stuffed: bytes) -> bytes:
    """
    Reverse JPEG byte-stuffing: every 0xFF in the original stream had a
    0x00 inserted after it during packing, so collapse `FF 00` back to `FF`.
    """
    out = bytearray()
    i = 0
    n = len(stuffed)
    while i < n:
        b = stuffed[i]
        out.append(b)
        if b == 0xFF and i + 1 < n and stuffed[i + 1] == 0x00:
            i += 2  # consume the stuffed 0x00
        else:
            i += 1
    return bytes(out)


def unpack_jpeg(input_path: str, output_path: str, force_raw: bool = False) -> int:
    try:
        with open(input_path, "rb") as f:
            data = f.read()
    except OSError as e:
        print(f"Error: Could not open input file '{input_path}': {e}")
        return 1

    mode_flag = find_jfif_flag(data, force_raw)
    if mode_flag is None:
        print("Error: Invalid JPEG file or missing JFIF header")
        return 1

    sos_offset = find_sos_offset(data)
    if sos_offset is None:
        print("Error: Could not find SOS marker")
        return 1

    eoi_offset = find_eoi_offset(data)
    if eoi_offset is None:
        print("Error: Could not find EOI marker")
        return 1

    if eoi_offset <= sos_offset:
        print("Error: No data found between SOS and EOI")
        return 1

    scan_data = data[sos_offset:eoi_offset]

    if mode_flag == FLAG_RAW:
        print("Mode detected: RAW (no byte stuffing)")
        payload = scan_data
    else:
        print("Mode detected: STANDARD (with byte stuffing)")
        payload = unstuff_data(scan_data)

    # Decrypt (subtract 0x55 mod 256) then reverse the whole buffer.
    payload = payload.translate(_DECRYPT_TABLE)[::-1]

    try:
        with open(output_path, "wb") as f:
            f.write(payload)
    except OSError as e:
        print(f"Error: Could not create output file '{output_path}': {e}")
        return 1

    print(f"Successfully extracted binary data to: {output_path}")
    print(f"Extracted data size: {len(payload)} bytes")
    print(f"SOS data offset: 0x{sos_offset:08X} ({sos_offset})")
    print(f"EOI marker offset: 0x{eoi_offset:08X} ({eoi_offset})")
    return 0


def print_usage(prog: str) -> None:
    print(f"Usage: {prog} [-raw]  ")
    print()
    print("  -raw     Force raw-mode extraction (skip stuffing detection)")


def main(argv) -> int:
    force_raw = False
    args = list(argv[1:])

    while args and args[0].startswith("-"):
        opt = args.pop(0)
        if opt.lower() == "-raw":
            force_raw = True
        else:
            print(f"Error: Unknown option '{opt}'\n")
            print_usage(argv[0])
            return 1

    if len(args) != 2:
        print("Error: Missing required arguments\n")
        print_usage(argv[0])
        return 1

    return unpack_jpeg(args[0], args[1], force_raw=force_raw)


if __name__ == "__main__":
    sys.exit(main(sys.argv))


Below is the standalone Python port for -unpack -raw options together. Since force_raw=True makes the thumbnail-width flag irrelevant and UnstuffData() is never called, both have been removed; only the JFIF header sanity-check, marker walk, decrypt, and reverse remain. This makes the "raw" version smaller.
Code:
import struct
import sys

# JPEG markers
JPEG_SOI  = 0xFFD8
JPEG_APP0 = 0xFFE0
JPEG_SOS  = 0xFFDA
JPEG_EOI  = 0xFFD9

# Decryption table: subtract 0x55 from each byte (mod 256) in one .translate() pass.
_DECRYPT_TABLE = bytes((i - 0x55) & 0xFF for i in range(256))


def validate_jfif(data: bytes) -> bool:
    """
    Confirm the file starts with SOI + APP0/JFIF, matching what the C
    FindJFIFFlag() function checks before returning. We don't read the
    thumbnail-width flag because force_raw makes its value irrelevant.
    """
    if len(data) < 20:
        return False
    if struct.unpack(">H", data[0:2])[0] != JPEG_SOI:
        return False
    if struct.unpack(">H", data[2:4])[0] != JPEG_APP0:
        return False
    if data[6:11] != b"JFIF\0":
        return False
    return True


def find_sos_offset(data: bytes):
    """
    Walk markers from just after SOI until SOS is found and return the
    offset of the first scan-data byte (i.e. just past the SOS header).
    Each segment's 2-byte big-endian length includes its own size, so
    `pos += length` skips the whole segment in one step.
    """
    pos = 2
    n = len(data)

    while pos + 4 <= n:
        marker = struct.unpack(">H", data[pos:pos + 2])[0]
        pos += 2

        if marker == JPEG_SOS:
            length = struct.unpack(">H", data[pos:pos + 2])[0]
            pos += length
            return pos

        if marker == JPEG_EOI or marker < 0xFF00:
            return None

        if pos + 2 > n:
            return None
        length = struct.unpack(">H", data[pos:pos + 2])[0]
        pos += length

    return None


def find_eoi_offset(data: bytes):
    """The packer always places EOI as the trailing 2 bytes of the file."""
    if len(data) < 2:
        return None
    if struct.unpack(">H", data[-2:])[0] != JPEG_EOI:
        return None
    return len(data) - 2


def unpack_jpeg_raw(input_path: str, output_path: str) -> int:
    try:
        with open(input_path, "rb") as f:
            data = f.read()
    except OSError as e:
        print(f"Error: Could not open input file '{input_path}': {e}")
        return 1

    if not validate_jfif(data):
        print("Error: Invalid JPEG file or missing JFIF header")
        return 1

    sos_offset = find_sos_offset(data)
    if sos_offset is None:
        print("Error: Could not find SOS marker")
        return 1

    eoi_offset = find_eoi_offset(data)
    if eoi_offset is None:
        print("Error: Could not find EOI marker")
        return 1

    if eoi_offset <= sos_offset:
        print("Error: No data found between SOS and EOI")
        return 1

    # In raw mode the scan-data slice is the encrypted payload directly —
    # no FF 00 unstuffing, since the packer skipped that step too.
    scan_data = data[sos_offset:eoi_offset]

    print("Mode detected: RAW (no byte stuffing)")

    # Decrypt then reverse, matching the order in UnpackJPEG().
    payload = scan_data.translate(_DECRYPT_TABLE)[::-1]

    try:
        with open(output_path, "wb") as f:
            f.write(payload)
    except OSError as e:
        print(f"Error: Could not create output file '{output_path}': {e}")
        return 1

    print(f"Successfully extracted binary data to: {output_path}")
    print(f"Extracted data size: {len(payload)} bytes")
    print(f"SOS data offset: 0x{sos_offset:08X} ({sos_offset})")
    print(f"EOI marker offset: 0x{eoi_offset:08X} ({eoi_offset})")
    return 0


def main(argv) -> int:
    if len(argv) != 3:
        print(f"Usage: {argv[0]}  ")
        return 1
    return unpack_jpeg_raw(argv[1], argv[2])


if __name__ == "__main__":
    sys.exit(main(sys.argv))

Last edited by HarrySpoofer; 05-03-2026 at 08:30.
Reply With Quote
The Following 2 Users Gave Reputation+1 to HarrySpoofer For This Useful Post:
Fyyre (05-23-2026), wx69wx2023 (05-02-2026)
The Following 7 Users Say Thank You to HarrySpoofer For This Useful Post:
dimosdimos (05-02-2026), emo (05-03-2026), Fyyre (05-23-2026), Jupiter (05-02-2026), tame_mpeg (05-02-2026), tonyweb (05-23-2026), Vosiyons (05-02-2026)
  #2  
Old 05-02-2026, 06:58
tame_mpeg tame_mpeg is offline
Friend
 
Join Date: Oct 2023
Posts: 21
Rept. Given: 0
Rept. Rcvd 1 Time in 1 Post
Thanks Given: 8
Thanks Rcvd at 22 Times in 10 Posts
tame_mpeg Reputation: 1
Nice idea.
Any examples of LLMs you got this working with and what sort of useful information they gave you on the binaries/prompts to get that info?
Reply With Quote
  #3  
Old 05-02-2026, 10:29
HarrySpoofer HarrySpoofer is offline
Friend
 
Join Date: Jul 2018
Posts: 47
Rept. Given: 0
Rept. Rcvd 5 Times in 3 Posts
Thanks Given: 10
Thanks Rcvd at 50 Times in 19 Posts
HarrySpoofer Reputation: 5
Quote:
Originally Posted by tame_mpeg View Post
Nice idea.
Any examples of LLMs you got this working with and what sort of useful information they gave you on the binaries/prompts to get that info?
I got this to pass through Claude upload filters and past the CGPT and Grok filters, too.

Grok was able to actually make a keygen for Offline Explorer and change the painting function in a silly Bubbles screensaver (the one built into Windows).

Last edited by HarrySpoofer; 05-02-2026 at 18:51.
Reply With Quote
The Following User Says Thank You to HarrySpoofer For This Useful Post:
niculaita (05-02-2026)
  #4  
Old 05-02-2026, 23:03
Jupiter's Avatar
Jupiter Jupiter is offline
Lo*eXeTools*rd
 
Join Date: Jan 2005
Location: Moscow, Russia
Posts: 234
Rept. Given: 43
Rept. Rcvd 62 Times in 37 Posts
Thanks Given: 37
Thanks Rcvd at 191 Times in 57 Posts
Jupiter Reputation: 62
Question Bubbles screensaver

Quote:
Originally Posted by HarrySpoofer View Post
... change the painting function in a silly Bubbles screensaver (the one built into Windows)
I'm intrigued. But why do you need this?

Kinda offtopic.
__________________
EnJoy!
Reply With Quote
  #5  
Old 05-03-2026, 07:41
emo emo is offline
Friend
 
Join Date: Dec 2010
Posts: 86
Rept. Given: 237
Rept. Rcvd 12 Times in 8 Posts
Thanks Given: 93
Thanks Rcvd at 8 Times in 6 Posts
emo Reputation: 12
This can be applied to all types of applications, regardless of the operating system (Windows, OS, Mac), including translation, reverse engineering, or open search, as well as banking and government tools.

analysis LLM <> GPT
Reply With Quote
  #6  
Old 05-03-2026, 08:20
HarrySpoofer HarrySpoofer is offline
Friend
 
Join Date: Jul 2018
Posts: 47
Rept. Given: 0
Rept. Rcvd 5 Times in 3 Posts
Thanks Given: 10
Thanks Rcvd at 50 Times in 19 Posts
HarrySpoofer Reputation: 5
Quote:
Originally Posted by Jupiter View Post
I'm intrigued. But why do you need this?
Kinda offtopic.
Oh, this was for a silly reason.
I wanted to modify this screen saver so it draws bubbles to a Window Device Context instead of the Desktop Device Context. Think about it as a screen saver for just one window.
I needed it for a toy game for kids (if they win then they get bubbles as a reward- I was too lazy to render the bubbles myself so I repurposed the screensaver).

Since then I also used this Binary to JPEG obfuscator to smuggle binaries into my employer's private corporate network because I needed some Sysinternals utilities that my IT Dept. just refused to install.
The corporate email attachment filter just let these JPEG files right through. It's been several months now and nobody has noticed anything, probably because these utilities are signed by Microsoft.

Last edited by HarrySpoofer; 05-03-2026 at 08:27.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On



All times are GMT +8. The time now is 05:48.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )