Is there a way to store binary code in memory (as a value) then execute it?
For instance if I have an array of bytes I have filled with the binary code of say, a .exe, is it possible to execute it?
Is there a way to store binary code in memory (as a value) then execute it?
For instance if I have an array of bytes I have filled with the binary code of say, a .exe, is it possible to execute it?
The short answer is yes for raw machine code (shellcode), but not by just dropping a full PE (.exe) image into a byte array and jumping to it. A PE needs the Windows loader: relocations, import resolution, TLS, etc. If your bytes are a position‑independent routine with the right calling convention, you can execute them by placing them in memory that is marked executable, as showed for Linux.
On Windows, use VirtualAlloc to get writable memory, copy the bytes, then flip the protection to executable with VirtualProtect before calling them. Keep to W^X: write as RW, then change to RX (avoid RWX). Minimal example:
#include <windows.h>
#include <stdint.h>
#include <string.h>
int main(void) {
uint8_t payload[] = { 0xC3 }; // ret; replace with your code
SIZE_T size = sizeof(payload);
void *mem = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!mem) return 1;
memcpy(mem, payload, size);
DWORD oldProt;
if (!VirtualProtect(mem, size, PAGE_EXECUTE_READ, &oldProt)) return 1;
((void(*)(void))mem)(); // or CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)mem,NULL,0,NULL);
VirtualFree(mem, 0, MEM_RELEASE);
return 0;
} About the masking in ’s Linux sample: pages are typically 4096 bytes, so addr & ~0xFFF aligns a pointer down to the start of its page because ~0xFFF clears the low 12 bits. Linux mprotect requires a page‑aligned address. VirtualProtect will round the address down internally, but you still need the correct region size (round up to a page multiple; use GetSystemInfo to query dwPageSize).
Practical cautions:
Jump to Post— gerard4143 371Here's an example that displays 'Hello, World!'. Note this will only work on a Linux 64 bit PC.
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> unsigned char mya[] = { 0x50,0x57,0x56,0x52,0xe8, 0x00,0x00,0x00,0x00,0x5e, 0x48,0x81,0xc6,0x24,0x00, 0x00,0x00,0x48,0xc7,0xc0, 0x01,0x00,0x00,0x00,0x48, 0xc7,0xc7,0x01,0x00,0x00, 0x00,0x48,0xc7,0xc2,0x0e, 0x00,0x00,0x00,0x0f,0x05, 0x5a,0x5e,0x5f,0x5a,0xc3, 0x48,0x65,0x6c,0x6c,0x6f, 0x2c,0x20,0x57,0x6f,0x72, 0x6c,0x64,0x21,0x0a,0x00 }; int main(int argc, char**argv) { …
You'll have to change the memory attributes of the array to read and execute and then point the instruction pointer at it.
Here's an example that displays 'Hello, World!'. Note this will only work on a Linux 64 bit PC.
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
unsigned char mya[] = {
0x50,0x57,0x56,0x52,0xe8,
0x00,0x00,0x00,0x00,0x5e,
0x48,0x81,0xc6,0x24,0x00,
0x00,0x00,0x48,0xc7,0xc0,
0x01,0x00,0x00,0x00,0x48,
0xc7,0xc7,0x01,0x00,0x00,
0x00,0x48,0xc7,0xc2,0x0e,
0x00,0x00,0x00,0x0f,0x05,
0x5a,0x5e,0x5f,0x5a,0xc3,
0x48,0x65,0x6c,0x6c,0x6f,
0x2c,0x20,0x57,0x6f,0x72,
0x6c,0x64,0x21,0x0a,0x00
};
int main(int argc, char**argv)
{
void *addr = (void*)((unsigned long)mya & ((0UL - 1UL) ^ 0xfff));/*get memory page*/
int ans = mprotect(addr, 1, PROT_READ|PROT_WRITE|PROT_EXEC);/*set page attributes*/
if (ans)
{
perror("mprotect");
exit(EXIT_FAILURE);
}
((void(*)(void))mya)();/*execute array*/
return 0;
} Forgot to mention I'm using Windows.
Also, what is the reason for bitwise AND'ing the address of the array with -1UL then XOR'ing it with 0xfff ?
Memory pages on my system are 4096 bytes which is 0xfff so that line of code is getting the address of the memory page that contains the array mya. Why you ask? The mprotect() function requires that the address past to it be aligned on a page boundary.
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.