Windows下的自我修改问题覆盖

时间:2019-04-21 05:51:29

标签: c++ self-modifying

我正在编写一个自变异代码,其覆盖之前的原始值为1,但是覆盖之后的原始值为42。我想我缺少一些规格,因为我在原始覆盖和变异覆盖上都得到了1。我完整的代码看起来像这个要点链接,但是原始源代码是在* unix https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/

下编写的
#include <windows.h>
#include <iostream>
using namespace std;
int getpagesize();
void foo(void);
int change_page_permissions_of_address(void *addr);

int getpagesize() {
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    return unsigned(si.dwPageSize);
}

void foo(void) {
    int i = 0;
    i++;
    printf("i: %d\n", i);
}

int change_page_permissions_of_address(void *addr) {
     // Get total function size
    int page_size = getpagesize();
    DWORD dwOldProtect;
    // Obtain the addresses for the functions so we can calculate size.
    uintptr_t tmp = (uintptr_t)addr-(uintptr_t)addr%page_size;
    addr = (void*)tmp;

     // We need to give ourselves access to modifify data at the given address
    if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
        return -1;
    }

    return 0;
}

int main() {
    void *foo_addr = (void*)foo;
    if (change_page_permissions_of_address(foo_addr) == -1) {
        printf("Error while changing page permissions of foo(): %s\n");
        return 1;
    }

    // Call the unmodified foo()
    puts("Calling foo...");
    foo();

    // Change the immediate value in the addl instruction in foo() to 42
    unsigned char *instruction = (unsigned char*)foo_addr + 18;
    *instruction = 0x2A;

    puts("Calling foo..., but I am the self-modifying");
    foo();
    cin.get();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

检查VirtualProtect是不正确的,因为它返回FALSE,如果出错则返回-1。另外,我怀疑您将需要获取指向foo所属页面区域的起始页面的指针,并且不清楚从何处获得偏移量18