memcpy 访问冲突错误

bak*_*Dev 0 c c++ operating-system portable-executable windows-8.1

    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);
.
.
.
Run Code Online (Sandbox Code Playgroud)

并在拆卸

_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 
Run Code Online (Sandbox Code Playgroud)

所以看起来我可以在 003C11E5 之后复制 15 个块的东西,
但是当我这样做时,我得到访问访问冲突错误

我尝试使用 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
}
Run Code Online (Sandbox Code Playgroud)

我又犯了那个错误

int (*func)();
func = (int (*)()) code;
(int)(*func)();
Run Code Online (Sandbox Code Playgroud)

这也不起作用

我的IDE是VS2013,我的操作系统是win8.1

我很感激任何想法

Dav*_*nan 5

嗯,OP是一个未初始化的指针。你不能把它传递给VirtualProtect. 代替

PDWORD OP;
Run Code Online (Sandbox Code Playgroud)

你需要:

DWORD OldProtect;
Run Code Online (Sandbox Code Playgroud)

然后传递&OldProtectVirtualProtect.

VirtualProtect(code_ptr, 14, PAGE_EXECUTE_WRITECOPY, &OldProtect);
Run Code Online (Sandbox Code Playgroud)

您现有的代码在调用VirtualProtect. 您不检查错误,因此无论如何都要继续。然后调用memcpy失败并出现一般保护错误,因为内存是只读的。

即使您修复了代码,我也怀疑它是否会起作用。我看不出dummy有 14 个字节长的理由。你靠运气和一厢情愿。因此,您可能会覆盖正在执行的代码。

如果您希望将代码写入 14 字节的内存,请调用VirtualAlloc. 这样你就可以确定成功了。

作为一条一般性建议,您需要养成检查返回值是否有错误的习惯。您调用VirtualProtect并忽略返回值。你怎么知道你的呼叫VirtualProtect成功了?

  • 好吧,既然你没有检查错误,你怎么能这么说?提示,停止忽略“VirtualProtect”的返回值。首先重新阅读文档并专注于返回值。 (3认同)
  • 嗯,正如我在答案中所说的那样。你传递了一个未初始化的指针,别无所求。总是有`GetLastError`。 (3认同)
  • 您传递了一个未初始化的变量。你还期待什么? (2认同)