#include <stdio.h> #include <string.h> #include <stdlib.h> typedef int (*funcPtrType)(int, int); int foo(int a, int b) { return a + b; } void main() { // Instructions in buf are identical to what the compiler generated for "foo". char buf[201] = {0x55, 0x8b, 0xec, 0x8b, 0x45, 0x08, 0x03, 0x45, 0x0c, 0x5D, 0xc3 }; int i; funcPtrType ptr; #ifdef GOOD char* heapBuf = (char*)malloc(200); printf("Addr of heap buf: %x\n", &heapBuf[0]); memcpy(heapBuf, buf, 200); ptr = (funcPtrType)(&heapBuf[0]); #else // BAD printf("Addr of local buf: %x\n", &buf[0]); ptr = (funcPtrType)(&buf[0]); #endif for (i=0; i < 1000000000; i++) ptr(1,2); }
运行此结果的结果是:
$cl -DGOOD ne3.cpp
Microsoft(R)32位C/C++优化编译器版本11.00.7022适用于80×86
版权所有(C)Microsoft Corp 1984-1997.版权所有.
ne3.cpp
Microsoft(R)32位增量链接器版本5.10.7303
版权所有(C)Microsoft Corp 1992-1997.版权所有.
/out:ne3.exe
ne3.obj
$time ./ne3
堆buf的地址:410eb0
真正的0m 4.33s
用户0m 4.31s
sys 0m 0.01s
$
$
$cl ne3.cpp
Microsoft(R)32位C/C++优化编译器版本11.00.7022适用于80×86
版权所有(C)Microsoft Corp 1984-1997.版权所有.
ne3.cpp
Microsoft(R)32位增量链接器版本5.10.7303
版权所有(C)Microsoft Corp 1992-1997.版权所有.
/out:ne3.exe
ne3.obj
$time ./ne3
本地buf的地址:12feb0
真正的6m41.19s
用户6m40.46s
sys 0m 0.03s
$
谢谢.
> Shasank
堆栈保护安全?作为一个疯狂的猜测,您可能会遇到基于MMU的堆栈保护方案.许多安全漏洞基于故意的缓冲区溢出,将可执行代码注入堆栈.解决这些问题的一种方法是使用不可执行的堆栈.这会导致进入操作系统的陷阱,我认为操作系统或某些病毒SW可能会执行某些操作.
负i-cache一致性互动?
另一种可能性是使用对附近地址的代码和数据访问都会破坏CPU缓存策略.我相信x86实现了一个基本上自动的代码/数据一致性模型,这可能导致在任何内存写入上大量附近的缓存指令失效.你不能通过改变你的程序来不使用堆栈(显然你可以移动动态代码)来解决这个问题,因为堆栈是由机器代码一直编写的,例如,每当推送参数或返回地址时程序调用.
这些天CPU相对于DRAM甚至是外层缓存环都非常快,所以任何破坏内部缓存环的东西都会非常严重,而且它的实现可能涉及CPU实现中的某种微陷阱,其次是HW中的“循环”使事物无效.英特尔或AMD不会担心速度问题,因为对于大多数程序来说,它永远不会发生,而且一旦发生,它通常只会在加载程序后发生一次.