третий. Хирургический
Не торопитесь на встречу с Богом, еще встретитесь.
Народная мудрость
Внесение изменений непосредственно в исполняемый файл – дело серьезное. Стиснутыми
уже существующим кодом, нам приходится довольствоваться только тем, что есть – и ни раздвинуть команды, ни даже "сдвинуть" их, выкинув из защиты "лишние запчасти",
не получится. Ведь это привело бы к "сдвигу" смещений всех остальных команд, тогда как значения указателей и адресов переходов останутся остались без изменений , – они будут и стали указывать совсем не туда, куда нужно!
Ну, с "выкидываем запчастей" справится как раз таки просто – достаточно забить код командами NOP (опкод который 0x90, а вовсе не 0х0, как почему-то думают многие начинающие кодокопатели) – т.е. пустой операцией (вообще-то NOP это просто другая форма записи инструкции XCHG EAX,EAX – если интересно). С "раздвижкой" куда сложнее! К счастью, в WindowsPE-файлах всегда присутствует множество "дыр", оставшихся от выравнивания – в них-то и можно разместить свой код или данные.
Но не проще ли просто откомпилировать ассемблированный файл, предварительно внеся в него требуемые изменения? Нет, не проще, и вот почему – если ассемблер не распознает указатели, передаваемые функции (а, как мы видели, наш дизассемблер не смог отличить их от констант), он, соответственно, не позаботится должным образом их скорректировать и, естественно, программа работать не будет.
Приходится "резать" программу в "живую". Легче всего это сделать с помощью утилиты HIEW, "переваривающей" PE-формат файлов и упрощающей тем самым поиск нужного фрагмента. Запустим его, указав имя файла в командной строке "hiew simple.exe", двойным нажатием <Enter> переключимся в режим ассемблера и по <F5> перейдем к требуемому адресу. Как мы помним, команда "TEST", проверяющая результат, возвращенный функцией на равенство нулю, располагалась по адресу 0x401056.
0040104E: E8 4D 00 00 00 call 004010A0
00401053: 83 C4 08 add esp,8
00401056: 85 C0 test eax,eax
^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
00401058: 74 0F je 00401069
Чтобы HIEW мог отличить адрес от смещения в самом файле, предварим его символом точки: ".401056"
00401056: 85C0 test eax,eax
00401058: 740F je .000401069 -------- (1)
Ага, как раз то, что нам надо! Нажмем <F3> для перевода HIEW в режим правки, подведем курсор к команде "TEST EAX,EAX" и, нажав <Enter>, заменим ее на "XOR EAX,EAX".
00001056: 33C0 xor eax,eax
00001058: 740F je 000001069
С удовлетворением заметив, что новая команда в аккурат вписалась в предыдущую, нажмем <F9> для сохранения изменений на диске, а затем выйдет из HIEW и попробуем запустить программу, вводя первый пришедший на ум пароль.
>simple.exe
Enter password:Привет, шляпа!
Password OK
Получилось! Защита пала! Хорошо, а как бы мы действовали, не умей HIEW "переваривать" PE-файлы? Тогда бы пришлось прибегнуть к контекстному поиску. Обратим свой взор на шестнадцатеричный дамп, расположенный дизассемблером слева от ассемблерных команд. Конечно, если пытаться найти последовательность "85 C0" – код команды "TEST EAX,EAX" ничего путного из этого не выйдет, – этих самых TEST-ов в программе может быть несколько сотен, а то и больше. Комбинация "ADD ESP,8\TEST EAX,EAX" так же вряд ли будет уникальна, поскольку встречается во многих типовых конструкциях языка Си "if (func(arg1,arg2))…", "if (!func(arg1,arg2))…", "while(func(arg1,arg2)" и т.д. А вот адрес перехода, скорее всего, во всех ветках программы различен и подстрока "ADD ESP,8/TEST EAX,EAX/JE 00401069" имеет хорошие шансы на уникальность.
Попробуем найти в файле соответствующий ей код: "83 C4 08 85 C0 74 0F" (в HIEW-е для этого достаточно нажать <F7>).
Опп-с! Найдено только одно вхождение, что нам собственно и нужно. Давайте теперь попробуем модифицировать файл непосредственно в hex-режиме,
не переходя в ассемблер. Попутно возьмем себе на заметку – инверсия младшего бита кода команды приводит к изменению условия перехода на противоположное. Т.е. 74 JE à
75 JNE.
Работает? (В смысле защита свихнулась окончательно – не признает истинные пароли, зато радостно приветствует остальные). Замечательно! Остается решить: как эту взломанную программу распространять. То есть, распространить-то ее дело не хитрое – на то и существуют CDR-писцы, BBS-ы, сеть Интернет, наконец! Заливай, пиши, нарезай – не хочу. Не хотите – и правильно! Незаконное это дело – распространять программное обеспечение в обход его владельца. Эдак, и засадить могут (причем прецеденты уже имеются). Куда безопаснее возложить распространение программы на ее дистрибьюторов, но до каждого пользователя донести: как эту программу сломать. Ковыряться в законном образом приобретенном приложении потребитель вправе, а распространение информации о взломе не запрещено в силу закона о свободе информации. Правда, при ближайшем рассмотрении выясняется, что этот закон и у нас, и за океаном действует лишь формально, и, если не посадить, то по крайне мере попытаться это сделать, право охранительные органы вполне могут (и не только могут, но и делают). Когда дело касается чьих-то финансовых интересов, правосудие "отдыхает". Наивно думать, что соблюдение закона автоматически дает некие гарантии. Нет, и еще раз нет! Чувствовать себя в относительной безопасности можно лишь при условии соблюдения кодекса "да не навреди сильным мира сего".
В любом случае – информация о взломе это не совсем то же, что сам взлом и за это труднее привлечь к ответственности. Единственная проблема – попробуй-ка, объясни этим пользователям: как пользоваться hex-редактором и искать в нем такие-то байтики.
Запорют же ведь файл за милую душу! Вот для этой цели и существуют автоматические взломщики.
Для начала нужно установить, какие именно байты были изменены. Для этого нам вновь потребуется оригинальная копия модифицированного файла (предусмотрительно сохраненная перед его правкой) и какой-нибудь "сравниватель" файлов. Наиболее популярными на сегодняшний день являются c2u by Professor Nimnul и MakeCrk by Doctor Stein's labs. Первый гораздо предпочтительнее, т.к. он не только более точно придерживается наиболее популярного "стандарта", но и умеет генерировать расширенный xck формат. На худой конец можно воспользоваться и штатной утилитой, входящей в поставку MS-DOS\Windows – fc.exe (сокращение от FileCompare).
Запустим свой любимый компаратор (это уж какой кому больше по душе) и посмотрим на результат его работы:
> fc simple.exe simple.ex_ > simple.dif
^-оригинальный ^ файл ^
L- хакнутый?файл
L- файл различий
> type simple.dif
Сравнение файлов simple.exe и SIMPLE.EX_
00001058: 74 75
Первая слева колонка указывает смещение байта от начала файла, вторая – содержимое байта оригинального файла, а третья – его значение после модификации. Теперь сравним это с отчетом утилиты c2u:
>c2u simple.exe simple.ex_
Все исправления заносятся в файл *.crx, где "*" – имя оригинального файла. Рассмотрим результат сравнения поближе:
>type simple.crx
[BeginXCK]-----------------------------------
¦ Description : $) 1996 by Professor Nimnul
¦ Crack subject :
¦ Used packer : None/UnKn0wN/WWPACK/PKLITE/AINEXE/DIET/EXEPACK/PRO-PACK/LZEXE
¦ Used unpacker : None/UNP/X-TRACT/iNTRUDER/AUT0Hack/CUP/TR0N
¦ Comments :
¦ Target OS : D0S/WiN/WNT/W95/0S¤/UNX
¦ Protection : [--------------------] %17
¦ Type of hack : Bit hack/JMP Correction
¦ Language : UnKn0wN/Turbo/Borland/Quick/MS/Visual C/C++/Pascal/Assembler
¦ Size : 28672
¦ Price : $000
¦ Used tools : TD386 v3.2, HiEW 5.13, C2U/486 v0.10
¦ Time for hack : 00:00:00
¦ Crack made at : 21-07-2001 12:34:21
¦ Under Music : iR0N MAiDEN
[BeginCRA]-----------------------------------
Difference(s) between simple.exe & simple.ex_
SIMPLE.EXE
00001058: 74 75
[EndCRA]-------------------------------------
[EndXCK]-------------------------------------
Собственно, сам результат сравнений ничуть не изменился, разве что к файлу добавился текстовой заголовок, поясняющий, что это за серверный олень такой и с чем его едят. Все поля не стандартизированы, и их набор сильно разнится от одного взломщика к другому, – при желании вы можете снабдить заголовок своими собственными полями или же, напротив, выкинуть из него чужие. Однако не стоит злоупотреблять этим без серьезной необходимости и лучше придерживаться какого-то одного шаблона.
Итак. "Description" – пояснение к взлому, заполняемое в меру буйства фантазии и уровня распущенности. В нашем случае оно может выглядеть, например, так: "Тестовой взлом N1".
"Crack subject" – предмет крака, - т.е. что собственно мы только что сломали. Пишем "Парольная защита simple.exe"
"Used packer" – используемый упаковщик. Еще во времена старушки MS-DOS существовали и были широко распространены упаковщики исполняемых файлов, автоматически разжимающие файл в памяти при его запуске. Этим достигалась экономия дискового пространства (вспомните: какими смехотворными по нынешним временам были размеры винчестеров конца восьмидесятых-начала девяностых?) и параллельно с этим усиливалась защита – ведь упакованный файл недоступен для непосредственного изучения, а тем более – правки. Прежде, чем начать что-то делать, файл необходимо распаковать, причем это делать приходится и самому ломателю, и всем пользователям этого crk-файла. Поскольку, наш файл не был упакован – оставим это поле пустым, или запишем в него "None".
"Used unpacker" – рекомендуемый распаковщик (если он необходим). Дело в том, что не все распаковщики одинаковы, многие упаковщики весьма продвинуты в технике защиты и умело сопротивляются попыткам их "снять". Понятное дело, распаковщики то же не лыком шиты, и держат своих "тузов" в рукавах, но… автоматическая распаковка – штука капризная. Бывает "интеллектуальный" unpacker легко расправляется со всеми "крутыми" packer-ми, но тихо сдыхает на простых защитах, и, соответственно, случается и наоборот. Дабы не мучить пользователей утомительным перебором всех имеющихся у них распаковщиков (пользователь – он ведь то же человек!) правила хорошо тона обязывают указывать по крайней мере один заведомо подходящий unpacker, а лучше – два или три сразу (вдруг какого-то из них у пользователя и не будет). Если же распаковщик не требуется – оставляйте это поле пустым или "None".
"Comments" – комментарии. Вообще-то это поле задумано для перечисления дополнительных действий, которые пользователь должен выполнить перед взломом, ну, например, снять с файла атрибут "системный" или, напротив, установить его. Но, поскольку, какие-либо дополнительные действия требуются только в экзотических случаях, в это поле обычно помещают разнообразные лозунги и комментарии (да, правильно, бывает и нецензурную брань по поводу умственных способностей разработчика защиты).
"Target OS" – операционная система для которой предназначен и (внимание!) в которой хакер тестировал сломанный продукт. Вовсе не факт, что программа сохранит после взлома черты своей прежней совместимости. Так, например, поле контрольной суммы Win 9x всегда игнорирует, а Win NT – нет и если его не скорректировать, файл запускаться не будет! В нашем случае контрольная сумма заголовка PE-файла равна нулю (так ведет себя компилятор), что означает – целостность файла не проверяется и он, после хака, будет успешно работать как под Win 9x, так и под Win NT.
"Protection" – степень "крутизны" защиты, выражаемой в процентах. 100% по идее соответствуют пределу интеллектуальных возможностей хакера – но кто же в этом захочет признаваться? Неудивительно, что "крутизну" защиты обычно занижают, порой даже больше, чем на порядок (смотрите все, вот я какой крутой хакер, для меня что угодно взломать не сложнее чем кончик хвоста обмочить!). Нечестность – не порок, но…
"Type of hack" – тип хака, - поле полезное, скорее для других хакеров, чем для пользователей, ничего не смыслящих в защитах и типах их взлома. Впрочем, с типами взломов не все гладко и у самих хакеров – общепризнанных классификацией нет. Наиболее употребляемый термин "bit-hack", как и следует из его названия, обозначает взлом посредством изменения одного или нескольких бит в одном или нескольких байтах. Частный случай bit-hack-а – JMP correction (jumping) – модификация адреса или условия перехода (то, что мы только что и проделали). "NOPing" – это bit-hack с заменой прежних инструкций на команду NOP или вставку незначащих команд, например для затирания двухбайтового JZ xxx можно применить сочетание однобайтовых INC EAX/DEC EAX.
"Language" – язык, а точнее компилятор, на котором написана программа. В нашем случае Microsoft Visual C++ (мы это знаем, поскольку только что ее компилировали), а вот как быть с чужими программами? Первое, что приходит на ум, – поискать в файле копирайты – их оставляют очень многие компиляторы, в том числе и Visual C++ - сморите: "000053d9:Microsoft Visual C++ Runtime Library". Если же компиляторов нет, то пробуем прогнать файл через IDA – она автоматически распознает большинство стандартных библиотек даже с указанием конкретной версии. В крайнем случае – пробует определить язык по самому коду, вспоминая о соглашениях Си и Паскаль, и пытаясь найти знакомые черты известных вам компиляторов (у каждого компилятора свой "почерк" и опытный хакер можно узнать не только чем компилировалась программа, но даже определить ключ оптимизации).
"Size" – размер ломаемой программы, служащий для контроля версии (чаще всего, хотя и не всегда, каждая версия программы имеет свой размер). Размер автоматически определяется утилитой c2u и самостоятельно его вставлять нет никакой нужды.
"Price" – стоимость лицензионной копии программы (должен же пользовать знать: сколько денег ему сэкономитсэкономил
этот крак!)
"Used tools" – используемые инструменты. Не заполнение этого поля считается дурным тоном – действительно же, интересно, чем именно была хакнута программа! Особенно этим интересуются пользователи, наивно полагающие, что если они раздобудут тот же DUMPBIN и HIEW защита сама собой сломается.
"Time for hack" – время, затраченное на хак, включая перерывы на "перекурить" и "сходить водички попить". Интересно, какой процент людей честно заполняет это поле, не пытаясь показаться "куче" в чужих глазах. Так что особенно доверять ему не следует…
"Crack made at" – дата завершения крака. Подставляется автоматически и править ее нет необходимости (разве что вы "жаворонок" и хотите выдать себя за "сову", проставляя время окончания взлома 3 часами ночи 31 декабря)
"Under Music" – музыка, прослушиваемая во время хака (еще не хватает поля "Имя любимого хомячка"). Вы слушали музыку во время хака? Если да – то пишете – пусть все знают ваши вкусы (за одно не забудьте цвет майки и температуру воздуха за ботом выше нуля).
В результате всех мучений у нас должно получится приблизительно следующее:
[BeginXCK]-----------------------------------
¦ Description : Тестовый взлом №1
¦ Crack subject : Парольная
защита simple.exe
¦ Used packer : None
¦ Used unpacker : None
¦ Comments : Hello, Sailor! Ты слишклм долго плавал!
¦ Target OS : WNT/W95
¦ Protection : [--------------------] %1
¦ Type of hack : JMP Correction
¦ Language : Visual C/C++
¦ Size : 28672
¦ Price : $000
¦ Used tools : DUMPBIN, HiEW 6.05, C2U/486 v0.10 & Brain
¦ Time for hack : 00:10:00
¦ Crack made at : 21-07-2001 12:34:21
¦ Under Music : Paul Mauriat L'Ete Indeien "Africa"
[BeginCRA]-----------------------------------
Difference(s) between simple.exe & simple.ex_
SIMPLE.EXE
00001058: 74 75
[EndCRA]-------------------------------------
[EndXCK]-------------------------------------
Теперь нам потребуется другая утилита, цель которой прямо противоположна: используя crk (xcrk) файл, изменить эти самые байты в оригинальной программе. Таких утилит на сегодняшний день очень много, что не лучшим образом сказывается на их совместимости с различными crk форматами. Самые известные из них, – cra386 by Professor и pcracker by Doctor Stein's labs.
Из современных Windows-разработок можно отметить "Patch maker" с продвинутым пользовательским интерфейсом (см. Рисунок 2). Он включает в себя сравниватель файлов, crk-редактор, hex-редактор (для ручной замены?) и компилятор crk в исполняемые файлы, чтобы пользователям не приходилось ломать голову: что это за крак такой и как им ломать.
Может, кому-то такой интерфейс и понравится, а вот хакеры в свой массе мышь органически не переносят и любят текстовые (консольные) приложения и тетю Клаву.
Рисунок 2 0x001 Patch Maker за работой!