Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute Code From Memory on Windows 10 c++ x64?

I'm trying to figure out how to execute arbitrary code on Windows 10. I feel like this code should work, but it's giving me an Access violation writing location error.

#include <iostream>
#include <vector>

#include <Windows.h>

// x64 assembly
#define ret (uint8_t)(0xc3)
#define nop (uint8_t)(0x90)

int main() {
    std::vector<uint8_t> raw_code = {
        nop, ret
    };

    LPVOID exec = VirtualAlloc(NULL, raw_code.size(), MEM_RESERVE, PAGE_READWRITE);
    memcpy(exec, raw_code.data(), raw_code.size());

    DWORD old_protect;
    VirtualProtect(exec, raw_code.size(), PAGE_EXECUTE, &old_protect); // Line where error occurs

    ((void(*)())exec)();

    VirtualProtect(exec, raw_code.size(), old_protect, &old_protect);
    VirtualFree(exec, raw_code.size(), MEM_RELEASE);

    return 0;
}
like image 627
NoahGav Avatar asked Mar 02 '23 23:03

NoahGav


2 Answers

Well, for one thing MEM_RESERVE means the memory isn't allocated, so trying to dereference the pointer will cause an access violation (as you saw for yourself). Don't be cute and just allocate your memory as normal, using MEM_COMMIT | MEM_RESERVE.

You also aren't setting your memory to be executable, you need to use PAGE_EXECUTE_READWRITE instead. Otherwise, with DEP enabled, your code will crash with access violation.

like image 56
Blindy Avatar answered Mar 11 '23 10:03

Blindy


Actually, the error occurs on the following line (at least, it does when I run your code):

    memcpy(exec, raw_code.data(), raw_code.size());

This is because your call to VirtualAlloc only reserves memory, but does not actually commit it. From the documentation:

MEM_RESERVE (0x00002000)
Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk.

To commit the memory (i.e., make it usable), you need to add the MEM_COMMIT flag:

    LPVOID exec = VirtualAlloc(nullptr, raw_code.size(), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

With this flag added, you code runs on my Windows 10 (built with clang-cl/VS-2019) without error.

like image 30
Adrian Mole Avatar answered Mar 11 '23 11:03

Adrian Mole