<< Все статьи по взлому Распаковка и взлом программы PECompact v2.78a Обсудить эту статью >>
Автор:Bokiv [AHTeam]
Уровень:Для начинающих
Программа:PECompact v2.78a
Тип защиты:PECompact
Инструменты:OllyDbg 1.10, PE Tools 1.5, Import REConstructor 1.6 final

[ Цель ]
PECompact v2.78a

[ Необходимый инструмент ]
OllyDbg 1.10
PE Tools 1.5
Import REConstructor 1.6 final

[ Введение ]
Просмативая мартовский диск журнала чип, я наткнулся на свежую версию упаковщика PECompact. Так как года два назад, я им активно пользовался для сжатия своих программ, то решил проверить его на устойчивость к взлому. Взломав, зашел на сайт разработчика в поисках новой версии, взломав и её, решил написать этот мануал. На сегодняшний день (март 2006), мы будем обладателями самой свежей и "бесплатной" версии PECompact v2.78a!

[ Описание программы ]
PECompact2 - это утилита, относящаяся к классу так называемых "упаковщиков исполняемых файлов". Такие упаковщики предназначены для сжатия исполняемых файлов и модулей, с целью существенно уменьшить их физический размер. При запуске сжатый модуль (исполняемый файл) распаковывается и в памяти воссоздаётся его исходный вид.

[ Постановка задачи ]
1. Распаковать.
2. Убрать триал период, вместе с нагскрином.
3. Убрать напоминание о "последних днях", вместе с проверкой на размер.

[ Часть первая - Распаковка ]
Распаковка всегда состоит из трёх составляющих:

- Нахождение OEP (Оригинальной точки входа)
- Дамп (Сохранение распакованной проги из памяти)
- Восстановление таблицы импорта (Имена Функций Windows, которые использует программа)

Как не трудно было догадаться, упаковщик нашей жертвы, конечно же он сам (PECompact 2.x)!

[ Нахождение OEP ]
Хочу вас научить своему, очень простому, способу нахождения OEP для всех версий PECompact. Запускаем OllyDbg 1.10 (далее Оля), нажимаем F3, указываем файл pec2gui.exe. Курсор Оли стоит здесь:

00401000 > $ B8 60894300 MOV EAX,pec2gui.00438960

Т.е. по адресу 00401000. Трассируем программу по F8 (т.е. просто отрывисто жмём F8 шесть раз), потом Shift+F8 (один раз) (так как по адресу 00401016 создаётся исключительная ситуация, и по F8 Оля не пустит). И попадаем в системную библиотеку, проходим её другой клавишей (только не путайте Ctrl и Shift) Ctrl+F9 (один раз), и мы у цели, в коде распаковщика!

00438983	B8 E57643F0	MOV EAX,F04376E5		<-Мы тут!
00438988 64:8F05 00000000 POP DWORD PTR FS:[0]

Далее прокрутим мышкой вниз до следующих строк:

00438A18	FF11	CALL DWORD PTR DS:[ECX]
00438A1A 8BC6 MOV EAX,ESI
00438A1C 5A POP EDX
00438A1D 5E POP ESI
00438A1E 5F POP EDI
00438A1F 59 POP ECX
00438A20 5B POP EBX
00438A21 5D POP EBP
00438A22 FFE0 JMP EAX <-Это переход на OEP!!! (Ставим сюда бряк по F2)
00438A24 0000 ADD BYTE PTR DS:[EAX],AL
00438A26 0000 ADD BYTE PTR DS:[EAX],AL
00438A28 0000 ADD BYTE PTR DS:[EAX],AL
00438A2A 0000 ADD BYTE PTR DS:[EAX],AL
00438A2C 0000 ADD BYTE PTR DS:[EAX],AL
00438A2E 0000 ADD BYTE PTR DS:[EAX],AL
00438A30 0000 ADD BYTE PTR DS:[EAX],AL <-Тут не ошибётесь эта команда,
00438A32 0000 ADD BYTE PTR DS:[EAX],AL <-выполняется о-о-очень много раз!

По адресу 00438A22 кликаем мышкой (один раз), и нажимаем F2. Этим действием мы указали Оле, где нужно остановить выполнение программы. Далее Ctrl+F2 (перезапуск программы), и Shift+F9 (пять раз), теперь мы стоим на нашей точке прерывания (она выделена красным), достаточно один раз нажать F8 и мы на OEP, т.е. в нашей распакованной программе!

0041B493	E8 DB E8	<-Это OEP!!!

Запишем адрес точки входа. У нас это: 0041B493.
---
Аналогично для распаковки можно использовать: bp VirtualAlloc. Попали в тело распаковщика, и установили бряк на последний JMP.

[ Дамп ]
Запускаем программу PE Tools, в появившимся окне выбираем наш процесс pec2gui.exe (правой кнопкой мыши) и нажимаем Dump Full.... Сохраняем файл dump.exe рядом с запакованной программой. Закрываем PE Tools.

[ Восстановление импорта ]
Теперь переходим к работе с программой Import REConstructor 1.6 final. В окне (Attach to an Active Process) выбираем нашу многострадальную программу pec2gui.exe. В поле Size вводим найденное нами OEP минус Image Base (значение которой находится чуть выше и равно 00400000), т.е.

0041B493	<-OEP
00400000 <-Image Base
-----------
0001B493 <-Вводим в поле Size

вводим 0001B493. Далее кнопки IAT AutoSearch->Get Imports->Fix Dump, и в появившимся окне указываем файл dump.exe, появится новый файл с именем Dumped_.exe, всё теперь программа полностью рабочая!


[ Часть вторая - Взлом ]
Далее работа пойдёт с распакованной программой (Dumped_.exe). Переведём системное время на месяц вперёд и запустим нашу жертву. Видим: выскочило окошко с предложением обновиться. Закроем его, и вылетает большой нагскрин, типа купите программу. Сейчас пришло время устранить это недоразумение!

Запускаем Олю, открываем в ней наш Dumped_.exe, смотрим адрес на котором стоит Оля, если на 0041B493, то всё в порядке, если на любом другом, то нажимайте (Shift+F9), пока не встанете на этом адресе. Далее Alt+F1, в появившемся окне пишем:

bp GetSystemTimeAsFileTime

и нажимаем Enter. Данным действием мы устанавливаем точку прерывания программы отладчиком, если программа пытается узнать системное время. Далее (Shift+F9), до тех пор пока курсор отладчика не остановиться по адресу: 7C8017E5 в четвёртый раз. Далее Ctrl+F9, потом F8 и видим следующий код:

004100F2	FF15 8CA04200	CALL DWORD PTR DS:[<&kernel32.GetSystemT>;	\GetSystemTimeAsFileTime
004100F8 837C24 10 01 CMP DWORD PTR SS:[ESP+10],1 <- Мы тут
004100FD 74 16 JE SHORT __pec2gu.00410115
004100FF 85FF TEST EDI,EDI
00410101 75 12 JNZ SHORT __pec2gu.00410115
00410103 8B7424 18 MOV ESI,DWORD PTR SS:[ESP+18]
00410107 2B7424 20 SUB ESI,DWORD PTR SS:[ESP+20]
0041010B 8B7C24 1C MOV EDI,DWORD PTR SS:[ESP+1C]
0041010F 1B7C24 24 SBB EDI,DWORD PTR SS:[ESP+24]
00410113 EB 2B JMP SHORT __pec2gu.00410140
00410115 8B5424 08 MOV EDX,DWORD PTR SS:[ESP+8] <- Создаём ключ с новой датой!
00410119 6A 08 PUSH 8 ; /BufSize = 8
0041011B 8D4C24 1C LEA ECX,DWORD PTR SS:[ESP+1C] ; |
0041011F 51 PUSH ECX ; |Buffer
00410120 6A 03 PUSH 3 ; |ValueType = REG_BINARY
00410122 6A 00 PUSH 0 ; |Reserved = 0
00410124 56 PUSH ESI ; |ValueName
00410125 52 PUSH EDX ; |hKey
00410126 FF15 18A04200 CALL DWORD PTR DS:[<&advapi32.RegSetValu ; \RegSetValueExA

В данной процедуре программа пытается прочитать дату первого запуска , и сравнить с сегодняшней датой. Но если, такой ссылки в реестре нет, то она создаёт новую запись с текущей датой! (00410115). А, следовательно триал период становится вечным, а с ним и пропадает нагскрин.

Править будем так:
Ставим курсор на строчку ниже (004100FD), нажимаем пробел и меняем JE SHORT 00410115 на JMP SHORT 00410115, далее кнопка Assemble, и закроем это окошко. Данной операцией мы заменили условный (JE) переход на безусловный (JMP).

Немного теории:

Схема команды: jz или je метка
Назначение: переход, если флаг нуля установлен в единицу или условие равно

- jz (Jump if Zero) – переход если флаг нуля установлен.
- je (Jump if Equal) – переход, если равно.

Команды jz и je одинаковы. Например, дисассемблер может показывать je, а отладчик jz.

Схема команды: jnz или jne метка

Назначение: переход, если флаг нуля не установлен в единицу или условие не равно

- jnz (Jump if not Zero) – переход если флаг нуля не установлен.
- jne (Jump if not Equal) – переход, если не равно.

И опять же команды jnz и jne одинаковы.

Далее вводим:

bc GetSystemTimeAsFileTime <-Удаляем бряк.

И установим на:

bp SetWindowTextA

Далее Shift+F9 (два раза), в общем пока в стёке не появиться:

0012C508	0040D6CC		/CALL to SetWindowTextA from __pec2gu.0040D6CA
0012C50C 003A02B6 |hWnd = 003A02B6 ('Static',class='Static',parent=001A03C6)
0012C510 0012C6B0 \Text = "7 trial days remain"

доходим до ret (Ctrl+F9) и выходим из процедуры (F8).

0040D6AD	E8 D9CB0000	CALL __pec2gu.0041A28B		<- это причина всех бед!
0040D6B2 83C4 0C ADD ESP,0C
0040D6B5 8D8C24 9C01000> LEA ECX,DWORD PTR SS:[ESP+19C]
0040D6BC 51 PUSH ECX
0040D6BD 68 0A040000 PUSH 40A ; /ControlID = 40A (1034.)
0040D6C2 56 PUSH ESI ; |hWnd
0040D6C3 FF15 FCA24200 CALL DWORD PTR DS:[<&user32.GetDlgItem>] ; \GetDlgItem
0040D6C9 50 PUSH EAX
0040D6CA FFD3 CALL EBX
0040D6CC 68 82000000 PUSH 82 ; /RsrcName = 130.
0040D6D1 6A 00 PUSH 0 ; |/pModule = NULL
0040D6D3 FF15 ECA14200 CALL DWORD PTR DS:[<&kernel32.GetModuleH> ; |\GetModuleHandleA
0040D6D9 50 PUSH EAX ; |hInst
0040D6DA FF15 8CA24200 CALL DWORD PTR DS:[<&user32.LoadIconA>] ; \LoadIconA

Ставим на 0040D6AD Hardware BreakPoint On Execution, и перезапускаем прогу. Заходим в 0040D6AD CALL (F7), нажимаем пробел, пишем retn. Всё! В той процедуре прятались: надпись с триальными днями, проверка размера, и прочий мусор. Т.к. других ограничений в программе нет, то взлом почти подошел к своему логическому завершению.

Для того чтобы сохранить взломанный файл - проделайте все изменения за один раз, и:

F10->Copy to executable->All Modifications.

Появится окно с названием «Copy selection to executable file» нажимаем Copy All, появиться новое окно с кодом, в нём F10->Save File. Сохраним как pec2gui_.exe. Программа взломана!

[ Часть третья - Приветы to ]
CrackLab, Bad_Guy, PaniX, Гоге, Sparkling.

P.S. Все материалы публикуются только в учебных целях, и автор за их использование ответственности не несет!
P.P.S. Возможно, имеют место опечатки, заранее извините!

Автор: Bokiv [AHTeam]

<< Все статьи по взлому Обсудить эту статью >>

ALIEN Hack Team - http://ahteam.org
Только для образовательных целей