Ошибка нарушения доступа с помощью memcpy

0
    unsigned char hexData[14] = {
    0x31, 0xC0, 0xBB, 0x42, 0x24, 0x80, 0x7C, 0x66,
    0xB8, 0x88, 0x13, 0x50, 0xFF, 0xD3
};

void dummy(){}

int main()
{
    void *code_ptr = &dummy;
    PDWORD OP;
    __asm
    {
        call code_ptr
        add code_ptr,10h
    }
    VirtualProtect(code_ptr, 14, PAGE_EXECUTE_WRITECOPY, OP);
    memcpy(code_ptr, hexData, 14);
.
.
.

и в разборке

_LoadLibraryA@4:
003C11E0  jmp         _LoadLibraryA@4 (03C1430h)  
dummy:
003C11E5  jmp         dummy (03C1A80h)  
_printf:
003C11EA  jmp         _printf (03C1436h)  
_VirtualProtect@16:
003C11EF  jmp         _VirtualProtect@16 (03C143Ch)  
003C11F4  int         3  
003C11F5  int         3  
003C11F6  int         3  
003C11F7  int         3 

поэтому кажется, что я могу скопировать что-то 15 блоков после 003C11E5
но когда я делаю это, я получаю доступ Ошибка доступа

Я попытался использовать VirtualAlloc, как

void *code_ptr = &dummy;
code_ptr = VirtualAlloc(NULL, 14, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(code_ptr, hexData, 14);
__asm
{
    call code_ptr
}

и я снова получил эту ошибку

int (*func)();
func = (int (*)()) code;
(int)(*func)();

что не работает ни

моя IDE - VS2013, а моя ОС - win8.1

Буду признателен за любые идеи

  • 0
    Преобразование в указатель на void из типа функции не гарантируется.
Теги:
operating-system
portable-executable
windows-8.1

1 ответ

3
Лучший ответ

Ну, OP - неинициализированный указатель. Вы не можете передать это VirtualProtect. Вместо

PDWORD OP;

тебе нужно:

DWORD OldProtect;

А затем передайте &OldProtect в VirtualProtect.

VirtualProtect(code_ptr, 14, PAGE_EXECUTE_WRITECOPY, &OldProtect);

Вы нарушаете существующий код при вызове VirtualProtect. Вы не проверяете наличие ошибок и поэтому продолжаете независимо. Затем вызов memcpy выходит из строя с общей ошибкой защиты, поскольку память считывается только.

Даже если вы исправите свой код, я сомневаюсь, что он будет работать. Я не вижу причин, чтобы dummy составлял 14 байтов. Вы полагаетесь на удачу и принятие желаемого за действительное. Таким образом, вы, вероятно, перепишете код, который вы выполняете.

Если вы хотите записать 14 байтов памяти для своего кода, вызовите VirtualAlloc. Таким образом, вы можете быть уверены в успехе.

В качестве общей рекомендации вам нужно будет привыкнуть проверять возвращаемые значения на наличие ошибок. Вы вызываете VirtualProtect и игнорируете возвращаемое значение. Как вы узнали, что ваш вызов VirtualProtect был успешным?

  • 0
    Кажется, что я могу передать неинициализированный указатель на функцию, и нет никакой ошибки, я сказал: «Я пытался использовать VirtualAlloc как .....»
  • 3
    Ну, так как вы не проверяли ошибки, как вы можете это сказать? Подсказка, перестаньте игнорировать возвращаемое значение VirtualProtect . Начните с перечитывания документации и концентрации на возвращаемом значении.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню