ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Распаковка RLPack 1.xx
  #1  
Старый 07.03.2007, 13:46
Аватар для taha
taha
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
Провел на форуме:
2472378

Репутация: 1077
По умолчанию Распаковка RLPack 1.xx


[iNtr0]

Юность в сапогах отменяется, по крайней мере на семестр, поэтому решил посмотреть, что же там, в разделе CrackMe, происходит. Первый в списке крякми Zlo'го. По словам автора, он использует один малоизвестный, но очень хороший прот. Стало интересно, что за протектор такой, что распаковать не могут. Вобщем, сегодня я поведаю о результатах исследования.

[t00ls]

OllyDbg (XP / Shadow кому какая больше нравится) // отладчик
// Статья для новичков, поэтому я взял минимальный набор плагинов
// только самое необходимое. Впоследствии мы будем дополнять нашу подборку.
// Эти плаги, и последующие, можно достать на tuts4you.com
[+] OllyDump
[+] OllyScript
[+] CommandBar
// И ещё вот эти тулзы
IDA // лучший дизассемблер
ImpREC // тулза для восстановления импорта
LordPE // PE Editor

[BeGin]

Итак, начнём. Грузим запакованную прогу в Olly. Будем пропускать все исключения.



Стек забивается регистрами, потом выравнивается. Далее следует pusha, интересно (тут я предполагаю, что вы читали статьи по распаковке и знаете , почему эта команда нас интересует ), но пока нас это не касается. Сперва попробуем запустить программу по F9.

[anti-debugg]

Первую глупость, которую сделал этот протектор, он выдал MessageBox о том, что его отлаживают. Не теряем времени! Пока висит MessageBox, мы переключаемся на OllyDbg и жмём Ctrl-G (что означает переход либо по адресу, либо по метке). В открывшемся окне пишем MessageBoxA и жмем enter. Мы попали в тело функции, ставим бряк на "POP EBP".

Код:
77D7052A   E8 2D000000      CALL user32.MessageBoxExA
77D7052F   5D               POP EBP
Жмём в MessageBox OK и брякаемся.



Снимаем бряк и выходим из функции (пару раз F8).

И вот функция проверки на наличие отладчика



По ходу, функция проверяет две переменные на равенство единице. Если хотябы одна равна единице, то выдаётся MessageBox. Нужно поставить на них брикпоинты. Для этого в CmdBar пишем следующие строки: "hr EBP+1EB2", "hr EBP+1EB6". Перезапускаем прогу Ctrl-F2, F9.
Код:
004FBEC5  |. FF95 A21E0000  CALL DWORD PTR SS:[EBP+1EA2]
004FBECB  |. 0BC0           OR EAX,EAX
004FBECD  |. 74 06          JE SHORT CrackMe2.004FBED5
004FBECF  |. 8985 B21E0000  MOV DWORD PTR SS:[EBP+1EB2],EAX
Как можно заметить, после выполнения некой функции, результат проверяется на равенство нулю. И если не ноль, то результат заносится в одну из наших переменных. Поставим hardware, on execution брикпоинт на эту функцию. Перезапускаемся (Ctrl-F2), F9.

Код:
004FBEC5  |. FF95 A21E0000  CALL DWORD PTR SS:[EBP+1EA2]     ;kernel32.IsDebuggerPresent
Знакомая функция, функция проверяет, присутсвует ли отладчик. В чём проблема? - Спросит читатель - Патчить функцию! А нет, всё дело в устройстве IsDebuggerPresent. Дело в том, что она опирается на одну интересную структуру PEB (блок окружения процесса), в которой есть поле BeingDebugged. В котором хранится 1 если процесс отлаживают, 0 если процесс не отлаживают. Этим и занимается IsDebuggerPresent, тоесть проверяет это поле.

Вот она IsDebuggerPresent:
Код:
MOV EAX,DWORD PTR FS:[18]	   ; NT_TIB.Self
MOV EAX,DWORD PTR DS:[EAX+30] ; TEB.Peb
MOVZX EAX,BYTE PTR DS:[EAX+2] ; Peb.BeingDebugged
RETN
Соответсвенно можно обратится к этому полю, минуя вызов IsDebuggerPresent. Думаю вы поняли, что патчить нужно не функцию, а эту переменную (BeingDebugged) в PEB структуре, чем и занимаются некоторые плагины к OllyDbg. Но не будем спешить, посмотрим что ещё нам уготовил протектор. Реверсим дальше, идём по F8.

Код:
004FBEDE  |. 83BD A61E0000 >CMP DWORD PTR SS:[EBP+1EA6],0
004FBEE5  |. 74 27          JE SHORT CrackMe2.004FBF0E
004FBEE7  |. 8D85 B61E0000  LEA EAX,DWORD PTR SS:[EBP+1EB6]
004FBEED  |. 50             PUSH EAX
004FBEEE  |. 6A FF          PUSH -1
004FBEF0  |. FF95 A61E0000  CALL DWORD PTR SS:[EBP+1EA6]             ;  kernel32.CheckRemoteDebuggerPresent
Так, так... CheckRemoteDebuggerPresent, ещё одна функция проверки на наличие отладчика. Эта функция возвращает значение в некоторый буфер, у нас это EBP+1EB6. Заглянув в эту API вы поймёте, что это обёртка вокруг ZwQueryInformationProcess. ZwQueryInformationProcess проверяет отладочный порт, и если он "открыт", то нас отлаживают. В принципе можно патчить, но пока не будем торопиться =).

И как оказывается не зря. Следующий код проверяет целостность функции, а точнее пропатченность.

Код:
004FBEF6  |. 8B85 A61E0000  MOV EAX,DWORD PTR SS:[EBP+1EA6]          ;  kernel32.CheckRemoteDebuggerPresent
004FBEFC  |. 8138 8B442408  CMP DWORD PTR DS:[EAX],824448B
004FBF02  |. 75 0A          JNZ SHORT CrackMe2.004FBF0E
004FBF04  |. C785 B61E0000 >MOV DWORD PTR SS:[EBP+1EB6],1
Если функция пропатчена, то в EBP+1EB6 1. От куда они взяли 824448B? Всё просто! Небезызвестный плагин Olly Advanced, так патчит эту функцию. Плэтому мы не будем использовать подобные плагины. Как вы поняли нам нужно скрыться от ZwQueryInformationProcess => и от CheckRemoteDebuggerPresent.

Идём дальше...

Код:
004FBF0E  |> 64:A1 30000000 MOV EAX,DWORD PTR FS:[30]
004FBF14  |. 83C0 68        ADD EAX,68
004FBF17  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]
004FBF19  |. 83F8 70        CMP EAX,70
004FBF1C  |. 75 0A          JNZ SHORT CrackMe2.004FBF28
004FBF1E  |. C785 B21E0000 >MOV DWORD PTR SS:[EBP+1EB2],1
Опять Peb! Что на этот раз? А на это раз вот что:

/*68*/ DWORD NtGlobalFlag

Проверяет на равенство 70, если 70, то в EBP+1EB2 единицу.

Идём дальше...
Опять peb =((((. Надоело =\.
Дальше...

Код:
004FBF44  |> BE 09000000    MOV ESI,9
004FBF49  |. 8DBD 4E1F0000  LEA EDI,DWORD PTR SS:[EBP+1F4E]
004FBF4F  |> 6A 00          /PUSH 0
004FBF51  |. 68 80000000    |PUSH 80
004FBF56  |. 6A 03          |PUSH 3
004FBF58  |. 6A 00          |PUSH 0
004FBF5A  |. 6A 01          |PUSH 1
004FBF5C  |. 68 00000080    |PUSH 80000000
004FBF61  |. 57             |PUSH EDI
004FBF62  |. FF95 AE1E0000  |CALL DWORD PTR SS:[EBP+1EAE]
004FBF68  |. 83F8 FF        |CMP EAX,-1
004FBF6B  |. 74 0A          |JE SHORT CrackMe2.004FBF77
004FBF6D  |. C785 B21E0000 >|MOV DWORD PTR SS:[EBP+1EB2],1
004FBF77  |> 47             |INC EDI
004FBF78  |. 803F 00        |CMP BYTE PTR DS:[EDI],0
004FBF7B  |.^75 FA          |JNZ SHORT CrackMe2.004FBF77
004FBF7D  |. 47             |INC EDI
004FBF7E  |. 4E             |DEC ESI
004FBF7F  |.^75 CE          \JNZ SHORT CrackMe2.004FBF4F
Защищаемся от SoftICE. И всё =))).

Делаем выводы... Нам понадобятся:

Phant0m
[+] hide from PEB (PEB BeingDebugged, PEB NtGlobalFlag)

Olly Advanced
[+] ZwQueryInformationProcess
[+] IsDebuggerPresent

Не ставьте лишнее (помните что происходит с CheckRemoteDebuggerPresent). Удаляем поставленные бряки. И запускаем по F9. Всё гуд +))). Прога запустилась.

[oep]

Фууууууухх, с антиотладкой разобрались. Итак, как мы заметили вначале, регистры сохраняются с помощью pusha. И будут храниться в стеке, пока прот не захочет их восстановить. А когда он захочет их восстановить? Когда будет переходить на OEP!



Ещё разок F8, и регистры запушены. Ставим бряк "hr esp". Пробуем - F9. Мы тут

Код:
004FA85B   . 61             POPAD
004FA85C   .-E9 5B49F7FF    JMP CrackMe2.0046F1BC
Снимаем бряк и прыгаем. Delphi!
Код:
0046F1BC   55               PUSH EBP
0046F1BD   8BEC             MOV EBP,ESP
0046F1BF   83C4 F0          ADD ESP,-10
0046F1C2   B8 54EF4600      MOV EAX,CrackMe2.0046EF54
0046F1C7   E8 EC6AF9FF      CALL CrackMe2.00405CB8
0046F1CC   A1 B0584700      MOV EAX,DWORD PTR DS:[4758B0]
0046F1D1   8B00             MOV EAX,DWORD PTR DS:[EAX]
0046F1D3   E8 F033FEFF      CALL CrackMe2.004525C8
0046F1D8   8B0D D4594700    MOV ECX,DWORD PTR DS:[4759D4]            ; CrackMe2.00476F98
0046F1DE   A1 B0584700      MOV EAX,DWORD PTR DS:[4758B0]
0046F1E3   8B00             MOV EAX,DWORD PTR DS:[EAX]
0046F1E5   8B15 9CB44600    MOV EDX,DWORD PTR DS:[46B49C]            ; CrackMe2.0046B4E8
0046F1EB   E8 F033FEFF      CALL CrackMe2.004525E0
0046F1F0   A1 B0584700      MOV EAX,DWORD PTR DS:[4758B0]
0046F1F5   8B00             MOV EAX,DWORD PTR DS:[EAX]
0046F1F7   E8 6434FEFF      CALL CrackMe2.00452660
0046F1FC   E8 B34BF9FF      CALL CrackMe2.00403DB4
0046F201   8D40 00          LEA EAX,DWORD PTR DS:[EAX]
0046F204   0000             ADD BYTE PTR DS:[EAX],AL
Вот и OEP!

[IAT]

Проскролируем вверх. Что то API невидать =\. Ctrl-G > GetModuleHandleA. Ставим бряк на выход из функции.



F8 и мы тут

Код:
00405CC2   6A 00            PUSH 0
00405CC4   E8 2BFFFFFF      CALL CrackMe2.00405BF4
00405CC9   A3 64664700      MOV DWORD PTR DS:[476664],EAX            ; CrackMe2.00400000
00405BF4, чтож пройдёмся по этому адресу! А вот и переходники



Пройдёмся по этому переходу

Код:
003C0386   93               XCHG EAX,EBX
003C0387   68 E9BD3C47      PUSH 473CBDE9
003C038C   812C24 C1D62949  SUB DWORD PTR SS:[ESP],4929D6C1
003C0393   93               XCHG EAX,EBX
003C0394   813424 89519282  XOR DWORD PTR SS:[ESP],82925189
003C039B   C3               RETN
Здесь формируется адрес API. Получается, что протектор разлагает адрес API на некоторые части, которые вследствии собираются, и выполняется переход. Адрес полученной функции забивается в таблицу. Нам известен элемент 0048A20C.

Перезапускаемся и ставим бряк на 0048A20C (hr 0048A20C).



Мдяя... Думаю пора пересесть на IDA Pro. Реверсим, кментим и в итоге
Код:
_cUB)9o]:004FA7BE                 call    dword ptr [ebp+0AF5h] ; call kernel32.GetProcAddress
_cUB)9o]:004FA7C4                 test    eax, eax        ; проверяем полученный адрес на валидность
_cUB)9o]:004FA7C6                 jz      loc_4FB1BE
_cUB)9o]:004FA7CC                 call    calc_to_new_proc_addr ;
_cUB)9o]:004FA7CC                                         ; функция строит кусок кода, который
_cUB)9o]:004FA7CC                                         ; будет считать смещение до API и
_cUB)9o]:004FA7CC                                         ; передовать управление на эту API
_cUB)9o]:004FA7D1                 mov     dword ptr [ebp+1B09h], 0
_cUB)9o]:004FA7DB                 mov     [edi], eax      ; заносим в таблицу импорта
Делаем вывод, что протектор сначала получает настоящий адрес API с помощью GetProcAddress. Затем с помощью функции, которую я обозвал calc_to_new_proc_addr, создаёт функцию переходник и заносит адрес этой функции в таблицу ипорта.

Ответ напрашивается сам собой. Если пропатчить функцию calc_to_new_proc_addr, тоесть вначале поставить ret, то в [edi] будет заноситься результат GetProcAddress, тоесть настоящий адрес.

