Как добавить возможность исполнения кода на стеке в PE файле? (Windows 7, ASM)

Рейтинг: 2Ответов: 1Опубликовано: 28.04.2011

Проблема такая.
Имеется программа (исполняемый PE файл), нужно дать ей возможность исполнять код на стеке (я знаю к каким последствиям это может привести). По умолчанию ОС не дает этого делать.

Собственно вопрос: Можно ли это сделать, путем изменения какого-либо ключа в реестре?
Если это нельзя изменить в реестре то может, можно подправить заголовок исполняемого файла?

Сразу, возник второй вопрос.
Как сказать ОС, что бы она не прятала стек по разным адресам и возможно ли такое?

Ответы

▲ 5Принят

Boot.ini

/noexecute=уровень_политики

Msdn

Локальные куки. После формирования Bp-фрейма (стекового фрейма) в переменную, находящуюся в стеке ниже, чем адрес возврата из функции, загружаются куки - рандомное значение. При возврате из функции оно сравнивается с исходным и если отлично, то генерится STATUS_STACK_BUFFER_OVERRUN:

В некоторых случаях эта техника позволяет избежать зацикливания и рекурсивных вызовов. Например, при захвате куков. В XP используется программная защита (DEP) стека от переполнения посредством куков. Следует рассмотреть механизм подробнее. В самом начале исполнения уязвимой процедуры в стеке сохраняется значение переменной

__security_cookie: RtlCreateUserThread: push 324 push 7C92E140 call _SEH_prolog mov eax,dword ptr ds:[__security_cookie] mov dword ptr ss:[ebp-1C],eax ... mov ecx,dword ptr ss:[ebp-1C] call __security_check_cookie call _SEH_epilog ret 28

Перед возвратом из процедуры сохранённое в стеке значение сравнивается со значением переменной и если они отличаются либо старшая часть сохранённого значения отлична от нуля, генерируется исключение STATUS_STACK_BUFFER_OVERRUN:

__security_check_cookie: cmp ecx,dword ptr ds:[__security_cookie] jnz __report_gsfailure test ecx,FFFF0000 jnz __report_gsfailure ret __report_gsfailure()

сохраняет контекст потока и вызывает финальный обработчик исключений посредством RtlUnhandledExceptionFilter(). В нём происходит нотификация отладчика посредством DbgPrint() и далее vDbgPrintExWithPrefix(). Последняя функция защищена куками. Если использовать захват куков загрузкой в старшую часть переменной __security_cookie значения, отличного от нуля (тогда при возврате из многих функций произойдёт вызов __report_gsfailure()), это приведёт к рекурсивным вызовам до исчерпания стека, после чего процесс будет завершён ядром. Для предотвращения этой ситуации можно использовать технику IDP...

Это препятствует локальным переполнениям буферов. Разумеется контролировать механизм нельзя, пока он не будет исполнен(то есть пока код не получит через него управление).

Защита памяти от исполнения. Этот механизм многоуровневый. Смотрите тут uninformed.org

А вобщем это бесмысленный вопрос, какже вы измените ключи реестра, если вашему коду мешает исполняться DEP :) В противном случае достаточно изменить атрибуты памяти, указав флаг PAGE_EXECUTENtProtectVirtualMemory или в соотв. апи).

Отключить ASLR для стека, TEB и PEB нельзя.