Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

articles:hex-rays [2017/09/05 02:55]
articles:hex-rays [2017/09/05 02:55] (текущий)
Строка 1: Строка 1:
 +====== hex-rays ======
 +<​sub>​{{hex-rays.odt|Original file}}</​sub>​
 +
 +====== hex-ray – декомпилятор нового поколения ======
 +
 +крис касперски,​ ака мыщъх, a.k.a. nezumi, a.k.a. souriz, a.k.a. elraton, no-email
 +
 +**начинающие реверсеры,​ еще не вкурившие в асм, постоянно спрашивают на хакерских формах:​ где бы им раздобыть декомпилятор для си или паскаля****?​**** декомпиляторов-то много, но вот результат... без дизассемблера ни один хвост не разобраться,​ даже если дунет. и вот, наконец — свершилось! Ильфак (автор легендарного дизассемблера ****IDA Pro****) выпустил декомпилятор нового поколения HexRays, делающий то, что другим не под силу. мир вздрогнул от восторга (реклама вообще обещала чудо), порождая сейсмические волны впечатлений:​ от оргазма,​ до полного отвращения. истина же, как водится,​ где-то посередине и представляет интерес обозначить эту середину,​ рассмотрев слабые и сильные стороны декомпилятора,​ а так же области его применения**
 +
 +===== введение =====
 +
 +Почему у Ильфака получилось то, что упорно не желало получаться у других?​ Начнем с того, что Hex-Ray представляет собой всего лишь plug-in к IDA Pro — интерактивному дизассемблеру более чем с десятилетней историей,​ первая версия которой увидела свет 6 мая 1991 года. Спустя некоторое время к работе над ней подключился удивительный человек,​ гениальный программист и необычайно креативный кодер Юрий Харон и они вместе с Ильфаком (не без помощи других талантливых парней,​ конечно) начали рыть землю в том направлении,​ куда еще никто не вкладывал деньги. До этого дизассемблеры писались исключительно на "​пионерском"​ энтузиазме параллельно с изучением ассемблера и довольно быстро забрасывались.
 +
 +IDA Pro — не только основной,​ но и, пожалуй,​ единственный продукт фирмы DataRescue (мелкие утилиты и прочие ответвления — не в счет). А Ильфак очень неглупый человек,​ и Юрий Харон тоже. Так стоит ли удивляться,​ что им удалось решить практически все фундаментальные проблемы дизассемблирования,​ над которыми просто не хотели работать остальные разработчики,​ зная, что быстрой отдачи не будет и проект потребует десятилетий упорного труда.
 +
 +И вот тут самое время выяснить:​ что же это за проблемы такие, откуда они берутся и куда деваются.
 +
 +===== фундаментальные проблемы декомпиляции =====
 +
 +Компиляция — процесс однонаправленный и необратимый,​ в ходе которого теряется огромное количество "​лишней"​ информации,​ совершенно ненужной процессору. Это не шутка! Исходный текст, написанный на языке высокого уровня,​ чрезвычайно избыточен,​ что с одной стороны упрощает его понимание,​ а с другой — страхует программиста от ошибок. Взять хотя бы информацию о типах. На низком уровне процессор оперирует базовыми типами:​ байт, слово, двойное слово. Строки превращаются в последовательности байтов и чтобы догадаться,​ что это действительно строка,​ приходится прибегать к эвристическим алгоритмам.
 +
 +Структуры и классы так же "​расщепляются"​ в ходе компиляции и за исключением некоторых виртуальных функций,​ все остальные члены класса теряют свою кастовую принадлежность,​ становясь глобальными процедурами. Восстановить иерархию классов в общем случае невозможно,​ да в принципе,​ не сильно и нужно.
 +
 +Никто из здравомыслящих людей не требует от декомпилятора получить хотя бы приближенную копию исходного кода, но мы вправе рассчитывать на удобочитаемость листинга,​ а так же на то, что повторная компиляция не развалит программу,​ а создаст вполне работоспособный модуль — тогда мы сможем вносить любые изменения в декомпилированный текст, развивая его в нужном нам направлении. В противном случае такому декомилятору место на свалке и фиксить баги декомпиляции ничуть не проще, чем переписывать подопытную программу с нуля.
 +
 +Декомпиляции препятствует ряд серьезных проблем,​ важнейшие из которых перечислены ниже.
 +
 +==== что в имени твоем ====
 +
 +Комментарии,​ имена функций и переменных в процессе компиляции теряются безвозвратно (исключение составляют динамические типы, имена которых в двоичном модуле хранятся "​как есть",​ а потому и тормозят словно динозавры). Ну, с комментариями в большинстве исходных текстов и так небогато,​ так что их отсутствие еще можно пережить,​ но вот без имен переменных и функций логика работы даже простейших программ становится совершенно непонятной.
 +
 +К счастью,​ современные программы наполовину (а то и более) состоят из библиотечных и API-функций,​ которые распознаются классическим сигнатурным поиском. Главное — собрать обширную базу библиотек всех популярных (и непопулярных) компиляторов с учетом многообразия их версий.
 +
 +IDA Pro уже давно поддерживает технологию FLIRT (Fast Library Identification and Recognition Technology),​ не только распознающую библиотечные функции,​ но так же восстанавливающую их прототипы вместе с прототипами API-функций,​ которые кстати говоря,​ могут импортироваться не только по имени, но еще и по ординалу,​ то есть по номеру и чтобы превратить бессловесный номер в имя, понятное человеку,​ опять-таки требуется база.
 +
 +Почему реконструкция прототипов так важна для декомпилятора?​ А потому,​ что она позволяет восстанавливать типы передаваемых функциями переменных,​ назначая им хоть и обезличенные,​ но все же осмысленные имена в стиле: hWnd, hModule, X, Y, nWidth, nHeight, hCursor, hMenu, hDlg. Согласитесь,​ это _намного_ лучше, чем dword_1008030,​ dword_1008269,​ dword_1006933 — что характерно для подавляющего большинства остальных декомпиляторов.
 +
 +Даже если часть переменных распознана,​ то это уже упрощает анализ программы и реконструкцию оставшихся переменных.
 +
 +==== константа или смещения ====
 +
 +В силу архитектурных особенностей x86 процессоров,​ константы и смещения (они же указатели — в терминах языков высокого уровня) синтаксически _абсолютно_ неразличимы и декомпилятру (равно как и дизассемблеру) приходится задействовать мощные эвристические алгоритмы,​ чтобы не попасть впросак.
 +
 +А какая между этими двумя сущностями разница?​ Очень большая!!! Вот, например,​ в регистр EAX загружается число 106996h. Если это указатель на ячейку памяти или массив данных,​ то дизассемблер должен воткнуть по этому адресу метку (label) и написать MOV EAX, _offset_ lab_106996 (ес-но, имя метки дано условно и совпадение с ее численным значением абсолютно случайно — при повторной компиляции она может оказаться расположенной по совершенно другому адресу). А вот если 106996h — это константа,​ выражающая,​ например,​ среднюю плотность тушканчиков на один квадратный метр лесополосы или количество полигонов на морде монстра,​ то ставить offset ни в коем случае нельзя,​ поскольку,​ это не только введет нас в заблуждение при анализе,​ но и, как уже говорилось,​ при повторной компиляции,​ смещение может уплыть,​ превращая число 106996h черт знает во что. Программа либо будет работать неправильно,​ либо сразу рухнет (особенно,​ если путаница между константами и смещениями происходит не единожды,​ а совершается на протяжении всего листинга).
 +
 +Так как же все-таки определить кто есть ху?! На первый взгляд все достаточно просто. Если данная сущность используется как указатель (то есть, через нее происходит обращение к памяти по заданному адресу:​ mov eax,​ 106996h/​mov ebx,[eax]), тут и дизассемблеру ясно, что это — смещение. Но стоит лишь немного усложнить пример,​ например,​ передать 106996h какой-нибудь функции или начать производить с ней сложные манипуляции,​ то дизассемблеру потребуется высадится на полную реконструкцию всей цепочки преобразований,​ но даже тогда его решение может оказаться неверным,​ поскольку в языке Си индексы (т. е. константы) и указатели (т. е. смещения) _полностью_ взаимозаменяемы и конструкция buf[69] не только равносильна 69[buf], но и транслируется в идентичный машинный код, при реконструкции которого возникает очевидная проблема. У нас есть два числа A и B, _сумма_ которых представляет указатель (то есть, существует возможность,​ определить,​ что это указатель — да и то, если попыхтеть),​ но вот кто из них индекс?​ Увы. Формальная математика не дает ответа на этот вопрос и дизассемблеру приходится полагаться лишь на свою интуицию да эвристику. Указатели в win32, как правило,​ велики,​ поскольку минимальный базовый адрес загрузки файла равен 100000h. Индексы же, как правило (опять! как правило!),​ малы и много меньше указателей,​ однако,​ если у нас имеется массив,​ расположенный по адресу 200000h и состоящий из 3.145.728 (300000h)элементов (а почему бы, собственно,​ и нет?!) то тут, индексы старших элементов становятся _больше_ базового указателя на массив,​ что вводит дизассемблер в заблуждение.
 +
 +Полный перечень эвристических методик,​ используемых ИДОЙ для распознавания смещений,​ можно найти в книге "​образ мышления — ИДА"​ (электронную копию которой находится на мыщъхином сервере http://​nezumi.org.ru/​ida.full.zip),​ нам же достаточно сказать,​ что IDA Pro действительно преуспела в этом направлении и ошибается она крайне редко, хотя все-таки ошибается и с ростом размеров дизассемблируемой программы количество ошибок резко нарастает.
 +
 +==== код или данные ====
 +
 +Вот так проблема! Наверное,​ даже самый тупой дизассемблер разберется что ему подсунули — код или данные,​ тем более, что в PE-файлах (основной формат исполняемых файлов под Windows) они разнесены по разным секциям. Ну, это в теории они разнесены,​ а на практике компиляторы очень любят пихать данные в секцию кода (особенно этим славиться Багдад — в смысле продукция фирмы Borland).
 +
 +С другой стороны,​ практически все компиляторы (особенно на Си++) сплошь и рядом используют вызовы функций в стиле CALL EBX и чтобы понять куда ведет такой вызов, необходимо установить значение регистра EBX, что требует наличия более или менее полного эмулятора процессора,​ отслеживающего всю историю содержимого EBX с момента его инициализации до непосредственного вызова.
 +
 +Но непосредственные вызовы это — ерунда. Вот косвенные — та да!!! Реконструкция CALL dword ptr DS:​[EBX] требует не только эмуляции процессора (т.е. набора машинных команд),​ но и эмуляции памяти!!! Естественно,​ это на порядок усложняет дизассемблерный движок,​ зато нераспознанные массивы данных мгновенно превращаются в функции и, что самое главное,​ — дизассемблер показывает кто именно и откуда их вызывает!
 +
 +Наличие эмулятора процессора и памяти позволяет так же отслеживать положение регистра ESP, используемого для адресации локальных переменных и аргументов,​ передаваемых функциям. Если же эмулятора нет (а в ИДЕ он есть), дизассемблер способен распознавать лишь простейшие формы адресации/​передачи аргументов. Механизм,​ ответственный за распознание и отслеживание аргументов,​ носит красивое название пива PIT, но расшифровывается эта аббревиатура отнюдь не как "​Пивоварный [завод] Ивана Таранова",​ а происходит от "​Parameter Identification and Tracking"​ — идентификация и отслеживание параметров,​ в смысле аргументов. Тех, что бывают у функций. А еще бывают функции без аргументов,​ но это уже другая история.
 +
 +{{hex-rays_Image_0.jpg}}
 +
 +Рисунок 1 PIT – это не только пиво!
 +
 +==== реконструкция потока управления ====
 +
 +Языки высокого уровня оперируют такими конструкциями как циклы, операторы выбора,​ ветвления и т. д., что делает программу простой и наглядной. Собственно говоря,​ именно отсюда и пошло структурное программирование. А ведь когда-то,​ давным-давно,​ в Бейсике (и других языках того времени) кроме примитивного GOTO ничего не было и программа,​ насчитывающая больше сотни строк, превращалась в сплошное "​спагетти",​ лишенное всякой логики,​ внутренней организации и следов цивилизации.
 +
 +На низком же, машинном,​ уровне ситуация осталось той же, что и лет пятьдесят тому назад. И хотя x86 процессоры формально поддерживают инструкцию цикла LOOP, компиляторы ее не используют,​ довольствуясь одними лишь условными и безусловными переходами,​ а потому первоочередная задача реверсера — реконструировать циклы, ветвления и другие высокоуровневые сооружения. Подробнее о том, как это делается "​руками"​ читайте в "​фундаментальных основах хакерства"​ (бесплатная электронная копия лежит на http://​nezumi.org.ru/​phck2.full.zip).
 +
 +Начиная с пятой версии в IDA Pro появился механизм графов,​ позволяющий _автоматически_ реконструировать циклы, ветвления и прочие "​кирпичи"​ языков высокого уровня. Впрочем,​ польза от графов была небольшой и в реальности они только замедляли анализ,​ поскольку подобрать адекватный механизм визуализации и навигации Ильфаку так и не удалось… Но ведь не пропадать же труду?​!
 +
 +{{hex-rays_Image_1.png}}
 +
 +Рисунок 2 графы — как они есть
 +
 +===== у истоков hex-rays =====
 +
 +К пятой версии IDA Pro имела в своем арсенале все необходимое для автоматической декомпиляции,​ причем,​ не просто декомпиляции,​ а _очень_ качественной декомпиляции,​ декомпиляции принципиально нового уровня,​ до которого не дотягивает ни один другой существующих декомпилятор.
 +
 +Вот так и родилась идея — дописать к ИДЕ еще небольшую (на самом деле очень большую) порцию кода, переводящую китайскую ассемблерную грамоту в доступный и понятный листинг на языке Си. Закипела напряженная работа,​ по ходу которой выявлялись все новые и новые подводные камни, требующие времени,​ усилий и мозговой активности для поиска тонкой нити фарватера. А всякая (или практически всякая) работа упирается в деньги,​ тем более, что у Ильфака — фирма!
 +
 +Включать декомпилиятор в дистрибутив IDA Pro Ильфак не стал. Тому способствовало несколько причин. Первое и главное — основной массе текущих пользователей ИДЫ декомпилятор не сильно нужен, если они им и будет пользоваться,​ то так — из чистого любопытства,​ чтобы запустить пару раз, плюнуть и вернуться к привычному стилю жизни — анализу дизассемблерного листинга. Второе — зарабатывать на жить (Ильфаку) и содержать фирму как-то же надо?!
 +
 +Все это привело к тому, что декомпилятор,​ получивший название (Hex-Rays), был выпущен отдельным продуктом,​ но! — внимание на экран! — требующим обязательного присутствия ИДЫ, поскольку Hex-Rays —всего лишь plug-in. Таким образом,​ реверсеру,​ желающему упростить свою жизнь за счет автоматической декомпиляции,​ необходимо прибрести как саму ИДУ, так и Hex-Rays, причем,​ приобретать этот комплект будет совсем другая пользовательская аудитория,​ совсем не та, что приобретала ИДУ и почитала ее как самый лучший интерактивный дизассемблер. Интерактивный ‑ значит,​ тесно взаимодействующий с пользователем (в смысле с хакером). В противовес ей, пакетные дизассемблеры стремятся к максимальной автоматизации реверсинга,​ лишая пользователя возможности вмешиваться в процесс и отдавать указания.
 +
 +{{hex-rays_Image_2.png}}
 +
 +Рисунок 3 Hex-Rays – это отдельный продукт и в то же время… plug-in для IDA Pro!
 +
 +Hex-Rays в отличии от ИДЫ интерактивностью не обладает,​ она у него атрофирована еще в зародыше. Нет даже опций настройки! А там где нет интерактивности,​ нет и хакеров,​ а процветает,​ извините за прямому выражения,​ пионерия непроходимого ламеризма. Но, тем не менее… пионер это не ругательство,​ а просто социальный статус. И тут мы плавно переходим к ответу на вопрос кому нужен Hex-Rays.
 +
 +===== >>>​ врезка почем Hex-Rays для народа или\\ по обе стороны от прилавка =====
 +
 +Цены на продукцию фирмы DataRescue постоянно меняются,​ причем в очень широких пределах,​ обусловленных не только спросом,​ но еще и фазами луны, а потому,​ перед совершением покупки необходимо зайти на www.idapro.com и взглянуть на прайс.
 +
 +На момент публикации данной статьи стандартная редакция ИДЫ стоила 515 американских енотов или 360 евриков,​ но стандартная редакция — это не солидно,​ да и покоцана она сильно,​ поэтому,​ лучше сразу рассчитывать на продвинутую (advanced), готовясь раскошелиться на все 985$/​690 EUR.
 +
 +Сам же Hex-Rays стоит…. всего-навсего каких-то жалких 2.299$ (1.500 EUR),​ что вместе с ИДОЙ составляет 3.284$, а в евриках — и того меньше. По сравнению с Мерседесом (даже подержанным!) — сущие пустяки,​ за тем исключением,​ что люди, занимающиеся реверсингом,​ если и ездят на Мерседесах,​ то только взятых на прокат в почасовую оплату.
 +
 +О том, что в России программное обеспечение не покупается,​ а экспроприируется и национализируется,​ переходя в общественное достояние,​ мы скромно промолчим. И у нас даже в мыслях не было говорить о том, что IDA Pro Advanced последней версии в комплексе с Hex-Rays валяется практически во всех файло-обменных сетях.
 +
 +Зададимся вопросом:​ кто же _реально_ готов заплатить три килобакса за декомпилятор?​ Буржуи,​ наверное. Фирмы, занимающиеся реверсингом малвари. Да мало ли еще кто! Вот только,​ среди читательской аудитории таковых скорее всего не окажется,​ а студенческие скидки отсутствуют. Жаль!
 +
 +===== боевое крещение =====
 +
 +Добыли мы, значит,​ Hex-Rays (где добыли?​! купили конечно! мы же состоятельные хакеры,​ можем себе позволить!),​ устанавливаем его туда же, куда IDA Pro ложит все свои plug-in'​ы и приступаем к тестированию.
 +
 +В качестве объекта тестирования используется стандартный "​Блокнот"​ (в данном случае из комплекта поставки W2KSP0), на котором обкатываются все вирусы,​ все упаковщики исполняемых файлов (вместе с распаковщиками),​ все протекторы… словом,​ декомпилятор не станет исключением. А что? Блокнот достаточно простая программа,​ обуславливающая тот минимум функционала,​ ниже которого декомпилятор из мощного программного комплекса превращается в дорогостоящую,​ но абсолютно бесполезную игрушку.
 +
 +{{hex-rays_Image_3.png}}
 +
 +Рисунок 4 "​Блокнот"​ — излюбленный хакерский полигон для всевозможных испытаний
 +
 +Загрузив notepad.exe в IDA Pro и ответив на ряд несложных вопросов мастера авто-анализа,​ даем дизассемблеру некоторое время поработать и когда он перейдет в режим ожидания,​ заходим в меню File  Produce File -> Create C file или нажимаем горячую клавишу <​Ctrl-F5>​.
 +
 +{{hex-rays_Image_4.png}}
 +
 +Рисунок 5 декомпиляция начинается!
 +
 +Сначала на экране появляется логотип Hex-Rays с предложением провериться на обновления (мы же ведь честные пользователи,​ правда?​ так почему мы нам и не провериться?​!) и после нажатия на <OK>, Hex-Rays думает некоторое время, а когда он закончит заниматься магической деятельностью,​ на диске образуется файл notepad.c.
 +
 +{{hex-rays_Image_5.png}}
 +
 +Рисунок 6 кто первый в очереди за обновлениями?​!
 +
 +Ура! Свершилось! Пробуем откомпилировать его компилятором MS VC 6.0,​ предварительно скопировав в текущий каталог файл defs.h из каталога Hex-Rays и заменив в строке #include <​defs.h>​ угловые скобки на двойные кавычки,​ иначе компилятор будет искать defs.h в системном каталоге с включаемыми файлами,​ где, естественно,​ его не обнаружит. Но это мелочи… А вот уже проблема посерьезнее. Компилятор,​ выдав более сотни ошибок,​ просто прерывает компиляцию,​ поскольку продолжать ее дальше — нет никакого смысла.
 +
 +{{hex-rays_Image_6.png}}
 +
 +Рисунок 7 простыня ошибок компиляции декомпилированного листинга
 +
 +Может, мы не тот компилятор выбрали для тестирования?​ Вообще-то,​ по идее, декомпилятор должен выдавать листинг на ANSI C, поддерживаемый любым ANSI-совместимым C-компилятором,​ но… все мы хорошо знаем любовь Ильфака к продукции фирмы Borland. На нем написана сама ИДА, на нем же вышло первое SDK…
 +
 +Хорошо,​ берем последнюю версию Borland C++ (благо она бесплатна) и что же?! Вновь простыня ошибок и ругательств,​ приводящих к преждевременному прерыванию компиляции. Оказывается,​ чтобы откомпилировать декомпилированный файл над ним еще предстоит основательно поработать. Вот тебе, бабушка,​ и раз…
 +
 +А вот тебе и два! Декомпилятор выдал чистый *.c файл, проигнорировав тот факт, что notepad.exe содержит еще и секцию ресурсов,​ но даже если при загрузке "​Блокнота"​ в ИДУ форсировать обработку ресурсов,​ мы все равно ни хвоста не получим. Ну не умеет Hex-Rays с ними работать. Возможно,​ когда ни будь он этому и научиться,​ но сейчас — нет.
 +
 +Другими словами — Hex-Rays не позволяет компилировать декомпилированные программы без дополнительной ручной работы и реально он пригоден лишь для анализа. Возникает резонный вопрос:​ и насколько же он упрощает анализ?​ Чтобы не быть голословным вот два фрагмента кода:
 +
 +if ( RegOpenKeyExA(
 +
 +HKEY_CLASSES_ROOT,​
 +
 +"​CLSID\\{ADB880A6-D8FF-11CF-9377-00AA003B7A11}\\InprocServer32",​
 +
 +0,
 +
 +0x20019u,
 +
 +&hKey) )
 +
 +{
 +
 +result = 0;
 +
 +}
 +
 +else
 +
 +{
 +
 +cbData = 260;
 +
 +if ( !RegQueryValueExA(hKey,​ ValueName, 0, 0, lpData, &​cbData) )v1 = 1;
 +
 +RegCloseKey(hKey);​
 +
 +result = v1;
 +
 +}
 +
 +return result;
 +
 +Листинг 1 фрагмент "​Блокнота",​ декомпилированного Hex-Rays
 +
 +Просто?​ Красиво?​ Понятно?​ Элегантно?​ Да!!! А вот как выглядел тот же самый код в чистом дизассемблере:​
 +
 +.text:​0100318Fpushebp
 +
 +.text:​01003190movebp,​ esp
 +
 +.text:​01003192pushecx
 +
 +.text:​01003193pushecx
 +
 +.text:​01003194leaeax,​ [ebp+hKey]
 +
 +.text:​01003197pushesi
 +
 +.text:​01003198xoresi,​ esi
 +
 +.text:​0100319Apusheax;​ phkResult
 +
 +.text:​0100319Bpush20019h;​ samDesired
 +
 +.text:​010031A0pushesi;​ ulOptions
 +
 +.text:​010031A1pushoffset SubKey; lpSubKey
 +
 +.text:​010031A6push80000000h;​ hKey
 +
 +.text:​010031ABcallds:​RegOpenKeyExA
 +
 +.text:​010031B1testeax,​ eax
 +
 +.text:​010031B3jnzshort loc_10031E7
 +
 +.text:​010031B5leaeax,​ [ebp+cbData]
 +
 +.text:​010031B8mov[ebp+cbData],​ 104h
 +
 +.text:​010031BFpusheax;​ lpcbData
 +
 +.text:​010031C0push[ebp+lpData];​ lpData
 +
 +.text:​010031C3pushesi;​ lpType
 +
 +.text:​010031C4pushesi;​ lpReserved
 +
 +.text:​010031C5pushoffset ValueName; lpValueName
 +
 +.text:​010031CApush[ebp+hKey];​ hKey
 +
 +.text:​010031CDcallds:​RegQueryValueExA
 +
 +.text:​010031D3testeax,​ eax
 +
 +.text:​010031D5jnzshort loc_10031DA
 +
 +.text:​010031D7push1
 +
 +.text:​010031D9popesi
 +
 +.text:​010031DA
 +
 +.text:​010031DA loc_10031DA:;​ CODE XREF: sub_100318F+46↑j
 +
 +.text:​010031DApush[ebp+hKey];​ hKey
 +
 +.text:​010031DDcallds:​RegCloseKey
 +
 +.text:​010031E3moveax,​ esi
 +
 +.text:​010031E5jmpshort loc_10031E9
 +
 +.text:​010031E7 ; ────────────────────────────────────────────────────────────────────
 +
 +.text:​010031E7
 +
 +.text:​010031E7 loc_10031E7:;​ CODE XREF: sub_100318F+24↑j
 +
 +.text:​010031E7 xoreax, eax
 +
 +.text:​010031E9
 +
 +.text:​010031E9 loc_10031E9:;​ CODE XREF: sub_100318F+56↑j
 +
 +.text:​010031E9popesi
 +
 +.text:​010031EAleave
 +
 +.text:​010031EBretn 4
 +
 +Листинг 2 тот же код в чистом дизассемблере
 +
 +Согласитесь,​ что сравнение отнюдь не в пользу дизассемблера,​ но не спешите радоваться. Рассмотрим еще один пример:​
 +
 +if ( (unsigned __int16)a2 == 1 )
 +
 +{
 +
 +dword_1008BCC = dword_1008028;​
 +
 +if ( !dword_1008014 && sub_10059A3(dword_10087D0,​ &​String2,​ 0) )
 +
 +return 1;
 +
 +}
 +
 +Листинг 3 еще один пример работы декомпилятора
 +
 +Что делает этот код? Совершенно непонятно. То есть, не то, чтобы _совсем_ непонятно,​ но смысл как-то ускользает. Тут требуется проанализировать — что это за переменные такие, кто еще (помимо данной функции) их модифицирует и зачем? В дизассемблере листинг выглядит схожим образом (см. листинг 4),​ но мощная система навигации по коду вкупе с перекрестными ссылками и подсветкой одноименных переменных/​функций сокращает время анализа на несколько порядков,​ причем,​ ни в одном текстовом редакторе,​ ни в одной среде программирования подобной системы навигации по коду нет!!!
 +
 +.text:​01002306 loc_1002306:;​ CODE XREF: sub_1002239+C4↑j
 +
 +.text:​01002306moveax,​ dword_1008028
 +
 +.text:​0100230Bpushebx
 +
 +.text:​0100230Cpushedi
 +
 +.text:​0100230Dmovdword_1008BCC,​ eax
 +
 +.text:​01002312pushdword_10087D0
 +
 +.text:​01002318callsub_10059A3
 +
 +.text:​0100231Dtesteax,​ eax
 +
 +.text:​0100231Fjzshort loc_1002328
 +
 +Листинг 4 а это вид в дизассемблере
 +
 +===== заключение =====
 +
 +Hex-Rays – это, безусловно,​ большой шаг вперед и неплохое подспорье для начинающих,​ но… он не стоит тех денег, которые за него просят,​ к тому же, что касается начинающих… однажды потратив время на изучение ассемблера,​ мы обретаем возможность реверисровать что угодно и в чем угодно (на худой конец с помощью утилиты "​DUMPBIN.EXE",​ входящей в состав SDK), а, обольщенные возможностями автоматической декомпиляции,​ мы становимся заложниками Hey-Rays, со всеми отсюда вытекающими…
 +
 +