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 Сохраняем изменения, запускаем крякми, вводим пасс – все работает!
Еще раз, напоминаю, что данная статья предназначена для новичков, которые вообще с этим не сталкивались. Думаю, полезно иногда объяснять такие вещи на простых примерах.