【问题标题】:lodsb instruction causes a stack overflowlodsb 指令导致堆栈溢出
【发布时间】:2015-05-23 10:00:35
【问题描述】:

我想在当前进程的内存中搜索模式。我使用 VirtualQuery 查询内存页面以提取感兴趣的范围。问题是在连续循环 5 分钟后,程序因堆栈溢出而崩溃。进程分配的内存越来越大。

问题在于这个循环:

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 

【问题讨论】:

  • 如果我注释掉 lodsb 一切顺利
  • 出现堆栈溢出有点奇怪,但您可能希望确保只接触已提交且未设置 PAGE_GUARD 属性的页面。
  • 是的,看起来内存范围是错误的,但仍然无法解释为什么读取内存会增加它。

标签: nasm shellcode


【解决方案1】:

您可能正在探测为堆栈保留的页面。这可能会导致分配新的堆栈页面并最终导致堆栈溢出。来自Microsoft Support

在 Microsoft Windows NT 操作系统中,堆栈溢出是由硬件和软件一起使用页面保护机制检测的。每个新的 Windows NT 进程都有一个最大保留堆栈大小和一个初始提交的堆栈分配。已提交的内存物理分配给进程并由页面文件支持;它是一种相对“昂贵”的资源。保留内存是没有映射到真实内存的地址空间;它是一种相对“便宜”的资源。

随着堆栈的增长,它会从堆栈内存的已提交部分移动到保留或未提交的内存中。发生这种情况时,会发生页面错误,并且操作系统会将另一页内存提交到堆栈。 如果在堆栈已经增长到其最大指定大小时发生页面错误,系统会报告堆栈溢出异常。

这种自动增长方法使用保护页,即保留的、未提交的内存页,它与已提交的内存部分相邻。 当应用程序接触到保护页面时,操作系统会提交该页面,下一个未提交的页面将成为新的保护页面。 自动堆栈增长仅适用于保护页面并且堆栈内存必须以 4K 增长,或者一页,递增。如果应用程序在接触保护页面之前接触了另一个保留但未提交的堆栈内存页面,则会发生正常的页面错误异常并可能导致不可预知的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2015-12-21
    相关资源
    最近更新 更多