两种线程栈的溢出

第一种情况代码很简单:

int main()
{
	int nValue[100];
	nValue[10000] = 0;
	return 0;
}

在这里插入图片描述
X86的CPU页面大小为4KB,而我们只使用了100*4=400byte的空间(没有超出默认调拨的存储器大小(第二个页面4KB),所以栈不会给下面的页面再调拨存储器了)。

而我们的nValue[10000] = 0;试图写入第10000*4 = 40000,也就是试图网40000+nValue处写入数据(在栈的第10个页面处),这块内存并没有被调拨物理存储器,所以会发生内存读取错误。


第一种情况理解了,我们来看第二种情况


#include<Windows.h>
#include<iostream>
#include<process.h>
DWORD WINAPI ThreadFunc(PVOID pvParam);
int main()
{
	HANDLE ThreadHandle = (HANDLE)_beginthreadex(NULL, 0, (_beginthreadex_proc_type)ThreadFunc, NULL, 0, NULL);


	WaitForSingleObject(ThreadHandle, INFINITE);
	CloseHandle(ThreadHandle);
	return 0;
}

DWORD WINAPI ThreadFunc(PVOID pvParam)
{
	BYTE aByte[0x10];
	MEMORY_BASIC_INFORMATION mbi;
	SIZE_T size = VirtualQuery(aByte, &mbi, sizeof mbi);
	SIZE_T s = (SIZE_T)mbi.AllocationBase + 1024 * 1024;
	PBYTE pAddress = (PBYTE)s;
	BYTE* pBytes = (BYTE*)VirtualAlloc(pAddress, 0x10000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	*pBytes = 0x5;
	//这里系统无法检测到内存被破坏,因为紧接着线程栈的后面已经有另一块已经调拨的
	//地址空间了,所以不会有栈溢出异常。
	//但是事实是内存确实被破坏了
	aByte[pBytes-aByte] = 1;
	return 0;
}

在这里插入图片描述

执行完*pBytes = 0x5;在pBytes内存第一个字节为0x05,这是没什么问题,因为是我们赋值的
但是执行aByte[pBytes-aByte] = 1;这句的时候我们再看内存

在这里插入图片描述
变成0x01了,为什么就不用多说了吧,因为我们手动给他接下来的页面调拨了物理存储器VirtualAlloc(pAddress, 0x10000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);自然不会发生栈溢出啦


特此声明,我是一个没什么分享精神的沙雕,不保证正确,只作为自己学习使用。

发布了5 篇原创文章 · 获赞 0 · 访问量 247
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览