Сейчас на форуме: asfa, bartolomeo (+7 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› Нужна помощь с защитой |
Посл.ответ | Сообщение |
|
Создано: 03 апреля 2012 08:17 · Личное сообщение · #1 Всем привет! Я новичок в крэкинге, поэтому если назову что-то не так, просьба не пинать сильно ![]() Пробую разобраться с защитой одной программы. Она отказывается запускаться, если вызывается, например, из своего приложения. Также вылетает при попытках отладки дебаггером (использовал Олли). При запуске из ком. строки работает нормально. В принципе идею защиты я понял, не понял механизма работы. Смысл в том, что когда открываешь прогу в Олли все адреса находятся в диапазоне условно 00400000-00500000, а непосредственно текстовка самой программы появляется динамически и находится в диапазоне 02000000-.... Эти адреса в самом начале работы программы недоступны, потом видимо происходит то ли распаковка, то ли расшифровка (а может еще что-то) и вызов первой функции из этого динамически созданного адресного пространства осуществляется через CALL EAX, где в EAX соответственно и находится "точка входа" в эту динамическую область. Дальше уже в ней с защитными механизмами все более-менее понятно. По крайней мере правя "по ходу" в Олли удалось запустить ее под отладчиком, убрать остальные ограничения. Вопрос в следующем: как пропатчить такого рода exe-шник? Пробывал просто добавить значение EAX, чтобы попадать сразу на "чистую" область, но пропускаю нужную инициализацию и прога виснет. Попытка дописать в основной части "изменялку" вида mov dword ptr ds:[eax+6c],нужное значение, чтобы условный переход, находящийся по этому адресу в динамической области, осуществлялся куда следуют не удалась, т.к. Access violation. Что следует предпринять в таком случае? ![]() |
|
Создано: 03 апреля 2012 09:07 · Поправил: Veliant · Личное сообщение · #2 Способ 1: Распаковать прогу, сдампив после call eax и править сколько душе влезет Способ 2: Пропатчить код так, чтобы call eax прыгал на ваш код, который будет патчить распакованный код в памяти, и потом прыгать дальше по адресу из eax. Для избавления от Acces Violation нужно еще вызывать VirtualProtect с PAGE_EXECUTE_READWRITE ![]() |
|
Создано: 03 апреля 2012 11:30 · Личное сообщение · #3 |
|
Создано: 03 апреля 2012 22:46 · Поправил: kamvin · Личное сообщение · #4 2Veliant: "Распаковать прогу, сдампив после call eax" Вот это меня очень инетересует. Как это сделать (распаковать и сдампить)? Хотя, если честно, то с "вызывать VirtualProtect с PAGE_EXECUTE_READWRITE " вопросов не меньше ![]() Попробую разобраться... 2DimitarSerg: Уверен, но с учетом того, что опыта исследования программ нет. А вообще х.з. В принципе там один EXE-ник только, поэтому чтобы вызывать dll надо иметь копию ее двоичного кода в теле файла, потом в temp-e создавать dll и ее линковать. Так? Таргет: ![]() |
|
Создано: 03 апреля 2012 23:11 · Поправил: MasterSoft · Личное сообщение · #5 kamvin пишет: потом в temp-e создавать dll и ее линковать. не самый красивый вариант, скорее для ленивых. можно по-другому и писать её на диск не обязательно, многие проты примерно так и делают: грузят в память, строят импорт и т.д. я бы советовал второй вариант, по-крайней мере мне он больше нравиться. Added: DimitarSerg пишет: А ты уверен, что эта "текстовка" (классно названо) не в длл ?! глянул, да, оно в длл ![]() |
|
Создано: 03 апреля 2012 23:27 · Личное сообщение · #6 |
|
Создано: 03 апреля 2012 23:31 · Поправил: MasterSoft · Личное сообщение · #7 NikolayD пишет: Там BoxedAppPacker. да похер. с этого места: Code:
пишешь тут джамп на свой код, который будет патчить кодекс в загруженной длл. сохраняешь регистры разумеется потом восстанавливаешь. сложного ничего не увидел. added: tihiy_grom инфы дали, если хочет сделать - сделает. тем более msdn никто не отменял. ток при патче про виртуалпротект не забудь, а то эксепшен схлопочешь ![]() |
|
Создано: 03 апреля 2012 23:33 · Поправил: tihiy_grom · Личное сообщение · #8 беда всего лишь одна ... kamvin пишет: Хотя, если честно, то с "вызывать VirtualProtect с PAGE_EXECUTE_READWRITE " вопросов не меньше kamvin пишет: с учетом того, что опыта исследования программ нет kamvin почитайте что ли ![]() |
|
Создано: 03 апреля 2012 23:35 · Личное сообщение · #9 |
|
Создано: 04 апреля 2012 02:23 · Личное сообщение · #10 |
|
Создано: 06 апреля 2012 05:18 · Личное сообщение · #11 Всем спасибо большое за советы!!! Попробывал сделать так (все в Olly): Code:
а перед Code:
Code:
В итоге, адрес перехода в dll поменялся на нужный, исключающий проверки, но программа работать отказалась. В этой связи возникли вопросы: 1. Я вставлял код фунции в конец файла, в область которая в Олли выглядит как последовательность строк Code:
2. Можно ли в функции VirtualProtect менять права доступа для отдельных байт с произвольного смещения? В гугле по этому поводу мнения разные. 3. Т.к. Олли формирует таблицу импортируемых функций, то вызов call VirtualProtect прошел нормально, имя функции было заменено дебаггером на ее адрес. Как вычислять адрес функции, если правишь в простом редакторе, например hiew32? Вызывать GetProcAddress? Я пробывал, но не понял как передать в эту функцию строковые значения? 4. Какими редакторами (кроме hiew32) можно править дизассемблированный код и потом сохранять его? 5. Вообще правильно ли я делал? ![]() |
|
Создано: 06 апреля 2012 12:50 · Поправил: Veliant · Личное сообщение · #12 kamvin пишет: а перед call eax вставил call адрес Если так, то в твоем коде вначале должна идти команда, которую ты затер call'ом на себя kamvin пишет: 1. Я вставлял код фунции в конец файла, в область которая в Олли выглядит как последовательность строк Все правильно kamvin пишет: 2. Можно ли в функции VirtualProtect менять права доступа для отдельных байт с произвольного смещения? В гугле по этому поводу мнения разные. Так первый параметр задает адрес, второй для скольки байт, что не так? Кстати PAGE_EXECUTE_READWRITE = 0x40, у тебя же 4 = PAGE_READWRITE, поэтому когда код там начинает выполняться срабатывает Exception kamvin пишет: 3. Т.к. Олли формирует таблицу импортируемых функций, то вызов call VirtualProtect прошел нормально, имя функции было заменено дебаггером на ее адрес. Как вычислять адрес функции, если правишь в простом редакторе, например hiew32? Вызывать GetProcAddress? Я пробывал, но не понял как передать в эту функцию строковые значения? Для начала поищи в импорте, может уже есть там адрес VirtualProtect. Если нет, но есть GetProcAddress, то сначала через GetModuleHandle или из PEB находишь базовый адрес kernel32, потом пишешь что-то вроде такого Code:
Если нет ни того, ни другого, то остается парсить таблицу экспорта вручную, или добавлять в таблицу импорта нужные тебе API kamvin пишет: 4. Какими редакторами (кроме hiew32) можно править дизассемблированный код и потом сохранять его? Можно в той же ollydbg сохранять изменения. ПКМ->Copy to executable. ![]() |
|
Создано: 06 апреля 2012 12:50 · Поправил: Konstantin · Личное сообщение · #13 |
|
Создано: 06 апреля 2012 16:15 · Поправил: kamvin · Личное сообщение · #14 Спасибо! 2Veliant: "Если так, то в твоем коде вначале должна идти команда, которую ты затер call'ом на себя" Нет, я затирал NOP-ы, идущие после. Т.е. мой код идет на месте call eax, затерев его и retn, а потом я их дописал на nop-ах Пока разбирался, в нескольких разных статьях прочитал, что нельзя использовать PAGE_EXECUTE_READWRITE, а надо PAGE_READWRITE (статьи про подмену содержимого API функций). Поэтому решил сделать так же. Исправлю! Про смещения: в Линуксе есть похожая функция, но она позволяет менять разрешения для доступа только тогда, когда адрес выровнен по странице памяти. Здесь как? Одни пишут, что можно менять любые, другие - что надо вычислять адрес начала страницы и менят целиком на всю страницу. Если второе, то как вычислять этот адрес страницы? "Для начала поищи в импорте..." А как поискать? Я думал, что GetProcAddress как раз этим и должна заниматься -по таблице импорта определять адрес функции. Как еще можно искать в таблице? 2Konstantin: Я мыслил так: pushad - поместит все текущие значения регистров в стек. Затем 4 push-a - это передача параметров для функции (они уйдут из стека после ее вызова) и затем возврат регистрам их первончальных значений. Я ваш код записал, попробую сегодня, просто хотелось знать, в чем конкретно я ошибся. ![]() |
|
Создано: 06 апреля 2012 16:37 · Поправил: Veliant · Личное сообщение · #15 kamvin пишет: но она позволяет менять разрешения для доступа только тогда, когда адрес выровнен по странице памяти. Здесь как? Из архитектуры страничной адресации памяти так и есть. Минимальная возможная единица памяти - страница, и как правило в 4кб. Но я так понимаю windows смотрит access violation и сравнивает, наш это блок или нет. kamvin пишет: А как поискать? Открыть в любом PE редакторе и посмотреть таблицу импорта kamvin пишет: в чем конкретно я ошибся. Add: Konstantin, да протупил малость, ты прав, перезатрется не 4, а один из сохраненных регистров. ![]() |
|
Создано: 06 апреля 2012 17:10 · Поправил: Konstantin · Личное сообщение · #16 Veliant пишет: Не критичная ошибка. push esp положит в стек адрес в стеке Ага, а потом VirtualProtect положит по этому "адрес в стеке" - pOldProtect. А далее popad запихнет его в регисты. Может и не критичная, а может оказаться и критичной. В моей же версии - первый push esp резервирует место для pOldProtect (можно любой регистр в стэк положить), а второй push esp это сам адрес pOldProtect. kamvin пишет: А как поискать? Чуть ниже EP проги есть такой код. Code:
Соответственно CALL DWORD PTR DS:[58E6A0] и будет вызов VirtualProtect ![]() |
|
Создано: 06 апреля 2012 17:40 · Личное сообщение · #17 |
|
Создано: 06 апреля 2012 21:26 · Личное сообщение · #18 Спасибо! Сохранил из Олли, исправленный файл отработал нормально. Про esp понял, я и правда не учел, что он на стек указывает... Остался вопрос про адрес функции. Вариант открыть и посмотреть в таблице импорта ясен. У меня сомнения (непроверенные) вот в чем: а будет ли этот адрес одинаков при запусках на другой машине или даже на этой, но с другой загрузкой. Если я найду функцию и жестко вобью ее текущий адрес, я смогу запустить программу что называется "здесь и сейчас", но смогу ли я ее запустить с тем же успехом где-то еще и в другое время? Пробывал получить адрес функции динамически, через GetProcAddress, но столкнулся с двумя непонятками: 1. не получилось задать строковую константу. Когда я пытаюсь ввести строку типа "db 'VirtualProtect', 0" Olly выдает ошибку "Constant required" 2. Адрес функции GetprocAddress тоже надо знать ![]() ![]() |
|
Создано: 06 апреля 2012 23:09 · Поправил: Konstantin · Личное сообщение · #19 kamvin пишет: 1. не получилось задать строковую Ctrl+E вам в помощь. Есть ещё отличный kamvin пишет: 2. Адрес функции GetprocAddress На EP данной проги есть вся эта процедура получения адреса. Что мешает посмотреть самому в отладчике? (См. мой прошлый пост.) kamvin пишет: а будет ли этот адрес одинаков при запусках Не совсем понятно про какой адрес спрашиваете. Действительный адрес в kernel32.VirtualProtect или косвенный в IAT? ![]() |
|
Создано: 07 апреля 2012 06:04 · Личное сообщение · #20 "Не совсем понятно про какой адрес спрашиваете. Действительный адрес в kernel32.VirtualProtect или косвенный в IAT? " Скорее всего про адрес в таблице адресов. Насколько я понимаю именно он должен использоваться во всех вызовах CALL. И ситуация когда, например, из kernel32 ничего не импортируется, а есть какая-то динамически подключаемая DLL с какой-то нужной функцией. Её адрес в IAT может меняться от загрузки к загрузке... Ладно, чувствую, что пока толком не знаю, что конкретно спросить ![]() Спасибо большое за советы!!! Было очень занятно (и получившаяся программа может пригодится когда-нибудь), а пока поищу еще что-нибудь интересное для анализа ![]() |
|
Создано: 07 апреля 2012 11:25 · Личное сообщение · #21 |
![]() |
eXeL@B —› Вопросы новичков —› Нужна помощь с защитой |