Вообще то я здесь описываю все очень детально, так как эта статья
писалась для новичков в этом деле, так что экспертов и
крэкtров средней квалификации попрошу откланяться - не советую читать им
дальше, дабы им не стало плохо от столь подробного изложения материала
(и не надо меня за это критиковать). Ладно, ближе к делу/телу (кому
как больше нравится). 

Приобрел я недавно относительно новый гамес от 7 волка - Unreal II:
The Awakening. Как игра она оставила не очень хорошие впечатления,
поэтому почти сразу возникло желание в ней
что-то улучшить 🙂

Инструменты: 

  • SoftIce 
  • Ida / Wdasm 
  • Hex редактор (юзайте какой больше нравится, я юзаю Hiew) 
  • Pe tools 
  • Совсем немного мозгов (грамм 20) 

Игра выдает сообщение, в котором просит вставить “оригинальный” диск
от 7 wolf. В данной статье я рассмотрю два способа обхода защиты, но попробовать
советую оба. 

Способ первый 

Расскажу я сначала про то, как снять защиту DDem исполняемого файла
игры (Unreal2.exe). Ставим бряк в айсе на GetDriveTypeА, запускаем Unreal2.exe… и в айсе,
жмем F11 и трейсим пока не наткнемся на вот такой код: 

10945075 CALL [EBX+0C] ;GetDriveTypeA 
10945078 CMP EAX,05 
1094507B JZ 1094507F ;JZ -> JNZ 

Поменяйте JZ на JNZ (для правки памяти
используйте команду: e 1094507B). Трейсим дальше… 

1094509D CALL [EBX+14] ;GetVolumeInforamtionA 
109450AD TEST EAX,EAX 
109450A2 JZ 1094505C ;JZ -> JNZ 

Опять меняем JZ на JNZ. Продолжаем трейсить… 

109450B4 JZ 1094505C ;JZ -> JNZ 
JZ -> JNZ, трейсим… 
109450D6 CALL [EBX+04] ;CreateFileA 
109450D9 CMP EAX,-01 
109450DC JZ 1094505C ;JZ -> JNZ 

Примечание: здесь JZ занимает шесть байт менять надо второй байт:
0F84XXXXXXXX -> OF85XXXXXXXX. 

Трейсим… 

109450E6 CALL [EBX+10] ;GetFileSize 
109450E9 MOV EDI,EAX 
109450EB CALL [EBX] ;CloseHandle 
109450ED MOV EAX,EDI 
109450EF CMP EAX,[EBX+00000270] 
109450F5 JNZ 1094505C ;JNZ -> JZ 

Все также как и в прошлый раз, только
наоборот: JNZ -> JZ (0F85XXXXXXXX -> OF84XXXXXXXX). Трейсим пару десяток строк и… 

10945192 JNZ 109412C 
10945194 ADD ESP,08 
10945197 MOV EAX,[EBX+7C] ;
долгожданный OEP равный 10913BC1 
1094519A POP ESI 
1094519B POP ECX 
1094519C POP EBX 
1094519D JMP EAX ;
джамп на OEP 

Первый условный переход (JNZ 109412C) повторяется N количество раз,
поэтому ставим бряк на адрес следующей за ним команды (на ADD ESP,08).
Записываем OEP на бумажку, трейсим до команды JMP
EAX (выполняем все команды кроме JMP EAX) и вводим в айсе следующие строки: 

a eip 
jmp eip 
<enter> 

Это нужно для зацикливания программы (точнее потока процесса). Советую
сразу после этого установить приоритет процесса (в смысле всех потоков
процесса) Unreal2 в значение Low, через Task Manager. Далее в PE Tools
снимаем полный дамп Unreal2.exe. Теперь можно завершить зацикленный
поток путем завершения процесса. Далее делаем Rebuild PE.
Теперь надо поправить точку входу. А вот формула для ее вычисления: 

EP=OEP-ImageBase=10913BC1h-10900000h=13BC1h. 

Итак, поменяли EP. Да, чуть не забыл, секцию .DDeMCod можно убрать - она
нам больше не нужна и после этого снова сделайте Rebuild PE. Также
название секции .DDeMImp можно поменять на стандартное
.idata, которая содержит таблицу импорта.  

Второй способ. 

Теперь второй способ - снятие защиты патчингом непосредственно в
файле. 

Вот как выглядит код расшифровки файла: 

.DDeMCod:10945000 push ebx 
.DDeMCod:10945001 push ecx 
.DDeMCod:10945002 push esi 
.DDeMCod:10945003 call $+5 
.DDeMCod:10945008 pop ebx 
;ebx=10945008h 
.DDeMCod:10945009 sub ebx, 1008h 
.DDeMCod:1094500F lea esi, [ebx+1034h] 
.DDeMCod:10945015 mov ecx, 3F3h 
.DDeMCod:1094501A mov edx, 0EE2A1763h 
.DDeMCod:1094501F 
.DDeMCod:1094501F loc_1094501F: ; CODE XREF: 
.DDeMCod:10945031 
.DDeMCod:1094501F xor [esi], edx 
.DDeMCod:10945021 add esi, 4 
.DDeMCod:10945024 
.DDeMCod:10945024 loc_10945024: ; CODE XREF: 
.DDeMCod:1094503E 
.DDeMCod:10945024 imul edx, 3E276897h 
.DDeMCod:1094502A xor edx, 17234893h 
.DDeMCod:10945030 dec ecx ;ecx=ecx-1 
.DDeMCod:10945031 jnz short loc_1094501F ;jump if 
ecx<>0 

Сначала идет сохранение регистров для дальнейшего их восстановления из
стека, так как именно они используются в ходе расшифровывания. Затем
команда call передает управление следующей за ней команде, которая
извлекает из стека адрес возврата (10945008h), являющийся абсолютным
адресом этой самой команды (pop ebx). Затем от полученного абсолютного
адреса (10945008h) отнимается 1008h (получается 10944000h) и
прибавляется 1034h (получается 10945034h), а затем указатель на данные
по адресу 10945034h загружается в регистр esi для дальнейших
манипуляций с ними. 

В ecx загружается количество циклов кода расшифровки
(всего изменяется ecx*4=3F3h*4=FCCh байт), а в edx первичный ключ с помощью которого
будет происходить расшифровка. Далее цикл расшифровки: ксоринг по
адресу, находящемуся в esi, ключом, значение которого находится в edx.
Затем происходит увеличение значения указателя на
DWORD (т.e. 4), находящегося в регистре esi, для дальнейшей расшифровки. Далее
генерируется следующий ключ в регистр edx при помощи умножения
текущего значения ключа на 3E276897h и ксоринга его на 17234893h.
Затем уменьшается значения ecx на 1 и если он равен нулю, то условный
переход не происходит. Но ведь можно провести и обратную операцию -
шифрование. В принципе для этого достаточно передать управление
обратно коду расшифровки – как я и сделал. 

Действуем… 

Ставим бряк на GetDriveTypeA… и в айсе жмем F11. Далее корректируем
все команды условного перехода в памяти (хинт: адреса брать из первого
способа): 

1094507B; 74 -> 75 
109450A2; 74 -> 75 
109450B4; 74 -> 75 
109450DC; 0F84 -> 0F85 
109450F5; 0F85 -> 0F84 

Теперь вводим: 

r eip=10945001 

В результате чего оказываемся на коде
расшифровки. Напомню, что в данном случае этот код будет зашифровывать. Трейсим и на этой команде
ставим бряк: 

10945033: LEA EDX,[EAX] ;ставим бряк 

И жмем F5, затем снимаем с памяти все зашифрованные байты команд
переходов: 

1094507B; D4 
109450A2; FF 
109450B4; 77 
109450DC; 9EB0 
109450F5; D866 

Теперь с помощью Hex редактора заносим измененные байты в исходный
файл Unreal2.exe. Разумеется, зашифрованный участок находится на том
же месте, что и расшифрованный.

Заранее приношу извинения, если что не так 🙂

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии