Инструкция lodsb вызывает переполнение стека

Я хочу искать паттерн в памяти текущего процесса. Я запрашиваю страницы памяти, используя 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 stackru 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 

1 ответ

Решение

Вы, вероятно, исследуете страницы, которые зарезервированы для стека. Это может привести к выделению новых страниц стека и в конечном итоге к переполнению стека. Из службы поддержки Microsoft:

В операционной системе Microsoft Windows NT переполнение стека обнаруживается аппаратными и программными средствами, работающими вместе с использованием механизмов защиты страниц. Каждый новый процесс Windows NT имеет максимальный зарезервированный размер стека и начальное выделение выделенного стека. Выделенная память физически выделяется для процесса и поддерживается файлом подкачки; это относительно "дорогой" ресурс. Зарезервированная память - это адресное пространство, которое не отображается в реальную память; это относительно "дешевый" ресурс.

По мере роста стека он перемещается из выделенной части памяти стека в зарезервированную или незафиксированную память. Когда это происходит, происходит сбой страницы, и операционная система фиксирует в стеке другую страницу памяти. Если сбой страницы происходит, когда стек уже достиг максимального заданного размера, система сообщает об исключении переполнения стека.

Этот метод автоматического роста использует защитную страницу, зарезервированную, незафиксированную страницу памяти, которая смежна с выделенной частью памяти. Когда приложение касается страницы защиты, операционная система фиксирует эту страницу, и следующая незафиксированная страница становится новой страницей защиты. Автоматический рост стека работает только для защитной страницы, а объем стека должен увеличиваться с шагом 4 КБ или одной страницы. Если приложение касается другой зарезервированной, но незафиксированной страницы стековой памяти, прежде чем оно коснется защитной страницы, возникает обычное исключение сбоя страницы, что может привести к непредсказуемому поведению.

Другие вопросы по тегам