Автор: Сергей Чубченко. Дата публикации: 19.08.2006
У любого аналитика бывают ситуации, когда под рукой кроме HEX редактора/дизассемблера hiew ничего нет, а исследовать тот или иной код нужно. Причем нужно бывает срочно. Такое обычно требуется в самых неожиданных местах: в гостях у друзей, если компьютер заражен непонятным вирусом, а с собой естественно ничего нет, в коммандировке, когда с собой только телефон. Да мало ли разных ситуаций. Бывает доходит до смешного, когда наемный программист поставит привязку к жесткому диску, а нужно срочно перенести АРМ (автоматизированное рабочее место, не путать с ARM) с одного компьютера на другой. Конечно можно пригласить автора АРМ’а и попросить его, но обычно на это банально нет времени и или писался код настолько давно, что на звонок тому работнику можно услышать "извини, код уже лет пять не пишу, работаю в автосервисе слесарем". Вот как раз для таких ситуаций и потребуются знания из этой статьи. Итак вперед!
Введение
Многие аналитики привыкли использовать довольно массивный комплект из различных утилит для исследования кода. Это и отладчик SoftICE или OllyDbg, это и дизассемблер IDA Pro, это и файловый анализатор PEiD и редактор PE Tools. И еще целая гора специализированного и нужного софта. Но нужно ли реально столько инструментов? Для большинства несложных задач по анализу кода можно вполне обойтись HEX редактором и дизассемблером, причем не самым идеальным. Все дело в том что многие вещи можно сделать и самому не прибегая к мощности утилит. Здесь я Вам расскажу как исследовать код только с помощью HIEW. Этот дизассемблер я выбрал не случайно - его всегда легко найти в локальной сети в любом крупном предприятии, хоть и старую версию, накрайняк скачать (вес утилиты порядка мегабайта) и он в своем составе имеет хороший HEX редактор, потому и пользуется везде спросом. Итак кроме комьютера и сети под руками у Вас ничего нет и стоит задача банально запустить неработающий АРМ, привязанный к старому диску. Давайте рассмотрим как выполнять различные операции по анализу кода в этом замечательном дизасме.
Сам себе PE Sniffer
Главным для аналитика всегда являлось локализовать компилятор/упаковщик, дабы знать с чем он имеет дело и какой подход ему использовать. Не спорю, что найдя упаковщик Вам как минимум потребуется его распаковать и тут уже без автораспаковщика не обойтись. Но обычно для узкоспециализированных утилит, которые писались по заказу штатным разработчиком, это не актуально. В таких случаях обычно не используются никакие упаковщики, так как клиент один и он всегда платит, а потому программист делает защиту только для того, чтобы клиент ее никому потом не перепродал и чтобы его услуги были востребованы. Конечно идея хорошая, но порой самому клиенту приходится апгрейдить комп и тут приходится чтото делать. И в этот момент обычно уже прошло много лет со времен разработки и человека уже не найти.
Локализация компилятора, которым собрана программа, будет не менее полезна. Для Delphi и Visual Basic потребуются разные знания и подготовка. Начнем с того, что откроем программу в hiew и посмотрим на гору ASCII символов. Что нить понятно?
При запуске экран хиева ничуть не отличается от экрана FAR’а в режиме просмотра файла
Нажмем дважды Enter и смотрим на более понятный дизассемблированный код. Дабы он стал еще понятнее - нажмите F8 и F5 - hiew перейдет на тот участок кода, который находится в точке входа. Внимательно взглянув на этот код уже можно понять на чем он написан. К примеру для Delphi программ код будет подобен этому:
Не узнать его нельзя... просто несколько Call вызовов, стандартных в Delphi программах. Если опять перейти в текстовый режим и нажать и подержать PgUp в самом верху увидим названия секций. Вот примерный расклад для нетронутых защитой Delphi программ:
CODE
DATA
BSS
idata
tls
rdata
.reloc
.rsrc
Итак с дельфями определились, теперь поговорим про C++ Builder. Тут вообще все проще. На оригинальной точке входа всегда такой код:
Байты, расположенные между jmp’ом и mov’ом это строчка "C++HOOK" Тоже все просто :) Что же насчет бейсика? А у него всегда 2 команды на точке входа:
По адресу 0004016EC всегда VBHeader, начинающийся с сигнатуры "VB5!".
Начало структуры, описывающей любую VB программу
Как видим не так уж и требуется PEiD для определения компилятора, а что же про упаковщики? А здесь можно даже не смотреть на точку входа. Достаточно в текстовом виде поглядеть на EXE заголовок. UPX пихает в начало первой секции сигнатуру "UPX!", а секции обзывает ".UPX0", ".UPX1", ".rsrc", причем секций три вне зависимости от того сколько их было до упаковки.
Если же взглянуть на точку входа, то откроется довольно стандартный для всех версий UPX’а код:
Подробнее о самом алгоритме распаковки и восстановлении импорта можете прочитать в моих статьях: Учимся распаковке DLL библиотек и Распаковываем UPX Shit v0.06. Я же продолжу рассказ о детекте других упаковщиков. Следующим по распространенности является FSG и с недавних пор Upack. Их узнать очень легко даже взглянув на текстовое представление EXE заголовка - он крайне оптимизирован и обычно там нет стольких ненужных нулевых байт выравнивания, сколько оставляют другие пакеры. А Upack даже заносит импорт прямо в DOS Header после MZ.
UPack жмет программу так, что от заголовка остается только MZ, после которого идет импорт. Жаль антивирусы не разделяют эту идею оптимизации.
Все просто, только hiew. Кстати еще есть метода легко отличать MS компиляторы от борландовых: по присутствию "Rich" строки после DOS Header’а. В общем если держать в голове все эти методики плюс иметь неслабый опыт - можно определить любой компилятор или упаковщик в hiew’е, это приходит со временем потому начинайте сейчас!
Стринг референсы
Лучшим помощником реверсера являются стринг референсы - перечень всех строковых данных, встречающихся в программе и адресов, где происходит обращение к этим строкам. Так вот в hiew’е это тоже есть! Достаточно в HEX режиме поставить курсор на начало любой строки и нажать F6 - сразу перейдем на первое обращение к этой строке! Вкупе с этим есть возможность искать русские строки. Жмем F7 и пишем "Ошабка запуска программы" и жмем Enter. Если нужно искать все места где встречается строка, жмем Shift + F7 - хиев найдет следующий адрес где имеется строчка. Так как же он находит русские строки? Ведь они могут быть и в DOS и в windows кодировке - все просто, нужные знания даем ему мы сами, для этого перед поиском необходимо в текстовом режиме нажать F8 и выбрать кодировку. Именно используя ее хиев и будет искать строку, то есть универсальности конечно не получится, но это куда лучше, чем любоваться только на английские строки в Olly.
Серфинг по EXE
Порой когда смотришь дизассемблерные листинги так и хочется перейти по адресу по которому указывает jmp, call или даже mov. Хиев и тут не подведет - каждому адресу на экране присваивается уникальное число, нажав которое на клавиатуре - мы перейдем куда надо, вот пример:
(1) и (2) - это как раз эти самые числа. Чтобы нам перейти по указанным адресам, жмем на клавиатуре эти самые числа (или буквы, если переходов больше 9). Цифровость задается в hiew7.ini и Вы можете сделать, чтобы вместо чисел были например китайские иероглифы. Теперь остановимся на перемещениям по EXE вручную. F5 позволяет перейти на указанный адрес, причем если просто ввести адрес - перейдем по Offset’у, а если перед адресом поставить точку, то хиев перейдет по виртуальному адресу. Очень удобно, причем даже в коде эти адреса можно переключать нажимая Alt + F1. Перейти к началу нужной секции также просто - достаточно нам зайти в PE заголовок нажав F8,затем кнопку F6 и выбрав нужную секцию из списка мы переместимся в ее начальный адрес. А что если нужно перейти в начало таблицы импорта или TLS? Искать их самому? Зачем? F8, затем F10 - мы перейдем к таблице директорий NTHeader’а. В ней просто выбираем нужное поле и жмем Enter. Вот так вот старый добрый хиев помогает в нелегком деле.
Ассемблируем
Исследовать мало - нужно править код, причем не все помнят машинные коды и не все могут ориентироваться в составлении mod/rm флагов и не все могут кодировать регистры в уме, потому править просто в HEX редакторе немного неудобный метод (хотя я написав весь движок DotFix LiteProtect’а чисто в hiew уже привык кодировать в уме, но эт так к слову). Хиев не оставит Вас в беде, он представляет мощный ассемблер. Нажмем F3 дабы править код, а затем дрожащим пальцем ткнем в клавишу Tab. О чудо, в появившейся текстовой строке можно писать команды прямо на ассемблере, причем нажав Enter можно набирать уже следующую команду и так хоть весь код.
Пишем программу как настоящие ассемблерщики, безо всяких сред программирования
Как видите - не все так сложно, как казалось, когда Вы начинали читать эту статью. Если в процессе набора кода Вы ошибетесь - помните, практически любой введенный код можно отменить нажимая F3. Когда уже написали что надо - жмите F9 для записи в файл. Вот незадача, после записи файл не запускается - приходится выходить из hiew, чтобы снять залоченность. Но и это обходится. Открываем hiew7.ini и ищем строку "ReopenAfterEdit" и ставим ее в "On". Теперь после редактирования файл будет закрываться и снова открываться для чтения, поэтому его можно будет запустить после каждой правки. Спросил я у автора, зачем он так не сделал в дефолтных настройках и меня настолько порадовал его ответ - "чтобы люди читали хелп" :) Так что почитайте хелп и комментарии ко всем строкам hiew7.ini, узнаете много нового.
Декриптуем XOR
С некоторых пор повелось, что каждый программист, разобравшийся с PE форматом пишет свой протектор EXE файлов. Как не странно, явление сие постоянно процветает и появляется все больше новых протектор, способных пошифровать EXE и якобы защитить его от взлома. Такие поделки используют в основном XOR для шифрации файла, который обратим, достаточно узнать пароль и пошифровать им уже шифрованный кусок кода для дешифровки. Порой анализируя программу можно узнать каким ключом дешифруется тот или иной блок. Но как же расшифровывать? В уме? Всю секцию кода? Довольно проблематично, скажете Вы и пойдете писать по-быстрому программу для решения данной задачи. Но зачем, если это все есть в хекс редакторе hiew? В нем присутствует и ксорилка. Достаточно в режиме редактирования нажать Ctrl + F8 и задать ключ, после чего просто нажимать F8 ксоря блок за блоком. Зажали F8 и держим пока все не раскриптовалось! Теперь остается только запустить hiew и расксорить все что надо.
Шифруем по формуле
Как бы не силен был XOR, он не всегда подходит для шифровки/дешифровки. Но грустить смысла нет, так как hiew позволяет задавать алгоритм шифровки самому. Для этого нажмем F3 чтобы перейти в режим редактирования а затем F7. Отроется диалог набора кода. Забиваем туда алгоритм криптовки и затем юзаем. Как писать криптоалгоритм объяснено в справке - я не буду ее переписывать в статье, так как ее Вы можете прочитать и так, скажу лишь что ничего сложного там нет - разобраться можно.
Реальный пример
Несложный кейгенми, который нам предстоит изучить
Все вышеописанное будет иметь смысл только если это применить на реальном примере, а именно, нам необходимо что-нибудь поисследовать. Анализ будем проводить используя только HIEW. Что, уже затряслись коленки? Не волнуйтесь - все просто. А для большей простоты и наглядности возьмем KeygenMe by Fabsys. Скачать его можно с crackmes.de. Начнем исследовать. Открываем keygen.exe в hiew. Что мы видим?
По адресу 40822A красуется вызов нагскрина, который требуется удалить. Для этого устанавливаем курсор на 40821C и жмем F3 чтобы перейти в режим правки, затем Tab для вызова окна ассемблера. В нем пишем "jmps .40822F" (без кавычек). Команда jmps в отличии от jmp сгенерит short jmp, который занимает всего 2 байта. Точка перед адресом ставится потому что это VA, а не Offset. Запустим для проверки. Ура! Нага как небывало. Теперь разберемся с проверкой пароля. Для этого я ввел имя "Test", а пароль "12345". При нажатии на кнопку "Generate" видим сообщение: "BaD BoY". Переходим обратно в hiew. В режиме дизассемблера жмем F8, затем F6 для вывода секций и выбираем первую секцию. Как только перейдем в ее начало - начнем поиск, для этого жми F7 и вводи "BaD BoY". Как только найдется жми F6, чтобы hiew перешел по адресу, откуда идет обращение к этой строке. Видим:
Теперь логично узнать, откуда идет обращение к 408086 адресу, ведь чуть выше его вывод информации о том что пароль правильный, следовательно где-то есть переходи либо на вывоl информации о верном пароле либо о неверном. Ставим курсор на адрес 408086 и жмем F6. Хиев почти мгновенно как по велению волшебной палочки перенесет нас на строку где идет обращение к адресу 408086:
Попробуем исправить переход jne на je по адресу 408055. Запустим кейгенми и введем любой пароль - программа будет зарегистрирована. Но не забывайте - наша цель получить рабочий ключ! Сразу огорчу - хиев не слишком мощен чтобы в нем исследовать алгоритм. Для того чтобы полноценно изучить генератор пароля нам потребуется отлаживать программу. Но нужно ли это? Может просто попытаться получить код на наше имя? Давайте-ка попробуем! Потому поизучаем код, что идет перед jne. А на пару экранов выше идет:
Сравниваем [ebp][-00000204] с нулем и если равно выводим что неверный серийник. Логично предположить что по адресу [ebp-204] лежит серийник. Смотрим ниже. Сравнивается с нулем уже [ebp-204] и выводится сообщение что неверное имя пользователя. Теперь ясно что имя в [ebp-204]. Смотрим далее:
Ясно что без дебаггера нам не понять какой Call выполняет какую функцию, но давайте взглянем на каждый из них. Первый похоже просто переносит имя пользователя в другую переменную. А вот второй криптует ее. Пролистаем код по адресу 407E14 и о чудо:
Без дебаггера понять этот код можно только логически. Как мне кажется пароль может складываться как: ’HZF-’ + [ebp][-0C] + ’-GFD’. Давайте это проверим. Из листингов выше мы знаем адрес MessageBoxA в IAT. Так давайте вызовем MessageBox и в параметрах укажем [ebp][-0C]. Прямо после
push 000407EFC ;’-GFD’
жмем F3 и набираем. У меня получилось следующее:
Теперь при вводе неверного серийника выводится середина верного. Добавим к ней слева ’HZF-’ и справа ’-GFD’ и получим верный код. Только автор не позаботился о том, чтобы код всегда имел печатаемые символы, потому не на каждое имя будет ключ из нормальных печатаемых символов. но это уже не наши проблемы, цель получения пароля нами достигнута.
Перспективы развития hiew
В заключении статьи я решил немного познакомить Вас с тем, что нас ждет в будущих версиях программы. Главное что дейстительно планирует автор - это поддержка AMD64. Эта линейка процессоров уже поистине стала народной и получила широкое распространение в мире. Даже Майкрософт в Win64 насколько мне известно делает основной упор на процессоры AMD. Отсюда в последнее время стало появляться все больше программ и даже драйверов, скомпилированных в формате AMD64. Вывод следует один - ассемблер и дизассемблер hiew’а необходимо расширять. Про IA64 пока планов никаких, но тут уж хотя бы AMD64 реализовать. Насчет .NET и ARM Sen обещал подумать но это больше на перспективу, так как разбираться с абсолютно новым ассемблером и псевдокодом не так просто. Помимо того что уже сказал, автором дизассемблера планируется публикация полного Plugin SDK, чтобы каждый мог разработать плагин для расширения функционала HIEW’а. К примеру может кто напишет скриптовый язык для автоматизации действий в HIEW или скажем анализатор компилятора/упаковщика. В общем если SDK появится, за плагинами думаю не заржавеет. Что касается GUI, то его скорее всего не будет. Консольный инструмент гораздо удобнее виндового. Это уже доказано FAR’ом. Так что перспектив много - осталось ждать. Надеюсь Евгений не подкачает. А Вам я желаю успехов в исследованиях и надеюсь, что данная статья поможет Вам узнать больше о таком полезном инструменте аналитика, как HIEW и лучше автоматизировать свои задачи.
Последнюю версию hiew всегда можно найти на сайте http://www.hiew.ru
Дзенский реверсинг: исследование кода в полевых условиях
У любого аналитика бывают ситуации, когда под рукой кроме HEX редактора/дизассемблера hiew ничего нет, а исследовать тот или иной код нужно. Причем нужно бывает срочно. Такое обычно требуется в самых неожиданных местах: в гостях у друзей, если компьютер заражен непонятным вирусом, а с собой естественно ничего нет, в коммандировке, когда с собой только телефон. Да мало ли разных ситуаций. Бывает доходит до смешного, когда наемный программист поставит привязку к жесткому диску, а нужно срочно перенести АРМ (автоматизированное рабочее место, не путать с ARM) с одного компьютера на другой. Конечно можно пригласить автора АРМ’а и попросить его, но обычно на это банально нет времени и или писался код настолько давно, что на звонок тому работнику можно услышать "извини, код уже лет пять не пишу, работаю в автосервисе слесарем". Вот как раз для таких ситуаций и потребуются знания из этой статьи. Итак вперед!
Введение
Многие аналитики привыкли использовать довольно массивный комплект из различных утилит для исследования кода. Это и отладчик SoftICE или OllyDbg, это и дизассемблер IDA Pro, это и файловый анализатор PEiD и редактор PE Tools. И еще целая гора специализированного и нужного софта. Но нужно ли реально столько инструментов? Для большинства несложных задач по анализу кода можно вполне обойтись HEX редактором и дизассемблером, причем не самым идеальным. Все дело в том что многие вещи можно сделать и самому не прибегая к мощности утилит. Здесь я Вам расскажу как исследовать код только с помощью HIEW. Этот дизассемблер я выбрал не случайно - его всегда легко найти в локальной сети в любом крупном предприятии, хоть и старую версию, накрайняк скачать (вес утилиты порядка мегабайта) и он в своем составе имеет хороший HEX редактор, потому и пользуется везде спросом. Итак кроме комьютера и сети под руками у Вас ничего нет и стоит задача банально запустить неработающий АРМ, привязанный к старому диску. Давайте рассмотрим как выполнять различные операции по анализу кода в этом замечательном дизасме.
Сам себе PE Sniffer
Главным для аналитика всегда являлось локализовать компилятор/упаковщик, дабы знать с чем он имеет дело и какой подход ему использовать. Не спорю, что найдя упаковщик Вам как минимум потребуется его распаковать и тут уже без автораспаковщика не обойтись. Но обычно для узкоспециализированных утилит, которые писались по заказу штатным разработчиком, это не актуально. В таких случаях обычно не используются никакие упаковщики, так как клиент один и он всегда платит, а потому программист делает защиту только для того, чтобы клиент ее никому потом не перепродал и чтобы его услуги были востребованы. Конечно идея хорошая, но порой самому клиенту приходится апгрейдить комп и тут приходится чтото делать. И в этот момент обычно уже прошло много лет со времен разработки и человека уже не найти.
Локализация компилятора, которым собрана программа, будет не менее полезна. Для Delphi и Visual Basic потребуются разные знания и подготовка. Начнем с того, что откроем программу в hiew и посмотрим на гору ASCII символов. Что нить понятно?
При запуске экран хиева ничуть не отличается от экрана FAR’а в режиме просмотра файла
Нажмем дважды Enter и смотрим на более понятный дизассемблированный код. Дабы он стал еще понятнее - нажмите F8 и F5 - hiew перейдет на тот участок кода, который находится в точке входа. Внимательно взглянув на этот код уже можно понять на чем он написан. К примеру для Delphi программ код будет подобен этому:
.0046D380: 55 push ebp
.0046D381: 8BEC mov ebp,esp
.0046D383: 83C4F0 add esp,-010 ;"?"
.0046D386: B8A0D14600 mov eax,00046D1A0
.0046D38B: E8DC94F9FF call .00040686C
.0046D390: A1E8F84600 mov eax,[0046F8E8]
.0046D395: 8B00 mov eax,[eax]
.0046D397: E8A4E6FCFF call .00043BA40
.0046D39C: E8B3EAFFFF call .00046BE54
.0046D3A1: 8B0D28F94600 mov ecx,[0046F928]
.0046D3A7: A1E8F84600 mov eax,[0046F8E8]
.0046D3AC: 8B00 mov eax,[eax]
.0046D3AE: 8B15F0B84600 mov edx,[0046B8F0]
.0046D3B4: E89FE6FCFF call .00043BA58
.0046D3B9: A1E8F84600 mov eax,[0046F8E8]
.0046D3BE: 8B00 mov eax,[eax]
.0046D3C0: 8B4044 mov eax,[eax][44]
.0046D3C3: E834FBFFFF call .00046CEFC
.0046D3C8: A1E8F84600 mov eax,[0046F8E8]
Не узнать его нельзя... просто несколько Call вызовов, стандартных в Delphi программах. Если опять перейти в текстовый режим и нажать и подержать PgUp в самом верху увидим названия секций. Вот примерный расклад для нетронутых защитой Delphi программ:
CODE
DATA
BSS
idata
tls
rdata
.reloc
.rsrc
Итак с дельфями определились, теперь поговорим про C++ Builder. Тут вообще все проще. На оригинальной точке входа всегда такой код:
.00401000: EB10 jmps .000401012
.00401002: 66623A bound di,[edx]
.00401005: 43 inc ebx
.00401006: 2B2B sub ebp,[ebx]
.00401008: 48 dec eax
.00401009: 4F dec edi
.0040100A: 4F dec edi
.0040100B: 4B dec ebx
.0040100C: 90 nop
.0040100D: E978D54900 jmp 0206321AA
.00401012: A16BD54900 mov eax,[0049D56B]
Байты, расположенные между jmp’ом и mov’ом это строчка "C++HOOK" Тоже все просто :) Что же насчет бейсика? А у него всегда 2 команды на точке входа:
.004011CC: 68EC164000 push 0004016EC
.004011D1: E8EEFFFFFF call MSVBVM60.100
По адресу 0004016EC всегда VBHeader, начинающийся с сигнатуры "VB5!".
Начало структуры, описывающей любую VB программу
Как видим не так уж и требуется PEiD для определения компилятора, а что же про упаковщики? А здесь можно даже не смотреть на точку входа. Достаточно в текстовом виде поглядеть на EXE заголовок. UPX пихает в начало первой секции сигнатуру "UPX!", а секции обзывает ".UPX0", ".UPX1", ".rsrc", причем секций три вне зависимости от того сколько их было до упаковки.
Если же взглянуть на точку входа, то откроется довольно стандартный для всех версий UPX’а код:
.00417180: 60 pushad
.00417181: BE00E04000 mov esi,00040E000
.00417186: 8DBE0030FFFF lea edi,[esi][-0000D000]
.0041718C: 57 push edi
.0041718D: 83CDFF or ebp,-001 ;"?"
.00417190: EB10 jmps .0004171A2
.00417192: 90 nop
.00417193: 90 nop
.00417194: 90 nop
.00417195: 90 nop
.00417196: 90 nop
.00417197: 90 nop
.00417198: 8A06 mov al,[esi]
.0041719A: 46 inc esi
.0041719B: 8807 mov [edi],al
Подробнее о самом алгоритме распаковки и восстановлении импорта можете прочитать в моих статьях: Учимся распаковке DLL библиотек и Распаковываем UPX Shit v0.06. Я же продолжу рассказ о детекте других упаковщиков. Следующим по распространенности является FSG и с недавних пор Upack. Их узнать очень легко даже взглянув на текстовое представление EXE заголовка - он крайне оптимизирован и обычно там нет стольких ненужных нулевых байт выравнивания, сколько оставляют другие пакеры. А Upack даже заносит импорт прямо в DOS Header после MZ.
UPack жмет программу так, что от заголовка остается только MZ, после которого идет импорт. Жаль антивирусы не разделяют эту идею оптимизации.
Все просто, только hiew. Кстати еще есть метода легко отличать MS компиляторы от борландовых: по присутствию "Rich" строки после DOS Header’а. В общем если держать в голове все эти методики плюс иметь неслабый опыт - можно определить любой компилятор или упаковщик в hiew’е, это приходит со временем потому начинайте сейчас!
Стринг референсы
Лучшим помощником реверсера являются стринг референсы - перечень всех строковых данных, встречающихся в программе и адресов, где происходит обращение к этим строкам. Так вот в hiew’е это тоже есть! Достаточно в HEX режиме поставить курсор на начало любой строки и нажать F6 - сразу перейдем на первое обращение к этой строке! Вкупе с этим есть возможность искать русские строки. Жмем F7 и пишем "Ошабка запуска программы" и жмем Enter. Если нужно искать все места где встречается строка, жмем Shift + F7 - хиев найдет следующий адрес где имеется строчка. Так как же он находит русские строки? Ведь они могут быть и в DOS и в windows кодировке - все просто, нужные знания даем ему мы сами, для этого перед поиском необходимо в текстовом режиме нажать F8 и выбрать кодировку. Именно используя ее хиев и будет искать строку, то есть универсальности конечно не получится, но это куда лучше, чем любоваться только на английские строки в Olly.
Серфинг по EXE
Порой когда смотришь дизассемблерные листинги так и хочется перейти по адресу по которому указывает jmp, call или даже mov. Хиев и тут не подведет - каждому адресу на экране присваивается уникальное число, нажав которое на клавиатуре - мы перейдем куда надо, вот пример:
.00417180: 60 pushad
.00417181: BE00E04000 mov esi,00040E000
.00417186: 8DBE0030FFFF lea edi,[esi][-0000D000]
.0041718C: 57 push edi
.0041718D: 83CDFF or ebp,-001 ;"?"
.00417190: EB10 jmps .0004171A2
(1) и (2) - это как раз эти самые числа. Чтобы нам перейти по указанным адресам, жмем на клавиатуре эти самые числа (или буквы, если переходов больше 9). Цифровость задается в hiew7.ini и Вы можете сделать, чтобы вместо чисел были например китайские иероглифы. Теперь остановимся на перемещениям по EXE вручную. F5 позволяет перейти на указанный адрес, причем если просто ввести адрес - перейдем по Offset’у, а если перед адресом поставить точку, то хиев перейдет по виртуальному адресу. Очень удобно, причем даже в коде эти адреса можно переключать нажимая Alt + F1. Перейти к началу нужной секции также просто - достаточно нам зайти в PE заголовок нажав F8,затем кнопку F6 и выбрав нужную секцию из списка мы переместимся в ее начальный адрес. А что если нужно перейти в начало таблицы импорта или TLS? Искать их самому? Зачем? F8, затем F10 - мы перейдем к таблице директорий NTHeader’а. В ней просто выбираем нужное поле и жмем Enter. Вот так вот старый добрый хиев помогает в нелегком деле.
Ассемблируем
Исследовать мало - нужно править код, причем не все помнят машинные коды и не все могут ориентироваться в составлении mod/rm флагов и не все могут кодировать регистры в уме, потому править просто в HEX редакторе немного неудобный метод (хотя я написав весь движок DotFix LiteProtect’а чисто в hiew уже привык кодировать в уме, но эт так к слову). Хиев не оставит Вас в беде, он представляет мощный ассемблер. Нажмем F3 дабы править код, а затем дрожащим пальцем ткнем в клавишу Tab. О чудо, в появившейся текстовой строке можно писать команды прямо на ассемблере, причем нажав Enter можно набирать уже следующую команду и так хоть весь код.
Пишем программу как настоящие ассемблерщики, безо всяких сред программирования
Как видите - не все так сложно, как казалось, когда Вы начинали читать эту статью. Если в процессе набора кода Вы ошибетесь - помните, практически любой введенный код можно отменить нажимая F3. Когда уже написали что надо - жмите F9 для записи в файл. Вот незадача, после записи файл не запускается - приходится выходить из hiew, чтобы снять залоченность. Но и это обходится. Открываем hiew7.ini и ищем строку "ReopenAfterEdit" и ставим ее в "On". Теперь после редактирования файл будет закрываться и снова открываться для чтения, поэтому его можно будет запустить после каждой правки. Спросил я у автора, зачем он так не сделал в дефолтных настройках и меня настолько порадовал его ответ - "чтобы люди читали хелп" :) Так что почитайте хелп и комментарии ко всем строкам hiew7.ini, узнаете много нового.
Декриптуем XOR
С некоторых пор повелось, что каждый программист, разобравшийся с PE форматом пишет свой протектор EXE файлов. Как не странно, явление сие постоянно процветает и появляется все больше новых протектор, способных пошифровать EXE и якобы защитить его от взлома. Такие поделки используют в основном XOR для шифрации файла, который обратим, достаточно узнать пароль и пошифровать им уже шифрованный кусок кода для дешифровки. Порой анализируя программу можно узнать каким ключом дешифруется тот или иной блок. Но как же расшифровывать? В уме? Всю секцию кода? Довольно проблематично, скажете Вы и пойдете писать по-быстрому программу для решения данной задачи. Но зачем, если это все есть в хекс редакторе hiew? В нем присутствует и ксорилка. Достаточно в режиме редактирования нажать Ctrl + F8 и задать ключ, после чего просто нажимать F8 ксоря блок за блоком. Зажали F8 и держим пока все не раскриптовалось! Теперь остается только запустить hiew и расксорить все что надо.
Шифруем по формуле
Как бы не силен был XOR, он не всегда подходит для шифровки/дешифровки. Но грустить смысла нет, так как hiew позволяет задавать алгоритм шифровки самому. Для этого нажмем F3 чтобы перейти в режим редактирования а затем F7. Отроется диалог набора кода. Забиваем туда алгоритм криптовки и затем юзаем. Как писать криптоалгоритм объяснено в справке - я не буду ее переписывать в статье, так как ее Вы можете прочитать и так, скажу лишь что ничего сложного там нет - разобраться можно.
Реальный пример
Несложный кейгенми, который нам предстоит изучить
Все вышеописанное будет иметь смысл только если это применить на реальном примере, а именно, нам необходимо что-нибудь поисследовать. Анализ будем проводить используя только HIEW. Что, уже затряслись коленки? Не волнуйтесь - все просто. А для большей простоты и наглядности возьмем KeygenMe by Fabsys. Скачать его можно с crackmes.de. Начнем исследовать. Открываем keygen.exe в hiew. Что мы видим?
.0040820C: 55 push ebp
.0040820D: 8BEC mov ebp,esp
.0040820F: 83C4F0 add esp,0FFFFFFF0 ;’?’
.00408212: B8C4814000 mov eax,0004081C4
.00408217: E8F0C2FFFF call .00040450C
.0040821C: 6A40 push 000000040 ;’@’
.0040821E: 684C824000 push 00040824C ;’Rules’
.00408223: 6854824000 push 000408254 ;’KeygenMe and de
.00408228: 6A00 push 0
.0040822A: E841C4FFFF call MessageBoxA ;user32
.0040822F: 68047F4000 push 000407F04
По адресу 40822A красуется вызов нагскрина, который требуется удалить. Для этого устанавливаем курсор на 40821C и жмем F3 чтобы перейти в режим правки, затем Tab для вызова окна ассемблера. В нем пишем "jmps .40822F" (без кавычек). Команда jmps в отличии от jmp сгенерит short jmp, который занимает всего 2 байта. Точка перед адресом ставится потому что это VA, а не Offset. Запустим для проверки. Ура! Нага как небывало. Теперь разберемся с проверкой пароля. Для этого я ввел имя "Test", а пароль "12345". При нажатии на кнопку "Generate" видим сообщение: "BaD BoY". Переходим обратно в hiew. В режиме дизассемблера жмем F8, затем F6 для вывода секций и выбираем первую секцию. Как только перейдем в ее начало - начнем поиск, для этого жми F7 и вводи "BaD BoY". Как только найдется жми F6, чтобы hiew перешел по адресу, откуда идет обращение к этой строке. Видим:
.00408067: 6848814000 push 000408148 ;’Prolixe KeygenM
.0040806C: 53 push ebx
.0040806D: E81EC6FFFF call SetWindowTextA ;user32
.00408072: 6A00 push 0
.00408074: 6874814000 push 000408174 ;’Winner’
.00408079: 687C814000 push 00040817C ;’GooD BoY’
.0040807E: 53 push ebx
.0040807F: E8ECC5FFFF call MessageBoxA ;user32
.00408084: EB20 jmps .0004080A6
.00408086: 6A00 push 0
.00408088: 6888814000 push 000408188 ;’Wrong Way’
.0040808D: 6894814000 push 000408194 ;’BaD BoY’
.00408092: 53 push ebx
.00408093: E8D8C5FFFF call MessageBoxA ;user32
.00408098: EB0C jmps .0004080A6
Теперь логично узнать, откуда идет обращение к 408086 адресу, ведь чуть выше его вывод информации о том что пароль правильный, следовательно где-то есть переходи либо на вывоl информации о верном пароле либо о неверном. Ставим курсор на адрес 408086 и жмем F6. Хиев почти мгновенно как по велению волшебной палочки перенесет нас на строку где идет обращение к адресу 408086:
.0040801E: E819B8FFFF call .00040383C
.00408023: 8B85F8FDFFFF mov eax,[ebp][-00000208]
.00408029: 8D55FC lea edx,[ebp][-04]
.0040802C: E8E3FDFFFF call .000407E14
.00408031: 8D85F4FDFFFF lea eax,[ebp][-0000020C]
.00408037: 8D95FCFDFFFF lea edx,[ebp][-00000204]
.0040803D: B900010000 mov ecx,000000100 ;’ ? ’
.00408042: E8F5B7FFFF call .00040383C
.00408047: 8B95F4FDFFFF mov edx,[ebp][-0000020C]
.0040804D: 8B45FC mov eax,[ebp][-04]
.00408050: E8EBB8FFFF call .000403940
.00408055: 752F jne .000408086 - мы здесь
.00408057: 6834814000 push 000408134 ;’Registred Versi
.0040805C: 68F1030000 push 0000003F1 ;’ ??’
.00408061: 53 push ebx
.00408062: E811C6FFFF call SetDlgItemTextA ;user32 --?
Попробуем исправить переход jne на je по адресу 408055. Запустим кейгенми и введем любой пароль - программа будет зарегистрирована. Но не забывайте - наша цель получить рабочий ключ! Сразу огорчу - хиев не слишком мощен чтобы в нем исследовать алгоритм. Для того чтобы полноценно изучить генератор пароля нам потребуется отлаживать программу. Но нужно ли это? Может просто попытаться получить код на наше имя? Давайте-ка попробуем! Потому поизучаем код, что идет перед jne. А на пару экранов выше идет:
.00407FCD: 80BDFCFDFFFF00 cmp b,[ebp][-00000204],0
.00407FD4: 7517 jne .000407FED
.00407FD6: 6A40 push 000000040 ;’@’
.00407FD8: 680C814000 push 00040810C ;’Error’
.00407FDD: 6814814000 push 000408114 ;’Enter a Serial’
.00407FE2: 53 push ebx
.00407FE3: E888C6FFFF call MessageBoxA ;user32
.00407FE8: E9B9000000 jmp .0004080A6
.00407FED: 80BDFCFEFFFF00 cmp b,[ebp][-00000104],0
.00407FF4: 7517 jne .00040800D
.00407FF6: 6A40 push 000000040 ;’@’
.00407FF8: 680C814000 push 00040810C ;’Error’
.00407FFD: 6824814000 push 000408124 ;’Enter a Name’
.00408002: 53 push ebx
.00408003: E868C6FFFF call MessageBoxA ;user32
Сравниваем [ebp][-00000204] с нулем и если равно выводим что неверный серийник. Логично предположить что по адресу [ebp-204] лежит серийник. Смотрим ниже. Сравнивается с нулем уже [ebp-204] и выводится сообщение что неверное имя пользователя. Теперь ясно что имя в [ebp-204]. Смотрим далее:
.0040800D: 8D85F8FDFFFF lea eax,[ebp][-00000208]
.00408013: 8D95FCFEFFFF lea edx,[ebp][-00000104]
.00408019: B900010000 mov ecx,000000100 ;’ ? ’
.0040801E: E819B8FFFF call .00040383C
.00408023: 8B85F8FDFFFF mov eax,[ebp][-00000208]
.00408029: 8D55FC lea edx,[ebp][-04]
.0040802C: E8E3FDFFFF call .000407E14
.00408031: 8D85F4FDFFFF lea eax,[ebp][-0000020C]
.00408037: 8D95FCFDFFFF lea edx,[ebp][-00000204]
.0040803D: B900010000 mov ecx,000000100 ;’ ? ’
.00408042: E8F5B7FFFF call .00040383C
.00408047: 8B95F4FDFFFF mov edx,[ebp][-0000020C]
.0040804D: 8B45FC mov eax,[ebp][-04]
.00408050: E8EBB8FFFF call .000403940
.00408055: 752F jne .000408086
Ясно что без дебаггера нам не понять какой Call выполняет какую функцию, но давайте взглянем на каждый из них. Первый похоже просто переносит имя пользователя в другую переменную. А вот второй криптует ее. Пролистаем код по адресу 407E14 и о чудо:
.00407E99: 68EC7E4000 push 000407EEC ;’HZF-’
.00407E9E: FF75F4 push d,[ebp][-0C]
.00407EA1: 68FC7E4000 push 000407EFC ;’-GFD’
Без дебаггера понять этот код можно только логически. Как мне кажется пароль может складываться как: ’HZF-’ + [ebp][-0C] + ’-GFD’. Давайте это проверим. Из листингов выше мы знаем адрес MessageBoxA в IAT. Так давайте вызовем MessageBox и в параметрах укажем [ebp][-0C]. Прямо после
push 000407EFC ;’-GFD’
жмем F3 и набираем. У меня получилось следующее:
.00407E99: 68EC7E4000 push 000407EEC ;’HZF-’
.00407E9E: FF75F4 push d,[ebp][-0C]
.00407EA1: 68FC7E4000 push 000407EFC ;’-GFD’
.00407EA6: 8B45F4 mov eax,[ebp][-0C]
.00407EA9: 6A00 push 0
.00407EAB: 50 push eax
.00407EAC: 50 push eax
.00407EAD: 6A00 push 0
.00407EAF: E8BCC7FFFF call MessageBoxA ;user32
.00407EB4: 90 nop
.00407EB5: 5A pop edx
.00407EB6: 59 pop ecx
.00407EB7: 59 pop ecx
.00407EB8: 648910 mov fs:[eax],edx
Теперь при вводе неверного серийника выводится середина верного. Добавим к ней слева ’HZF-’ и справа ’-GFD’ и получим верный код. Только автор не позаботился о том, чтобы код всегда имел печатаемые символы, потому не на каждое имя будет ключ из нормальных печатаемых символов. но это уже не наши проблемы, цель получения пароля нами достигнута.
Перспективы развития hiew
В заключении статьи я решил немного познакомить Вас с тем, что нас ждет в будущих версиях программы. Главное что дейстительно планирует автор - это поддержка AMD64. Эта линейка процессоров уже поистине стала народной и получила широкое распространение в мире. Даже Майкрософт в Win64 насколько мне известно делает основной упор на процессоры AMD. Отсюда в последнее время стало появляться все больше программ и даже драйверов, скомпилированных в формате AMD64. Вывод следует один - ассемблер и дизассемблер hiew’а необходимо расширять. Про IA64 пока планов никаких, но тут уж хотя бы AMD64 реализовать. Насчет .NET и ARM Sen обещал подумать но это больше на перспективу, так как разбираться с абсолютно новым ассемблером и псевдокодом не так просто. Помимо того что уже сказал, автором дизассемблера планируется публикация полного Plugin SDK, чтобы каждый мог разработать плагин для расширения функционала HIEW’а. К примеру может кто напишет скриптовый язык для автоматизации действий в HIEW или скажем анализатор компилятора/упаковщика. В общем если SDK появится, за плагинами думаю не заржавеет. Что касается GUI, то его скорее всего не будет. Консольный инструмент гораздо удобнее виндового. Это уже доказано FAR’ом. Так что перспектив много - осталось ждать. Надеюсь Евгений не подкачает. А Вам я желаю успехов в исследованиях и надеюсь, что данная статья поможет Вам узнать больше о таком полезном инструменте аналитика, как HIEW и лучше автоматизировать свои задачи.
Последнюю версию hiew всегда можно найти на сайте http://www.hiew.ru
Комментарии |
Добавил: BUGOR Дата: 20.08.2006 Вполне ничего, пару новых функций hiew'a для себя всё же открыл) Спасибо. |
Добавил: script Дата: 29.07.2007 При попытке изменения jne на je по адресу 408055 пишет "Read-Only Mode" как сделать Write Mode ? |
Добавил: GPcH Дата: 26.10.2007 Слудовательно у тебя файл запущен. Выгрузи его сначала, а потом редактируй. |
Добавил: Ray Дата: 21.04.2009 GPcH У меня вопрос по поводу ассемблирования в хьюве. Как ты уже написал в статье, он позволяет писать команды прямо на ассемблере. Как я только не пробовал, у меня никак не получилось написать банальный call MessageBoxA. Т.е. все команды вроде как проходят, а вот сделать вызов ф-и - никак.Hiew 7.51 P.S. За статью спасибо. |
Добавил: GPcH Дата: 23.04.2009 Ну чтобы сделать вызов функции, для начала ее нужно добавить в таблицу импорта. После добавления все просто - делаем Jump на адрес функции в таблице импорта. В HEX виде это будет выглядеть как: FF25XXXXXXXX, где XXXXXXXX - это адрес функции в таблице импорта. В иморт функцию проще всего добавить с помощью PE Tools или LordPE. |
Добавление комментария |