Защитись и замети! Коваленко Дмитрий aka Ingrem Спецвыпуск Xakep, номер #045, стр. 045-068-5 Запомним "аварийный" адрес 0x486723, закроем WinRAR. С помощью Symbol Loader загрузим winrar.exe в Soft-Ice. Symbol Loader матюгнется на отсутствие отладочной информации, но winrar.exe загрузит. Поставим брэйкпоинт и выйдем из отладчика: :bpx 486723 :x Снова попробуем открыть 29A.RAR. Брэйкпоинт срабатывает, всплывает окно отладки. EIP указывает на инструкцию 001B:00486723 | ADD [EAX],AL. Именно она приводит к аварийному завершению. Поскольку мы имеем дело с переполнением стека, управление на эту "смертельную" инструкцию, скорее всего, передается инструкцией ret. Посмотрим, какое слово лежало на стеке непосредственно перед тем, как ret выполнилась (поскольку мы имеем дело со стеком, у тебя вместо 0x00125A68 вполне может быть какой-то другой адрес): :dd esp-4 0010:00125A68 | 0048671A 001270B6 001270B0 00128DE0 | .gH..p..p.. 0010:00125A78 | 00000000 001270B6 00125BA0 0044F2D2 | ....p..[..D Получается, что управление передается на адрес 0x0048671A. Посмотрим, что лежит по этому адресу (:u 48671A). В окне кода видим: ...... 001B:0048671A | ADD EAX, 00000000 001B:0048671F | ADD AH, AH 001B:00486721 | DEC AX 001B:00486723 | ADD [EAX],AL ; >-- it's just a little crash... ...... Ранее мы уже выяснили, что к аварийному завершению приводит инструкция по адресу 0x00486723. Теперь мы знаем, что перед ней выполняются еще три инструкции. Уже кое-что... Выйдем из отладчика и подумаем (WinRAR тем временем опять завалится ;-)). Фактически причиной передачи управления на 0x0048671A является двойное слово, записанное по адресу 0x00125A68. Значит, нужно отловить инструкцию, которая это двойное слово туда записывает. Опять загружаем winrar.exe в Soft-Ice. Ставим брейкпоинт на память 0x00125A68 :bpm 00125A68. Ого! На этом брейкпоинте WinRAR постоянно вылетает в отладку. И это он еще даже окно не успел создать! Воистину программы на C++ много работают со стеком. Временно отключим поставленный брейкпоинт: :bd * , подведем курсор к 29A.RAR, включим поставленный брейкпоинт – :be *. Попытаемся открыть 29A.RAR. Каждый раз, когда будет всплывать окно отладчика (а таких разов будет больше десятка), будем проверять, не записано ли по адресу 0x00125A68 двойное слово 0x0048671A – :dd 00125A68. В конце концов мы поймаем некую инструкцию по адресу 0x0047366A: ...... 001B:00473659 | CLD 001B:0047366A | REPE MOVSD ; >-- вот оно! 001B:00473673 | POP EDI ...... Она и заносит в 0x00125A68 интересующее нас двойное слово. Посмотрим на пойманный код. Похоже на внутренности какой-то строковой HLL-функции, правда? Запомним адрес 0x0047366A и на всякий случай нажмем F12. Если адрес 0x0047366A – действительно часть функции, нужно узнать, откуда ее вызвали. Остановка происходит на адресе 0x00453D69: ...... 001B:00453D63 | PUSH ECX 001B:00453D64 | CALL 473648 ; >-- интересующий нас вызов 001B:00453D69 | ADD ESP, 8 ...... Запомним и его тоже. Отключим все брейкпоинты и выйдем из отладки. Загрузим WinRAR в IDA. Пока IDA его дизассемблирует, пойдем попьем пива. Когда вернемся, посмотрим, куда указывает адрес 0x0047366A. А он указывает в середину функции сравнения строк. Разберемся, как она работает. |