Запомним адрес этой функции
Код:
004FBD9E     60             PUSHAD
004FBD9F   . 83BD 5A200000 >CMP DWORD PTR SS:[EBP+205A],0
004FBDA6   . 75 48          JNZ SHORT CrackMe2.004FBDF0
004FBDA8   . 60             PUSHAD
004FBDA9   . 8D9D 451B0000  LEA EBX,DWORD PTR SS:[EBP+1B45]
004FBDAF   . 53             PUSH EBX
004FBDB0   . FF95 050B0000  CALL DWORD PTR SS:[EBP+B05]
Удаляем бряк с 0048A20C. Савим бряк (hardware) на 004FA85B. Теперь путешествуем к 004FBD9E ( спомощью Ctrl-G ). Патчим начало, теперь оно

Код:
004FBD9E     C3             RETN
004FBD9F   . 83BD 5A200000 >CMP DWORD PTR SS:[EBP+205A],0
004FBDA6   . 75 48          JNZ SHORT CrackMe2.004FBDF0
Запускаем, F9! Переходим на oep, скроллируем вверх.

Код:
0040124A   8BC0             MOV EAX,EAX
0040124C  -FF25 A0A14800    JMP DWORD PTR DS:[48A1A0]                ; kernel32.GetCommandLineA
00401252   8BC0             MOV EAX,EAX
00401254  -FF25 9CA14800    JMP DWORD PTR DS:[48A19C]                ; kernel32.GetLocaleInfoA
0040125A   8BC0             MOV EAX,EAX
0040125C  -FF25 98A14800    JMP DWORD PTR DS:[48A198]                ; kernel32.GetModuleFileNameA
00401262   8BC0             MOV EAX,EAX
00401264  -FF25 94A14800    JMP DWORD PTR DS:[48A194]                ; kernel32.GetModuleHandleA
0040126A   8BC0             MOV EAX,EAX
0040126C  -FF25 90A14800    JMP DWORD PTR DS:[48A190]                ; kernel32.GetProcAddress
00401272   8BC0             MOV EAX,EAX
00401274  -FF25 8CA14800    JMP DWORD PTR DS:[48A18C]                ; kernel32.GetStartupInfoA
0040127A   8BC0             MOV EAX,EAX
0040127C  -FF25 88A14800    JMP DWORD PTR DS:[48A188]                ; kernel32.GetThreadLocale
00401282   8BC0             MOV EAX,EAX
00401284  -FF25 84A14800    JMP DWORD PTR DS:[48A184]                ; kernel32.LoadLibraryExA
0040128A   8BC0             MOV EAX,EAX
0040128C  -FF25 D0A14800    JMP DWORD PTR DS:[48A1D0]                ; user32.LoadStringA
Красота... Дампим, пока мы на oep.



Никаких Rebuild'ов Import! Жмём Dump. Отлично! Всё сдампилось =)).

Теперь собственно восстановление. Запускаем ImpREC, открываем наш процесс, вводим oep, IAT AutoSearch, GetIports. Функции найденны, это радует.
Теперь фиксируем наш дамп. ImpREC говорит всё прошло отлично.
Момент истины! Запускаем! Оба ошибка инициализации данных 0xc000007b!
Тут что то не так с PE-заголовком. Нужно восстановить. Для этого нам понадобится LordPE. В нём есть одна очень полезная фитча - Rebuild PE. Как можно понять из названия она восстановит наш PE.



Готово! Попробуем запустить теперь! Уряяяя!! Заработало.
Вот с этим у меня возникли главные проблемы, пока не вспомнил про эту фитчу.

[library]
www.cracklab.ru
www.wasm.ru
www.tuts4you.com
http://guru-exe.ripgames.org/

[heppy end]
Вроде всё! Что ещё сказать? До новых встреч! =)))
 
Ответить с цитированием

  #2  
Старый 18.03.2007, 00:28
Аватар для zl0y
zl0y
Banned
Регистрация: 13.09.2006
Сообщений: 523
Провел на форуме:
2869410

Репутация: 925


Отправить сообщение для zl0y с помощью ICQ
По умолчанию

Хорошая стотья вот Ap0x и обасрался зы + как всегда ))
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распаковка PESpin 0.7 taha Авторские статьи 1 11.12.2006 01:10
Распаковка Upx'ов для новичков KindEcstasy Авторские статьи 0 29.11.2006 22:45
Распаковка. Общий подход. taha Авторские статьи 0 22.11.2006 14:48
Ручная распаковка и взлом HP-crackme ProTeuS Авторские статьи 2 14.08.2006 16:23



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