Как исправлять байты в пакованных файлах: UPX

"If it runs it can be defeated."
+ORC

Инструменты

IDA - я использовал версию, любезно предоставленную мне Гарри Колтоном :)
HIEW - можно использовать любой редактор со встроенным дизассемблером
Мозги - не советую пользоваться пиратскими версиями, лучше купите ;-)

Принцип работы

UPX, как и любой другой паковщик, при запуске программы должен распаковать ее в память и затем передать ей управление. Вот этим мы и воспользуемся - отследим где UPX передает управление собственно программе. Найдя это место мы сначала заставим UPX пропатчить нам несколько байт, а уже потом вернем управление программе.
Я не буду говорить какую программу исследовал я - это не важно, результат будет тот же, только циферки другие.

Начнем...

Отдадим на растерзание IDA нашу программу. В W32dasm ее засовывать нельзя так как он пытается дизассемблировать зашифрованные участки кода. Получается полный бред. IDA дизассеблирует только инструкции распаковщика, зашифрованные участки не трогает. Вот типичный листинг:

;----------- S U B R O U T I N E --------------
0040CE30   public start
0040CE30   start proc near
0040CE30   pusha                      ;Начало распаковки ищем POPA
0040CE31   mov    esi, 40B000h        ;здесь начинаются инструкции,
0040CE36   lea    edi, [esi-0A000h]   ;распаковывающие программу в память.
0040CE3C   push   edi                 ;Если вам интересен принцип работы
0040CE3D   or     ebp, 0FFFFFFFFh     ;- потрассируйте, на это уходит
                                      ;около часа.
0040CE40   jmp    short loc_40CE52
;----пропущено около  несколько десятков строк т.к они нам не нужны----
0040CF67   dword ptr [esi+0C118h]
0040CF6D   or     eax, eax
0040CF6F   jz     short loc_40CF78
0040CF71   mov    [ebx], eax
0040CF73   add    ebx, 4
0040CF76   jmp    short loc_40CF59
0040CF78   ; -------------------------------------
0040CF78   loc_40CF78:                ;CODE XREF: start+13F.j
0040CF78   call   dword ptr [esi+0C11Ch]
0040CF7E   loc_40CF7E:                ;CODE XREF: start+110.j
0040CF7E   popa                       ;вот эта "попа" нам и была нужна :-)
0040CF7F   jmp    near ptr unk_403A68 ;JMP на начало распакованной
                                      ;программы!!!
0040CF7F   start endp

Вот теперь мы знаем все что нам нужно. Посмотрим на нашу программу через HIEW. Две последние инструкции будут выглядеть так:


0000237E: 61             popad
0000237F: E9E46AFFFF     jmp      0FFFF8E68

Теперь нам надо найти пустое место , куда мы впишем наш патч. Примерно пятью инструкциями ниже мы обнаруживаем кучу ноликов (add [eax],al). Подойдет. Перенаправляем JMP:


0000237F: E90F000000      jmp 000002393          ;jmp на свободное место
00002393: C6053234450075  mov b,[000453432],075  ;заменяем байт по адресу
                                                 ;453432 на 75
0000239A: E9E46AFFFF      jmp 0FFFF8E68          ;возвращаем управление
                                                 ;программе

Вот и все.

Все замечания, благодарности, ругательства приветствуются.
Удачи,
Corbio
corbio@mail.ru
Genocide Crew member
uinC Member
[c]uinC