buzulukland
26.09.2008, 00:18
InLine Patching файлов запакованных PE-Compact (PE-Compact v2.66)
minderbinder
Следую примеру taha и помятуя о том, статей по InLine Patching'у мало (по крайней мере в ру зоне), предлагаю перевод статьи посвященнной этому.
Прежде всего, подчеркну, что данная статья ориентирована для новичков (коим и я являюсь), и возможно она прибавит не только знания, но и опыта в данной сфере. Кроме того, убедительная просьба ногами не бить - это мой первый перевод.
Сама статья (http://vault.reversers.org/TextSearch&phrase=PECompactInlinePatching)
Подопытный крякми (http://vault.reversers.org/PECompactInlinePatching/files.xml&action=download&file=dhx.cme.1.zip)
Начнем. Крякми приложенный к данной статье был запакован 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
Сохраняем изменения, запускаем крякми, вводим пасс – все работает!
minderbinder
Следую примеру taha и помятуя о том, статей по InLine Patching'у мало (по крайней мере в ру зоне), предлагаю перевод статьи посвященнной этому.
Прежде всего, подчеркну, что данная статья ориентирована для новичков (коим и я являюсь), и возможно она прибавит не только знания, но и опыта в данной сфере. Кроме того, убедительная просьба ногами не бить - это мой первый перевод.
Сама статья (http://vault.reversers.org/TextSearch&phrase=PECompactInlinePatching)
Подопытный крякми (http://vault.reversers.org/PECompactInlinePatching/files.xml&action=download&file=dhx.cme.1.zip)
Начнем. Крякми приложенный к данной статье был запакован 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
Сохраняем изменения, запускаем крякми, вводим пасс – все работает!