簡體   English   中英

在 Windows 上執行來自 Memory 的代碼 10 c++ x64?

[英]Execute Code From Memory on Windows 10 c++ x64?

我想弄清楚如何在 Windows 10 上執行任意代碼。我覺得這段代碼應該可以工作,但它給我一個訪問沖突寫入位置錯誤。

#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;
}

好吧,一方面, MEM_RESERVE意味着 memory 沒有分配,因此嘗試取消引用指針將導致訪問沖突(如您親眼所見)。 別裝傻,像往常一樣分配你的 memory,使用MEM_COMMIT | MEM_RESERVE MEM_COMMIT | MEM_RESERVE

您也沒有將 memory 設置為可執行文件,您需要改用PAGE_EXECUTE_READWRITE 否則,在啟用 DEP 的情況下,您的代碼將因訪問沖突而崩潰。

實際上,錯誤發生在以下行(至少,當我運行您的代碼時會發生):

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

這是因為您對VirtualAlloc的調用僅保留memory,但並未實際提交 從文檔中

MEM_RESERVE (0x00002000)
在 memory 或磁盤上的分頁文件中不分配任何實際物理存儲的情況下保留進程的虛擬地址空間范圍。

要提交 memory(即使其可用),您需要添加MEM_COMMIT標志:

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

添加此標志后,您的代碼可以在我的 Windows 10(使用 clang-cl/VS-2019 構建)上正常運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM