Проблемы с самоизменяющимся кодом с разрешениями на изменение

#c #visual-studio

#c #visual-studio

Вопрос:

Я пишу самоизменяющийся код. Я пытаюсь изменить разрешение адреса моей функции для выполнения, но когда я пытаюсь перенести свой код, написанный на Dev C , в Visual Studio 2017, я получил сообщение об ошибке.

Я использую Microsoft Windows 10 и Visual Studio 20017 для этой задачи с конфигурациями по умолчанию.

 int change_page_permissions_of_address(void *addr) {
    // Move the pointer to the page boundary
    int page_size = getpagesize();
    DWORD dwOldProtect;
    addr -= (uintptr_t)addr % page_size;

    if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, amp;dwOldProtect) == -1) {
        return -1;
    }
    return 0;
}


int main() {
    char *foo_addr = (char*)foo;

    if (change_page_permissions_of_address(foo_addr) == -1) {
        printf("Error while changing page permissions of foo(): %sn");
        return 1;
    }
}

int main(){
    // 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;

    // Call the modified foo()
    puts("Calling foo..., but I am the self-modifying");
    foo();
    }
}
  

Я хочу иметь такое же поведение, как у разработчика c в Visual Studio

ошибка

Ошибка (активная) Выражение E0852 должно быть указателем на полный объект
Ошибка типа C2036 ‘void *’: неизвестный размер

перезапись_мутация

Комментарии:

1.2 main ???!!!

2. VirtualProtect возвращает a BOOL , а не -1 . Также см. Функцию VirtualProtect в MSDN.

Ответ №1:

addr -= (uintptr_t)addr % page_size; проблема. -= при указателе вычитает левую часть как целое число, умноженное на размер объекта, на который указывает указатель, и вычитает его из указателя. Компилятор жалуется, потому что он не знает размер void .

Можете ли вы сделать параметр a char * ?

Комментарии:

1. вовсе нет, потому что, если я перейду на char, то моя основная функция сделает несовместимый параметр для void foo_addr = (void )foo;

2. То же предложение. Сделайте foo_addr символом *.

3. если я изменю значение на char, то моя основная функция создаст несовместимый параметр для void foo_addr = (void )foo; , и он всегда будет печатать исходное значение 1 и мутацию 1 . Таким образом, мой результат мутации должен быть перезаписан моим значением в этом случае 42

4. @yesii_0691: addr = ((char*)addr) - ((uintptr_t)addr) % page_size; .

5. Или, может быть, битовая операция: addr amp;= ~(uintptr_t)(page_size-1); .