Статьи InLine Patching файлов запакованных PE-Compact (PE-Compact v2.66)

Discussion in 'Статьи' started by buzulukland, 26 Sep 2008.

  1. buzulukland

    buzulukland Elder - Старейшина

    Joined:
    24 Jan 2008
    Messages:
    40
    Likes Received:
    4
    Reputations:
    0
    InLine Patching файлов запакованных PE-Compact (PE-Compact v2.66)​


    minderbinder


    Следую примеру taha и помятуя о том, статей по InLine Patching'у мало (по крайней мере в ру зоне), предлагаю перевод статьи посвященнной этому.


    Прежде всего, подчеркну, что данная статья ориентирована для новичков (коим и я являюсь), и возможно она прибавит не только знания, но и опыта в данной сфере. Кроме того, убедительная просьба ногами не бить - это мой первый перевод.

    Сама статья

    Подопытный крякми

    Начнем. Крякми приложенный к данной статье был запакован PE-Compact v2.66
    Обрисую задачу:
    1. Найти предположительное (а лучше точное) месторасположения OEP или jmp на него
    2. ищем место патча (самое легкое)
    3. найти «ненужные строки кода». Т.е. те изменение которых, никак не скажется на работоспособности нашего крякми (и самое главное они должны располагаться недалеко от OEP) и после распаковки программы аккуратно внести изменения в ее код, для нужного нам результата.

    ПУНКТ 1. Существует по крайней мере 2 способа нахождения OEP у данного пакера: простой и сложный. Начнем со сложного
    При первой загрузки файла в отладчик видим это:
    00401000 > $ B8 2C5A4000 MOV EAX,dhx_cme_.00405A2C
    00401005 . 50 PUSH EAX
    00401006 . 64:FF35 000000>PUSH DWORD PTR FS:[0]
    0040100D . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
    00401014 . 33C0 XOR EAX,EAX
    00401016 . 8908 MOV DWORD PTR DS:[EAX],ECX
    00401018 . 50 PUSH EAX
    00401019 . 45 INC EBP
    0040101A . 43 INC EBX
    0040101B . 6F OUTS DX,DWORD PTR ES:[EDI] ; I/O command
    0040101C . 6D INS DWORD PTR ES:[EDI],DX ; I/O command
    0040101D . 70 61 JO SHORT dhx_cme_.00401080
    0040101F . 637432 00 ARPL WORD PTR DS:[EDX+ESI],SI
    00401023 . 55 PUSH EBP
    00401024 . 50 PUSH EAX
    00401025 . 6D INS DWORD PTR ES:[EDI],DX ; I/O command
    00401026 . 55 PUSH EBP
    00401027 . 8BEC MOV EBP,ESP
    00401029 . 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],62000111
    00401030 . C1B2 0F85DA00 >SAL DWORD PTR DS:[EDX+DA850F],8B ; Shift constant out of range 1..31
    00401037 . 45 INC EBP
    00401038 . 1083 01E8C02C ADC BYTE PTR DS:[EBX+2CC0E801],AL
    0040103E . 7D 14 JGE SHORT dhx_cme_.00401054


    Обратим внимание, на данный блок
    00401014 . 33C0 XOR EAX,EAX
    00401016 . 8908 MOV DWORD PTR DS:[EAX],ECX


    В данном случае eax зануляется, таким образом выскакивает исключение (access violation), которое фактически и является ключом к OEP.

    Используя трассировку (F8) дойдем до следующих инструкций, которые очевидно являются началом нашего обработчика исключений.
    77F5109C 8B1C24 MOV EBX,DWORD PTR SS:[ESP]
    77F5109F 51 PUSH ECX
    77F510A0 53 PUSH EBX
    77F510A1 E8 BD060100 CALL ntdll.77F61763
    77F510A6 0AC0 OR AL,AL
    77F510A8 74 0C JE SHORT ntdll.77F510B6
    77F510AA 5B POP EBX
    77F510AB 59 POP ECX
    77F510AC 6A 00 PUSH 0
    77F510AE 51 PUSH ECX
    77F510AF E8 FFD40200 CALL ntdll.ZwContinue


    Наша задача на данном участке заключается в следующем, при дальнейшей трассировке дойти до функции ntdll.ZwContinue, которая располагается по адресу 77F510AF.
    Зайдем в эту функцию, и вот что мы увидим:
    77F7E5B3 > B8 20000000 MOV EAX,20
    77F7E5B8 BA 0003FE7F MOV EDX,7FFE0300
    77F7E5BD FFD2 CALL EDX
    77F7E5BF C2 0800 RETN 8


    Далее, что очень важно, дойдя до вызова
    77F7E5BD FFD2 CALL EDX
    зайдем в него:
    7FFE0300 8BD4 MOV EDX,ESP
    7FFE0302 0F34 SYSENTER
    7FFE0304 C3 RETN

    Не углубляясь в вызов функции 7FFE0302 0F34 SYSENTER опустимся ниже и окажемся там, где нам нужно.
    00405A4F B8 23480700 MOV EAX,74823


    Далее у нас есть 2 пути: либо осуществить поиск команды 'jmp eax' используя (control+F),либо просто поскролить вниз и найти ее же (теоретически она окажется в конце кода). Это и есть наш искомый jump на OEP. Устанавливаем на него брейкпоинт.
    00405AEE -FFE0 JMP EAX ; dhx_cme_.<ModuleEntryPoint>

    Это был сложный способ. Рассмотрим способ попроще (простой способ)
    Находясь в Olly нажимаем alt+m и смотрим в память, далее выбираем .rsrc секцию нашего запакованного файла, нажимаем ctrl+b для поиска по байтам, и вводим бинарный код, который представляет собой инструкции, распаложенные в непосредственной близости от джампа на наш OEP, а именно
    00405AE8 5A POP EDX
    00405AE9 5E POP ESI
    00405AEA 5F POP EDI
    00405AEB 59 POP ECX
    00405AEC 5B POP EBX
    00405AED 5D POP EBP
    00405AEE FFE0 JMP EAX


    (5A 5E 5F 59 5B 5D FF E0 и есть те самый байты которые мы ищем)
    Именно эти байты мы и записываем в строку поиска. Пару секунд спустя, мы стоим точно около искомого джампа.
    Далее анализируем код (ctrl+a) и начинаем искать то смещение которое необходимо пропатчить. В данном случае не составляет особого труда выяснить, за проверку введенной строки отвечает функция strcmpA. После которой идет тот самый адрес который необходимо пропатчить.
    004010FA |. 75 26 JNZ SHORT dhx_cme_.00401122

    Записываем этот адрес и перезагружаем крякми.
    ПУНКТ 2. Запускаем программу и не забываем перед этим поставить брейкпоинт на jmp ведущий к OEP
    004010FA |. /75 26 JNZ SHORT 00401122 ; dhx_cme_.00401122
    Очевидно, что данную строку надо заменить на
    004010FA |. /74 26 JE SHORT 00401122 ; dhx_cme_.00401122
    Пришло время патчить.
    ПУНКТ 3. Ищем те строки изменение которых не скажутся на работоспособности нашего крякми.
    Первым кандидатом, идеально подходит строка
    00405ACC 8985 CD123900 MOV DWORD PTR SS:[EBP+3912CD],EAX

    Забиваем ее нопами, для того чтобы разместить следующую строку
    00405AEE C605 FA104000 7>MOV BYTE PTR DS:[4010FA],74
    Видим что данная строка немного не лезет, и при попытке записать ее туда, она успешно забивает строку
    00405AD2 8BF0 MOV ESI,EAX
    Кроме того, обратим внимание на строку идущую сразу за ней (скажу сразу, она тоже оказалась не особо важной)
    00405AD4 8B4B 14 MOV ECX,DWORD PTR DS:[EBX+14]

    Ее также нопим. Ну вот практически и все. Конечные действия
    Вставляем в наш первый получивший ноп строку
    MOV BYTE PTR DS:[4010FA],74
    Она забивает строку
    MOV ESI,EAX
    Второй строчкой вставляем, именно ту самую забитую команду
    MOV ESI,EAX
    Конечный вид будет таким
    00405ACC C605 FA104000 7>MOV BYTE PTR DS:[4010FA],74
    00405AD3 8BF0 MOV ESI,EAX
    00405AD5 90 NOP
    00405AD6 90 NOP
    00405AD7 5A POP EDX
    00405AD8 EB 0C JMP SHORT 00405AE6 ; dhx_cme_.00405AE6

    Сохраняем изменения, запускаем крякми, вводим пасс – все работает!
     
    #1 buzulukland, 26 Sep 2008
    Last edited: 26 Sep 2008
  2. void //tPORt

    void //tPORt New Member

    Joined:
    19 Feb 2008
    Messages:
    3
    Likes Received:
    1
    Reputations:
    0
    Вы еще про инлайн упикса нопешите =\\\
    С более поздними версиями пе компакта не прокатит.
     
  3. buzulukland

    buzulukland Elder - Старейшина

    Joined:
    24 Jan 2008
    Messages:
    40
    Likes Received:
    4
    Reputations:
    0
    Еще раз, напоминаю, что данная статья предназначена для новичков, которые вообще с этим не сталкивались. Думаю, полезно иногда объяснять такие вещи на простых примерах.