Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@NHollmann
Last active April 3, 2021 00:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NHollmann/c4f17b3372ec6e137418edae57bdec63 to your computer and use it in GitHub Desktop.
Save NHollmann/c4f17b3372ec6e137418edae57bdec63 to your computer and use it in GitHub Desktop.
Run dynamic code on Windows (x86)
// Run dynamic code on Windows (x86)
// Compile with: gcc -o dynamicCodeWin dynamicCodeWin.c
// Tutorial: https://nicolashollmann.de/blog/run-dynamic-code-windows/
#include <stdio.h>
#include <stdbool.h>
#include <Windows.h>
/**
* Helper function to execute dynamic code.
*
* @param code a pointer to the code to execute
* @param length the length of the code
* @return true if the code run successfully, otherwise false
*/
bool run_code(const void* code, size_t length)
{
// Allocate new memory for code execution.
// We don't set the execute flag because we won't want to
// open doors to malicious software.
// dynMemory must be declared as volatile, as some Release
// optimizations cause problems on VirtualFree. Maybe some
// sort of reordering.
volatile LPVOID dynMemory = VirtualAlloc(NULL, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (dynMemory == NULL)
{
printf("Alloc Error: %ld\n", GetLastError());
return false;
}
// Copy code to new memory.
memcpy(dynMemory, code, length);
// Change protection.
// We remove the write flag and set the execute flag on that page.
DWORD oldProtection;
if (!VirtualProtect(dynMemory, length, PAGE_EXECUTE, &oldProtection))
{
printf("Protect Error: %ld\n", GetLastError());
return false;
}
// Call the new function in memory.
int result = ((int (*)(void))dynMemory)();
printf("Result: %d\n", result);
// At the end we free the memory.
if (!VirtualFree(dynMemory, 0, MEM_RELEASE))
{
printf("Free Error: %ld\n", GetLastError());
return false;
}
return true;
}
/**
* Entrypoint of the program.
*
* @return exit code of the program, 0 if successful,
* -1 in case of an error
*/
int main(void)
{
// Define the code we want to execute
const char code[] = {
// Direct set
0xb8, 0x05, 0x00, 0x00, 0x00, // mov eax, 0x05
// Addition
0x05, 0x06, 0x00, 0x00, 0x00, // add eax, 0x06
// Subtraction
0x2d, 0x01, 0x00, 0x00, 0x00, // sub eax, 0x01
// Return (result in EAX)
0xc3 // ret
};
// Run the code
if (!run_code(code, sizeof code)) {
return -1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment