Привет, млин у меня нет возможности поставить SP2, и у знакомых нету его, вощем вопрос: в этом сервис паке нельзя выполнять код в стэке а если я код положу в буфер и выполню ошибка будет? например Код (Text): mov Buff, 0c3h call Buff
Leroy > "если я код положу в буфер и выполню ошибка будет?" Если страница памяти, которой принадлежит буфер, имеет атрибут executable, то ошибки не будет никогда Если же не executable, то зависит от поддержки и установок режима DEP - data execution prevention: 1) поддерживает ли проц хардварный DEP 2) какой режим контроля установлен в системе (вкл или выкл для всех или только для системных файлов) Если проц не поддерживает DEP, то винда использует ограниченный программный DEP - контролирует атрибут executable только при обработке исключений (поэтому про эксепшены при выполнении кода на стеке лучше забыть
Вообщем я пишу криптор, мне нужно просто передать управление носителю, я делаю так Код (Text): mov eax, [ebp+offset oep] jmp eax вызовит это ошибку в SP2 или делать GlobalAlloc кидать туда адрес и выполнять там? заранее thanks ))
leo > Скорее всего, это неверно. Вот код из одного пакера, который не только работает на XPSP2 (программный DEP только для системных файлов), но ещё и сайс отлавливать пытается. Код (Text): mov si,'FG' ; magic values fcall ecx,09Ah lea edx,[ebp+@after_int] ; handler offset fcall eax,069h mov di,'JM' ; magic call @set_seh lea edx,[edx-(@after_int-@exit_process)] fcall ebx,0E8h db 68h ; push dword db 0CCh ; int 3 <-------+ db 0FFh,0E2h ; jmp edx | db 9Ah ; junk | ; | jmp esp ; --------------+ db 069h @exit_process: jmp dword ptr[ebp+_ExitProcess] ; exit process db 0E9h @after_int:
S_T_A_S_ > "Скорее всего, это неверно" Скорее всего, это просто неточно Программный DEP контролирует не EIP исключения, а принадлежность точки входа в обработчик к executable memory. Насколько я понимаю, в приведенном примере точка входа lea edx,[edx-(..)] не находится в стеке ? Leroy > "вызовит это ошибку в SP2 или делать GlobalAlloc кидать туда адрес и выполнять там?" GlobalAlloc ничего не даст, т.к.стратегия DEP в равной мере относится к предотвращению исполнения "данных" (кода) как в стеке так и в стандартной куче. Чтобы не было проблем совместимости (в будущем) нужно использовать VirtualAlloc с флагом PAGE_EXECUTE_READWRITE. А вот насчет вопросов "нельзя выполнять код в стэке" и "вызовет это ошибку в SP2", могу только посоветовать еще раз почитать статью о DEP. Если проблемы с инглишем, то есть и русский вариант Изменения в функциональных возможностях Microsoft Windows XP с пакетом обновления 2 (SP2) Часть 3. Технологии защиты памяти. Хотя по сравнению с англ.вариантом есть неточности перевода, в частности искажен смысл программного DEP: получается, что он сам "регистрирует" или "размещает" SEH-обработчик, а на самом деле перед тем как вызвать обработчик DEP проверяет его валидность, т.е.зарегистрирован ли он в сл.SafeSEH или же принадлежит executable памяти в сл.обычного SEH. Резюме ИМХО такое, что на сегодняшний день полноценный аппаратный DEP это лишь путь развития, стратегия повышения безопасности: "Предполагается, что в будущем все 32- и 64-разрядные процессоры будут поддерживать аппаратное предотвращение выполнения данных. Майкрософт расширяет сотрудничество с производителями процессоров в целях содействия принятию и развитию технологий DEP". Пока же это дело будущего, если учесть огромный парк существующих компьютеров, не поддерживающих аппаратный DEP, и проблемы совместимости существующего программного обеспечения с технологией DEP. Поэтому Майкрософт и оставляет лазейки для частичного или полного отключения этого режима. На сегодняшний день, если проц не поддерживает аппаратный DEP, то XP SP2 включает программный DEP: по умолчанию только для "основных программ и служб Windows", но шустрый админ может включить его и для всех программ "кроме перечисленных" или наоборот отключить совсем, прописав в boot.ini /noexecute=AlwaysOff. Программный DEP ИМХО не может запретить исполнение любого "безобидного" кода в стеке или куче, он действует только в отношении SEH-обработчиков - перед тем как вызвать обработчик проверяется его валидность - он должен быть либо зарегистрирован (SafeSEH), либо принадлежать executable памяти.
leo > А это не точка входа, а точка выхода Код на стэке (как видно из приведённого листинга) запускается так: Код (Text): push 0x9AE2FFCC jmp esp
S_T_A_S_ Повторяю для невнимательных Для програмного DEP пофиг где исполняется код - хошь в стеке, хошь где. Писец наступает тогда, когда возникает исключение и диспатчер обнаруживает передачу управления на SEH-обработчик, находящийся в памяти недоступной для исполнения. Если даже исключение возникает при исполнении кода в стеке, но SEH-обработчик находится в code или в executable памяти, то все проходит нормально. А из твоего листинга явно НЕ видно где находится вход в SEH, но обычно call @set_seh это и есть запушивание указателя на SEH-handler, который идет сразу за этим call. Чтобы не быть голословным, проверил несколько примерчиков на XP SP2 (без аппаратного DEP). Результаты такие: 1) "Обычный" код в стеке работает нормально как при OptIn, так и при OptOut. Тоже самое и в случае когда код в стеке вызывает исключение, но SEH обработчик находится в code. 2) Попытка поместить SEH обработчик в стек приводит к тихой смерти проги НЕЗАВИСИМО от OptIn или OptOut !!! Если запустить под OllyDbg, то происходит останов на исключении, но передать его в прогу не удается = висяк. В win 98SE этот код прокатывает нормально - ошибок нет. (PS: про выравнивание стека просьба не напоминать 3) Если поместить SEH в Buf=HeapAlloc(), то поведение зависит от OptIn\OptOut. При OptIn ес-но все работает нормально, а при OptOut ось задумывается на несколько секунд и затем выводит сообщение: типа сработала защита, просим извинить за причиненные неудобства, выберите действия - включить данную прогу в список "кроме" или закрыть как зловредную, отправить отчет в майкрософт и т.д. и т.п. Если при OptOut включить прогу в список "кроме", то она ес-но работает нормально.
В SafeDisc используется выполнение кода из стека. Делается VirtualProtect на нужный участок (16 байт) c PAGE_EXECUTE_READWRITE. Работает с аппаратным DEP.
Да, сделать страничку стека executable можно VirtualProtect'ом и соотвественно исполнять код в стеке тоже можно, но только не SEH-обработчик. Проверка того, что обработчик принадлежит области стека делается в KiUserExceptionDispatcher, точнее в функции ntdll.7C9377C1, которая много чего проверяет, но первым делом - выравнивание записи SEH-chain в стеке, затем принадлежность адреса обработчика диапазону StackLimit..StackBase, и только потом идет проверка на executable. Если адрес обработчика находится в стеке, то кранты - устаналивается "страшный" ExceptionFlag = 8 (ExceptionCode не изменяется) и на выход с вещами в ZwRaiseException. Без отладки прога умирает быстро и бесшумно - никаких сообщений ось почему-то не выдает. А вот под отладчиком все происходит довольно мирно. Если отладчик перехватывает исключение, то не может передать его программе, т.к. ось наотрез отказывается передавать управление в стек и в тоже время не желает вызывать следующий по цепочке обработчик (или финальный). Если отладчик игнорирует исключение, то ось поступает более изощренно - передает управление на начало инструкции, вызвавшей исключение, устанавливая флаг трассировки (int1). Если пытаться продолжить выполнение, то путешествие повторяется по кругу KiUserExceptionDispatcher -> ZwRaiseException -> ошибочная инструкция. Единственный выход - заменить в отладчике ошибочную инструкцию или ее операнды, чтобы устранить исключение, ну или самому прибить прогу. Вот такая "демократия"