我分配了一些空间,写了一些asm并试图在那时开始一个线程。 但我一直在违反访问权限。它假设要推四个0并调用messageboxa函数。但是在区域地址处,它会遭到访问冲突。 如何让它像普通代码一样运行?
void test2()
{
byte* area;
HANDLE process;
area = new byte[1024];
for(int i = 0; i < 1024; i++)
area[i] = 0;
memmove((char*)area, "\x6a\x00\x6a\x00\x6a\x00\x6a\x00\xE8", 9);
*(DWORD*)&area[9] = ((DWORD)GetProcAddress(GetModuleHandle("User32.dll"), "MessageBoxA") - (DWORD)&area[9] - 4);
memmove((char*)&area[13], "\x33\xc0\xc3", 3);
VirtualProtect(area, 17, PAGE_EXECUTE_READWRITE, 0);
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)area, 0, 0, 0);
}
这是反汇编的屏幕截图 http://screensnapr.com/v/P33NsH.png
答案 0 :(得分:1)
VirtualProtect()
调用在这种情况下没有做任何事情:它只是失败,因为它希望第4个参数是一个有效的指针,指向一个接收先前访问保护标志的内存区域(所以你可以恢复它)后来)。因此,CPU拒绝执行此页面,并在第一条指令处获得GPF。
您还需要使用PAGE_EXECUTE_READ
作为标志,否则第一个堆操作(甚至对堆中任何其他变量的读访问,碰巧碰到同一页)将生成GPF。或者,使用VirtualAlloc()
,而不是在堆上分配。
注意,我没有检查其余的代码,因此可能还有其他一些问题。另请注意,这不是编写程序集的方法,除非您正在编写漏洞利用程序(弄乱VirtualProtect()
是一个明确的迹象)。这是希望我对这个漏洞利用的假设是错误的。