So lets present and explain line by line the code that will perform the first task.
#include <cstdio>
#include <Windows.h>
#include "Entropy.h"
using namespace std;
BYTE payload[] = { 0xFF, 0x44, 0x01, 0xE2, 0x86, 0xD1, 0xC6, 0x88, 0x39, 0xA2, 0xAF, 0x59, 0x3D, 0x8C, 0x0F, 0x90, 0x7E, 0xB2, 0xAF, 0xBD, 0xAA, 0xE0, 0xBB, 0x87, 0x10, 0xF0, 0xD1, 0x37, 0x00, 0x55, 0x07 }; // Simulated high entropy code
constexpr int number_of_chunks = 5; // Number of chunks. You can randomize this too.
constexpr int chunk_size = sizeof payload / number_of_chunks; // Size of each chunk
constexpr int remaining_bytes = sizeof payload % number_of_chunks; // Remaining bytes after the last chunk is processed
BYTE low_entropy_payload[sizeof payload * 2 - remaining_bytes] = {0}; // array of bytes size calculation to contain the original high entropy code plus the low entropy inserts
constexpr int payload_size_after_entropy_reduction = sizeof payload * 2; // Total size of the reduced entropy payload
Notice that all of these calculations are stored in global variables and
the high entropy code is also located in the global area of the code to
assure that it will be stored in the data section of the executable but
it could be perfectly located in the resources section and loaded at
runtime too. You could even store the high entropy byte pattern inside
the main function, however then the pattern would be stored in the .text
section
and it would be loaded in the stack and not in the heap as it happens
when its stored in the data section or in the resources section. This is
important because the stack can't handle very big array of bytes and
also some
compilers complain about this when array is too big.
Next task is to divide the high entropy code in chunks and add the low entropy patterns: