Сейчас на форуме: asfa, bartolomeo (+7 невидимых)

 eXeL@B —› Вопросы новичков —› Нужна помощь с защитой
Посл.ответ Сообщение

Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 апреля 2012 08:17
· Личное сообщение · #1

Всем привет!
Я новичок в крэкинге, поэтому если назову что-то не так, просьба не пинать сильно
Пробую разобраться с защитой одной программы. Она отказывается запускаться, если вызывается, например, из своего приложения. Также вылетает при попытках отладки дебаггером (использовал Олли). При запуске из ком. строки работает нормально. В принципе идею защиты я понял, не понял механизма работы. Смысл в том, что когда открываешь прогу в Олли все адреса находятся в диапазоне условно 00400000-00500000, а непосредственно текстовка самой программы появляется динамически и находится в диапазоне 02000000-....
Эти адреса в самом начале работы программы недоступны, потом видимо происходит то ли распаковка, то ли расшифровка (а может еще что-то) и вызов первой функции из этого динамически созданного адресного пространства осуществляется через CALL EAX, где в EAX соответственно и находится "точка входа" в эту динамическую область. Дальше уже в ней с защитными механизмами все более-менее понятно. По крайней мере правя "по ходу" в Олли удалось запустить ее под отладчиком, убрать остальные ограничения. Вопрос в следующем: как пропатчить такого рода exe-шник? Пробывал просто добавить значение EAX, чтобы попадать сразу на "чистую" область, но пропускаю нужную инициализацию и прога виснет. Попытка дописать в основной части "изменялку" вида mov dword ptr ds:[eax+6c],нужное значение, чтобы условный переход, находящийся по этому адресу в динамической области, осуществлялся куда следуют не удалась, т.к. Access violation. Что следует предпринять в таком случае?



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 03 апреля 2012 09:07 · Поправил: Veliant
· Личное сообщение · #2

Способ 1:
Распаковать прогу, сдампив после call eax и править сколько душе влезет
Способ 2:
Пропатчить код так, чтобы call eax прыгал на ваш код, который будет патчить распакованный код в памяти, и потом прыгать дальше по адресу из eax. Для избавления от Acces Violation нужно еще вызывать VirtualProtect с PAGE_EXECUTE_READWRITE




Ранг: 253.5 (наставник), 684thx
Активность: 0.260.25
Статус: Участник
radical

Создано: 03 апреля 2012 11:30
· Личное сообщение · #3

kamvin
Таргет выложи....
kamvin пишет:
текстовка самой программы

А ты уверен, что эта "текстовка" (классно названо) не в длл ?!

-----
ds




Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 апреля 2012 22:46 · Поправил: kamvin
· Личное сообщение · #4

2Veliant:
"Распаковать прогу, сдампив после call eax"
Вот это меня очень инетересует. Как это сделать (распаковать и сдампить)?
Хотя, если честно, то с "вызывать VirtualProtect с PAGE_EXECUTE_READWRITE " вопросов не меньше
Попробую разобраться...

2DimitarSerg:
Уверен, но с учетом того, что опыта исследования программ нет. А вообще х.з. В принципе там один EXE-ник только, поэтому чтобы вызывать dll надо иметь копию ее двоичного кода в теле файла, потом в temp-e создавать dll и ее линковать. Так?
Таргет: --> Link <-- (триальная версия)



Ранг: 281.8 (наставник), 272thx
Активность: 0.250.01
Статус: Участник
Destroyer of protectors

Создано: 03 апреля 2012 23:11 · Поправил: MasterSoft
· Личное сообщение · #5

kamvin пишет:
потом в temp-e создавать dll и ее линковать.

не самый красивый вариант, скорее для ленивых. можно по-другому и писать её на диск не обязательно, многие проты примерно так и делают: грузят в память, строят импорт и т.д. я бы советовал второй вариант, по-крайней мере мне он больше нравиться.

Added:
DimitarSerg пишет:
А ты уверен, что эта "текстовка" (классно названо) не в длл ?!

глянул, да, оно в длл



Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 03 апреля 2012 23:27
· Личное сообщение · #6

Там BoxedAppPacker.



Ранг: 281.8 (наставник), 272thx
Активность: 0.250.01
Статус: Участник
Destroyer of protectors

Создано: 03 апреля 2012 23:31 · Поправил: MasterSoft
· Личное сообщение · #7

NikolayD пишет:
Там BoxedAppPacker.

да похер. с этого места:

Code:
  1. 0040291F  |.  FFD0          call    eax


пишешь тут джамп на свой код, который будет патчить кодекс в загруженной длл. сохраняешь регистры разумеется потом восстанавливаешь. сложного ничего не увидел.

added:
tihiy_grom
инфы дали, если хочет сделать - сделает. тем более msdn никто не отменял.

ток при патче про виртуалпротект не забудь, а то эксепшен схлопочешь



Ранг: 441.3 (мудрец), 297thx
Активность: 0.410.04
Статус: Участник

Создано: 03 апреля 2012 23:33 · Поправил: tihiy_grom
· Личное сообщение · #8

беда всего лишь одна ...
kamvin пишет:
Хотя, если честно, то с "вызывать VirtualProtect с PAGE_EXECUTE_READWRITE " вопросов не меньше

kamvin пишет:
с учетом того, что опыта исследования программ нет


kamvin
почитайте что ли это



Ранг: 617.3 (!), 677thx
Активность: 0.540
Статус: Участник

Создано: 03 апреля 2012 23:35
· Личное сообщение · #9

Да вроде ихний софт кейгенился даже новичками.



Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 04 апреля 2012 02:23
· Личное сообщение · #10

Это точно, из всего серийника только 2 символа рандомны DDD



Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 06 апреля 2012 05:18
· Личное сообщение · #11

Всем спасибо большое за советы!!!

Попробывал сделать так (все в Olly):

Code:
  1. pushad
  2. push esp
  3. push 4
  4. push 8
  5. add eax,6e
  6. push eax
  7. call VirtualProtect
  8. popad
  9. mov dword ptr ds:[eax+6e], новое значение
  10. retn


а перед
Code:
  1. call eax
вставил
Code:
  1. call адрес


В итоге, адрес перехода в dll поменялся на нужный, исключающий проверки, но программа работать отказалась.
В этой связи возникли вопросы:
1. Я вставлял код фунции в конец файла, в область которая в Олли выглядит как последовательность строк
Code:
  1. db 00
. Можно ли делать вставку в эту область? Если нет, то куда можно и как выделять место в файле под свой дополнительный код? Там есть последовательности NOP-ов, но мне их не хватило (да они наверное далеко не в каждом файле есть)...
2. Можно ли в функции VirtualProtect менять права доступа для отдельных байт с произвольного смещения? В гугле по этому поводу мнения разные.
3. Т.к. Олли формирует таблицу импортируемых функций, то вызов call VirtualProtect прошел нормально, имя функции было заменено дебаггером на ее адрес. Как вычислять адрес функции, если правишь в простом редакторе, например hiew32? Вызывать GetProcAddress? Я пробывал, но не понял как передать в эту функцию строковые значения?
4. Какими редакторами (кроме hiew32) можно править дизассемблированный код и потом сохранять его?
5. Вообще правильно ли я делал?



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 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:
  1. call m1:
  2. db 'VirtualProtect', 0
  3. m1:
  4. push hKernel32
  5. call [GetProcAddress]

Если нет ни того, ни другого, то остается парсить таблицу экспорта вручную, или добавлять в таблицу импорта нужные тебе API

kamvin пишет:
4. Какими редакторами (кроме hiew32) можно править дизассемблированный код и потом сохранять его?
Можно в той же ollydbg сохранять изменения. ПКМ->Copy to executable.



Ранг: 42.9 (посетитель), 33thx
Активность: 0.040
Статус: Участник

Создано: 06 апреля 2012 12:50 · Поправил: Konstantin
· Личное сообщение · #13

kamvin
Если делать, то так
Code:
  1. pushad
  2. push esp
  3. push esp
  4. push 40
  5. push 8
  6. add eax,6e
  7. push eax
  8. call VirtualProtect
  9. pop eax
  10. popad
  11. mov dword ptr ds:[eax+6e], новое значение
  12. retn

А так как у вас сделано, затрет стэк.



Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 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 - это передача параметров для функции (они уйдут из стека после ее вызова) и затем возврат регистрам их первончальных значений. Я ваш код записал, попробую сегодня, просто хотелось знать, в чем конкретно я ошибся.



Ранг: 301.4 (мудрец), 194thx
Активность: 0.170.01
Статус: Участник

Создано: 06 апреля 2012 16:37 · Поправил: Veliant
· Личное сообщение · #15

kamvin пишет:
но она позволяет менять разрешения для доступа только тогда, когда адрес выровнен по странице памяти. Здесь как?

Из архитектуры страничной адресации памяти так и есть. Минимальная возможная единица памяти - страница, и как правило в 4кб. Но я так понимаю windows смотрит access violation и сравнивает, наш это блок или нет.
kamvin пишет:
А как поискать?

Открыть в любом PE редакторе и посмотреть таблицу импорта

kamvin пишет:
в чем конкретно я ошибся.

Не критичная ошибка. push esp положит в стек адрес в стеке, в котором 4 лежит. Проблемы в этом не вижу. Параметр все равно раньше будет использован, прежде чем перезапишется

Add:
Konstantin, да протупил малость, ты прав, перезатрется не 4, а один из сохраненных регистров.



Ранг: 42.9 (посетитель), 33thx
Активность: 0.040
Статус: Участник

Создано: 06 апреля 2012 17:10 · Поправил: Konstantin
· Личное сообщение · #16

Veliant пишет:
Не критичная ошибка. push esp положит в стек адрес в стеке

Ага, а потом VirtualProtect положит по этому "адрес в стеке" - pOldProtect. А далее popad запихнет его в регисты.

Может и не критичная, а может оказаться и критичной.

В моей же версии - первый push esp резервирует место для pOldProtect (можно любой регистр в стэк положить), а второй push esp это сам адрес pOldProtect.

kamvin пишет:
А как поискать?

Чуть ниже EP проги есть такой код.
Code:
  1. 005916BB    A1 A4E65800     MOV EAX,DWORD PTR DS:[58E6A4]
  2. 005916C0    68 58E75800     PUSH 0058E758                            ; ASCII "VirtualProtect"
  3. 005916C5    56              PUSH ESI
  4. 005916C6    FFD0            CALL EAX
  5. 005916C8    A3 A0E65800     MOV DWORD PTR DS:[58E6A0],EAX
  6.  

Соответственно CALL DWORD PTR DS:[58E6A0] и будет вызов VirtualProtect




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 06 апреля 2012 17:40
· Личное сообщение · #17

Не надо ничего выравнивать в адресах памяти, винда сама базовый адрес обрежет до начала страницы, а размер округлит вверх до конца страницы. И выставит атрибуты на всю страницу(ы) целиком, никаких сравнений на части страницы при исключениях не будет.



Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 06 апреля 2012 21:26
· Личное сообщение · #18

Спасибо! Сохранил из Олли, исправленный файл отработал нормально.
Про esp понял, я и правда не учел, что он на стек указывает...

Остался вопрос про адрес функции. Вариант открыть и посмотреть в таблице импорта ясен. У меня сомнения (непроверенные) вот в чем: а будет ли этот адрес одинаков при запусках на другой машине или даже на этой, но с другой загрузкой. Если я найду функцию и жестко вобью ее текущий адрес, я смогу запустить программу что называется "здесь и сейчас", но смогу ли я ее запустить с тем же успехом где-то еще и в другое время?
Пробывал получить адрес функции динамически, через GetProcAddress, но столкнулся с двумя непонятками:
1. не получилось задать строковую константу. Когда я пытаюсь ввести строку типа "db 'VirtualProtect', 0" Olly выдает ошибку "Constant required"
2. Адрес функции GetprocAddress тоже надо знать Получается замкнутый круг



Ранг: 42.9 (посетитель), 33thx
Активность: 0.040
Статус: Участник

Создано: 06 апреля 2012 23:09 · Поправил: Konstantin
· Личное сообщение · #19

kamvin пишет:
1. не получилось задать строковую

Ctrl+E вам в помощь. Есть ещё отличный плагин.

kamvin пишет:
2. Адрес функции GetprocAddress

На EP данной проги есть вся эта процедура получения адреса. Что мешает посмотреть самому в отладчике? (См. мой прошлый пост.)

kamvin пишет:
а будет ли этот адрес одинаков при запусках

Не совсем понятно про какой адрес спрашиваете. Действительный адрес в kernel32.VirtualProtect или косвенный в IAT?



Ранг: 2.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 07 апреля 2012 06:04
· Личное сообщение · #20

"Не совсем понятно про какой адрес спрашиваете. Действительный адрес в kernel32.VirtualProtect или косвенный в IAT? "

Скорее всего про адрес в таблице адресов. Насколько я понимаю именно он должен использоваться во всех вызовах CALL. И ситуация когда, например, из kernel32 ничего не импортируется, а есть какая-то динамически подключаемая DLL с какой-то нужной функцией. Её адрес в IAT может меняться от загрузки к загрузке...
Ладно, чувствую, что пока толком не знаю, что конкретно спросить Поэтому закончим.

Спасибо большое за советы!!! Было очень занятно (и получившаяся программа может пригодится когда-нибудь), а пока поищу еще что-нибудь интересное для анализа



Ранг: 189.9 (ветеран), 334thx
Активность: 0.30
Статус: Участник

Создано: 07 апреля 2012 11:25
· Личное сообщение · #21

kamvin, почитай может пригодится --> BoxApp_unpack_y_analisis_de_emulacion_de_loader <--


 eXeL@B —› Вопросы новичков —› Нужна помощь с защитой
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати