防止VC调用chkstk函数

微软的C\C++编译器老是很是的弱智,不但随便乱插运行时函数,还随便加进乱七八糟的引用,致使程序难以通用。例如__chkstk函数,只要你使用8120字节以上的局部变量,他就会偷偷调用(CALL)该函数, 例如 
int Data[8192];
int *P=(int*)&Data;
for(int I=0;I<8192;I++,P++)
{
*P=(int)I;
函数

反汇编结果,在进行for循环以前,他会隐藏调用__chkstk。该函数 汇编伪代码以下: oop

 

;探测堆栈 
ALIGN DWORD
chkstk PROC USES EBX EDX ESI EDI mov eax,esp
mov ecx,32
@@:
sub esp, 1000H
test BYTE PTR[esp],0
loop @B
mov esp,eax
ret chkstk 测试

ENDP 命令行

 

其本质来讲 就是访问下堆栈,引起缺页异常,系统检测到这种操做后,将该页提交
因而就能够访问了. 


但咱们的问题有三:
1:随便乱CALL致使代码不可总体搬移.
2:在内核即便探测也没用,内核堆栈只有8KB,探测也不会提交,更不会增大.
3:偷偷摸摸乱增长引用增长了调试难度. 若是咱们真的须要增大堆栈,那么在用户态,咱们彻底能够ZwAllocateVirtualMemory分配10-20MB,在内核态咱们能够用ExAllocatePoolWithTag分配几MB,而后 mov esp,xxxxxxxx.

 调试

所以这种鸡肋的功能没有必要留在程序里.可是翻遍MSDN,没有找到取消的办法,最后在编译器参数里(项目->属性->配置属性->C/C++->命令行->其余选项),找到某个参数,说明以下:编译器

/Gs 设置堆栈检查字节数. 咱们使用/Gs8192设置堆栈检查字节为8MB,经测试,对 __chkstk的调用没有了,成功达到咱们的目的.it

相关文章
相关标签/搜索