我想在当前进程的内存中搜索一个模式。我使用VirtualQuery查询内存页面以提取感兴趣的范围。问题是连续循环5分钟后,程序由于stackoverflow崩溃而崩溃。进程分配的内存大小变大。
问题出在以下循环中:
valid_range:
pushad
mov eax, [ebp]
mov esi, [eax] ; memory range start
mov ecx, [eax + 12] ; memory range size
xor eax, eax
loopmem:
lodsb ; this causes stackoverflow after certain time ????
dec ecx
cmp ecx, 0 ; we loop trough memory until we finish it
; reduced the code to minimum
je finish_range
jmp loopmem
finish_range:
popad
ret
您可能正在探查为堆栈保留的页面。这可能会导致分配新的堆栈页面,并最终导致堆栈溢出。来自Microsoft支持:
在Microsoft Windows NT操作系统中,使用页面保护机制,由硬件和软件一起检测堆栈溢出。每个新的Windows NT进程都有一个最大的保留堆栈大小和一个初始提交的堆栈分配。承诺的内存是物理分配给进程的,并由页面文件支持;它是一种相对“昂贵”的资源。保留内存是未映射到实际内存的地址空间;它是一种相对“便宜”的资源。
随着堆栈的增长,它会从堆栈内存的已提交部分移至保留或未提交的内存中。发生这种情况时,将发生页面错误,并且操作系统会将另一页内存提交到堆栈中。如果堆栈已增长到其最大指定大小时发生页面错误,则系统将报告堆栈溢出异常。
这种自动增长方法使用保护页,与内存的已提交部分连续的保留的,未提交的内存页。当应用程序触摸保护页面时,操作系统将提交该页面,而下一个未提交的页面将成为新的保护页面。自动堆栈增长仅适用于保护页,并且堆栈内存必须以4K或一页的增量增长。如果应用程序在触摸保护页面之前先触摸了堆栈存储器的另一个保留但未提交的页面,则将发生正常的页面错误异常,并且可能导致不可预测的行为。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句