Патчинг EXECryptor 2.x

Mail2k

(L2) cache
Пользователь
Регистрация
24.05.2006
Сообщения
379
Реакции
8
Хотел в начале в халяву выложить,т.к. по запросу в поисковой системе эта статья нигде не высветилась и посчитал,что,наверное,редкая.Но выложил для всех.Начинающим крякерам будет полезной.
Код:
                                           Патчинг EXECryptor 2.x 

Автор: sanniassin

                          Жертва: execrypt.exe из дистрибутива EXECryptor 2.1.21.

Инструменты (к-рые использовал я): SoftICE 4.32+IceExt 0.66 (олли не катит, потому что EXECryptor её очень не любит), WinHex 12.05 SR9, IDA 4.8.0.847

Попробуем изменить что-нибудь в коде жертвы (например, первый байт на EP (всё-равно он не выполняется)). Получим “File corrupted!”, значит execryptor проверяет CRC файла (кто бы сомневался :)). Посмотрим, как именно он его проверяет. bpx MapViewOfFile ничего интересного не дал, а вот если брякнуться на ReadFile и посмотреть в его (ReadFile) буфер после выхода из ReadFile, то видно, что читаются именно части execrypt.exe :) 

Однако при выходе из ReadFile мы попадём не в код протектора, а в функцию _lread, которую использует EXECryptor для чтения защищённого файла. Попробуем поискать в памяти зацикленной проги (например: bpx _lread, !suspend) адрес _lread (у меня это 7С839418). Запускаем WinHex, открываем в нем процесс execrypt->execrypt.exe (Alt+F9) и ищем (Ctrl+Alt+F) адрес _lread (т.е. у меня 7С839418 (пишем в окне поиска ессно в обратном порядке, т.е. 1894837C)). Должно найтись по адресу 7172F4. Нам нужно поменять этот адрес на что-то своё, чтобы можно было корректировать прочитанную часть файла. 

Поставим “bpm 7172F4 w” и посмотрим, где по этому адресу будет писаться адрес _lread. Видно, что запись происходит по адресу 7608B7, однако, при запуске проги по этому адресу ничего нет, поэтому будем патчить нешифрованный код протектора в момент, когда код проверки CRC будет расшифрован, но, попытавшись пропатчить код сразу после rep movs, выяснилось, что EXECryptor до проверки CRC файла проверяет ещё и память (не всю и, возможно, не всегда, но для удобства (потому что процедура проверки памяти (сигнатура: 
“565189C689D183E904FCACD0E880F874750E8B060FC801C8890683C60483E904497FE7595EC3”) не извращается EXECryptor-ом и находится сразу после TlsCallbacks, поэтому её легко найти) лучше использовать этот метод), поэтому будем патчить процедуру проверки памяти (её начало - 783118 ) (сама эта процедура почему то не проверяется :)) 


Поставим вместо “jg 783122” jmp 400078 (команды с jg 783122 по ret занимают как-раз 5 байт), т.к. EXECryptor не проверяет CRC до “PE header-20h байт”. По адресу 400078 восстановим команду “jg 783122”, а после неё

HEADER:0040007E                 cmp esi,78299C | 78299C взято из esi при последнем
                                                                             | срабатывании бряка на 78313B (сразу после
                                                                             | jg) в оригинальном exe
HEADER:00400084                 jnz     short loc_400097
HEADER:00400086                 mov     dword ptr ds:7608B8h, 0FFC9F7DEh | вместо записи
HEADER:00400090                 mov     byte ptr ds:7608B7h, 0E8h                  | _lread, поставим
                                                                                                                           | переход на наш
                                                                                                                           | код
HEADER:00400097
HEADER:00400097 loc_400097:                            ; CODE XREF: HEADER:00400084j
HEADER:00400097                 pop     ecx | восстанавливаем
HEADER:00400098                 pop     esi  | затертые
HEADER:00400099                 retn           | команды

По адресу 7608B7 теперь стоит “call 40009A”, а по адресу 40009A напишем такой код

HEADER:0040009A                mov     ds:478FFCh, eax                           | сохраним адрес _lread

HEADER:0040009F                 mov     dword ptr ds:7172F4h, 4000AAh | вместо _lread
                                                                                                                     | сделаем переход на
                                                                                                                     | наш код
HEADER:004000A9                 retn

Вместо _lread мы будем попадать на адрес 4000AA

HEADER:004000AA                 push    dword ptr [esp+0Ch] | восстанавливаем параметры для
HEADER:004000AE                 push    dword ptr [esp+0Ch] | _lread 
HEADER:004000B2                 push    dword ptr [esp+0Ch] |

HEADER:004000B6                 call    dword ptr ds:478FFCh | и вызываем его

Теперь нужно поймать момент, когда будет читаться измененная нами часть файла (там, где мы поставили jmp 400078). Я сделал так

HEADER:004000BC                 push    eax
HEADER:004000BD                 mov     eax, [esp-4] | пишем в eax адрес буфера для чтения

HEADER:004000C1                 cmp     dword ptr [eax+34h], 32D7B98Bh | проверяем, нужная
                                                                                                                       | ли нам часть прочитана

HEADER:004000C8                 jnz     short loc_4000F6
HEADER:004000CA                 mov     dword ptr [eax+0D69h], 5E59E77Fh | восстанавливаем
HEADER:004000D4                 mov     byte ptr [eax+0D6Dh], 0C3h              | измененный код

HEADER:004000DB                 mov     eax, ds:478FFCh | восстанавливаем переход 
HEADER:004000E0                 mov     ds:7172F4h, eax   | на _lread

HEADER:004000E5                 mov     byte ptr ds:45E674h, 0C3h | делаем с прогой что хотим

А теперь обратим вниманию на фичу “Patch protection”, к-рая должна помешать всяким лоадерам и инлайнам :) Вот только обходится она легко. Поставим bpm 45E674 и когда брякнемся по адресу 74AFBE, то немного потрейсим (F8 - step into) до адреса 77B2F6. 

Как видно это какой-то цикл (правда при трейсе встречается ещё и js, но я сначала воспринял его, как мусорный джамп и слава богу, а то начал бы копать не туда :)). Поставим бряк на 77B2FC и отпустим прогу. Когда брякнемся, опять также потрейсим до адреса 716320. Это опять какой-то цикл, поставим бряк на выход из него (т.е. на 716326). 

Опять потрейсив заметим, что по адресу 74E1A6 происходит сравнение, похожее на сравнение CRC (используются те же переменные). Если заменить jz на jmp, то никакой “Patch protection” нам не страшен :)

HEADER:004000EC                 mov     word ptr ds:74E1A9h, 0E990h | пресекаем “Patch
                                                                                                                 | protection”

HEADER:004000F5                 nop | nop лишний, просто лень было убрать :)
HEADER:004000F6 loc_4000F6:                            ; CODE XREF: HEADER:004000C8j
HEADER:004000F6                 pop     eax
HEADER:004000F7                 retn

На этом первая часть закончена.
 
Это статья по обходу crc защиты протектора execryptor который ущу туеву хучу бабла стоит ? сойдет но лучше найди что нибудь посущественне типа снять protect защиту по ключам :lol:
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх