0x0c0de
27.07.2007, 13:00
Исследование DotFix NiceProtect
[Part I]
[Intro]
Начала эту статью писать еще до отпуска.. Сейчас нарыла в недрах винта и решила ее закончить наконец-то=) Начала писать потому, что материала было этому проту катастрофически мало. Скачала протектор, и начала его препарировать…
* Версия, используемая в этой статье – 2.5 – вм не используется, так как триал(
[Инструменты]
OllyDbg – отладчик
LordPe – дампер
ImpRec – восстановление импорта
CFF Explorer – Pe Editor
[Опции]
Посмотрим сначала на возможные опции защиты
*Protect original entry point ; защита оригинальной точки входа
*Encrypt code section ; шифрация кодовой секции
*Use anti-tracing ; анти-трассировка
*Use anti-debug ; анти-отладка
Здесь, думаю, все понятно
Также существует два метода защиты
*Include SEH frames
*Stolen bytes protection
Второй случай страшнее и продвинутей, первый – более простая защита.
[Исследование]
Распаковка на примере Пасьянс ”Паук” из стандартной поставки форточек.
Опции защиты – все.
1.Метод защиты – SEH.
Интересная функция прота – использование сигнатуры какого-то компилятора или протектора=) Чтобы ввести Peid в замешательство. Например в нашем случае entry point выглядит так
01008F00 > 55 PUSH EBP
01008F01 8BEC MOV EBP,ESP
01008F03 6A FF PUSH -1
01008F05 68 92240001 PUSH spider.01002492
01008F0A 68 92240001 PUSH spider.01002492
01008F0F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
01008F15 50 PUSH EAX
01008F16 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
01008F1D 83C4 10 ADD ESP,10
01008F20 B8 00000000 MOV EAX,0
01008F25 8BE5 MOV ESP,EBP
01008F27 5D POP EBP
Peid самоуверенно заявляет, что файл ничем не запакован и определяет компилятор - Microsoft Visual C++=) Отлично. Пакер свое дело сделал=)
[ Нахождение OEP]
Логично использовать тот факт, что все графические приложения используют в своей работе определенный стандартный набор функций. При нахождении OEP в данном случае нам понадобятся две функции GetModuleHandleA и GetVersionExA. Если не срабатывает на этих функциях – попробуйте поставить бряк на юникод-версии этих функций (GetVersionExW и GetModuleHandleW). Поставили бряки. В Olly Dbg Go-to->Expression-> GetModuleHandleA -> брекпоинт на ret, также поступаем с GetVersion. Брекпоинт сработает несколько раз, нужно дождаться момента, когда адрес возврата будет соответствовать нашей запакованной программе. В данной проге функция-ориентир – как раз GetVersion, а не GetModuleHandle. Сначала я пробовала как раз второй вариант, но не получив результатов начала искать альтернативу. Альтернативой оказалась GetVersion.
01008FB2 6A 60 PUSH 60
01008FB4 68 48160001 PUSH spider.01001648
01008FB9 E8 B2110000 CALL spider.0100A170
01008FBE BF 94000000 MOV EDI,94
01008FC3 8BC7 MOV EAX,EDI
01008FC5 E8 06130000 CALL spider.0100A2D0
01008FCA 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
01008FCD 8BF4 MOV ESI,ESP
01008FCF 893E MOV DWORD PTR DS:[ESI],EDI
01008FD1 56 PUSH ESI
01008FD2 FF15 58110001 CALL DWORD PTR DS:[1001158] ; kernel32.GetVersionExA
01008FD8 8B4E 10 MOV ECX,DWORD PTR DS:[ESI+10] ; нажав f7 попали сюда
Типичный start-up. Снимаем дамп. Дамп снимается без проблем – антидамп не предусмотрен. Восстановим импорт. Ввожу OEP 0008FB2-> Iat auto search->Get Import. Все нашлось=) Склеиваю с дампом и все работает на ура. Нда. Работает на ура – а размер гигантский. 5,6 метров! С помощью CFF Explorer отрезаю 5-метровую секцию. Запускаю. Все работает.
Приступаем ко второму дублю распаковки. Участники те же=)
2.Метод защиты – Stolen Bytes.
OEP – находим так же. Только возвращаемся мы в секцию пакера.
015A3FCC . 6A 60 PUSH 60
015A3FCE . C74424 FC 48160001 MOV DWORD PTR SS:[ESP-4],spider.01001648
015A3FD6 . EB 01 JMP SHORT spider.015A3FD9
015A3FD8 E9 DB E9
015A3FD9 > 83EC 04 SUB ESP,4
015A3FDC . 68 ED3F5A01 PUSH spider.015A3FED
015A3FE1 . EB 01 JMP SHORT spider.015A3FE4
015A3FE3 E8 DB E8
015A3FE4 > 68 70A10001 PUSH spider.0100A170
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8
015A3FEC > C3 RETN
015A3FED . 68 00000094 PUSH 94000000
015A3FF2 . 5F POP EDI
015A3FF3 . 0FCF BSWAP EDI
015A3FF5 . 8BC7 MOV EAX,EDI
015A3FF7 . 68 08405A01 PUSH spider.015A4008
015A3FFC . EB 01 JMP SHORT spider.015A3FFF
015A3FFE E9 DB E9
015A3FFF > 68 D0A20001 PUSH spider.0100A2D0
015A4004 . EB 01 JMP SHORT spider.015A4007
015A4006 E8 DB E8
015A4007 > C3 RETN
015A4008 . 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
015A400B . 8BF4 MOV ESI,ESP
015A400D . 893E MOV DWORD PTR DS:[ESI],EDI
015A400F . 897424 FC MOV DWORD PTR SS:[ESP-4],ESI
015A4013 . 83EC 04 SUB ESP,4
015A4016 . FF15 58110001 CALL DWORD PTR DS:[<&KERNEL32.GetVersionExA>] ; \GetVersionExA
015A401C . 8B4E 10 MOV ECX,DWORD PTR DS:[ESI+10] ; возврат сюда
015A401F . 890D 6C300101 MOV DWORD PTR DS:[101306C],ECX
015A4025 . 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
015A4028 . A3 78300101 MOV DWORD PTR DS:[1013078],EAX
015A402D . 8B56 08 MOV EDX,DWORD PTR DS:[ESI+8]
015A4030 . 8915 7C300101 MOV DWORD PTR DS:[101307C],EDX
015A4036 . 8B76 0C MOV ESI,DWORD PTR DS:[ESI+C]
015A4039 . 81E6 FF7F0000 AND ESI,7FFF
015A403F . 9C PUSHFD
015A4040 . 9D POPFD
015A4041 . 8935 70300101 MOV DWORD PTR DS:[1013070],ESI
015A4047 . 83F9 02 CMP ECX,2
015A404A . 9C PUSHFD
015A404B . 9D POPFD
015A404C > 60 PUSHAD
015A404D . 68 03900001 PUSH spider.01009003 ; этот пуш+ следующий рет аналогичны инструкции jmp 01009003
Видно, что oep начинается с инструкции push 60 - так как прога на с++ написана. Проверим, действительно ли это сильно замусоренный стартовый код...
Посмотрим внимательнее ...
015A3FCE . C74424 FC 48160001 MOV DWORD PTR SS:[ESP-4],spider.01001648
015A3FD6 . EB 01 JMP SHORT spider.015A3FD9
015A3FD8 E9 DB E9
015A3FD9 > 83EC 04 SUB ESP,4
аналогично push 01001648...
015A3FE1 . EB 01 JMP SHORT spider.015A3FE4
015A3FE3 E8 DB E8
015A3FE4 > 68 70A10001 PUSH spider.0100A170
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8
015A3FEC > C3 RETN
Пара инструкций PUSH spider.0100A170 и ret аналогичны инструкции call 0100A170. Так дальше...
015A3FED . 68 00000094 PUSH 94000000
015A3FF2 . 5F POP EDI
015A3FF3 . 0FCF EDI
015A3FF5 . 8BC7 MOV EAX,EDI
Первые две инструкции можно заменить на mov edi,94000000.. Я не помнила, что такое BSWAP, поэтому поставила на инструкцию по адресу 015A3FED New origin here и после выполнения команды в edi оказалось число 94.
Теперь пора заменить эти инструкции на
mov edi,94
mov eax,edi
Что мы получили теперь
push 60
push 01001648
call 0100A170
mov edi,94
mov eax,edi
Похоже на oep. будем считать что это oep.
Такс… Много байт притырил себе. И мусора намешал, но это мы обошли, проанализировав код
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8 ; это чтобы смутить отладчик=) следующие 4 байта будут неверно проанализированы
Восстанавливать не хочется. Да и зачем это надо? Крадет только с OEP байты + все это добро не в выделенной памяти. Значит дампим. Открываем Imprec, пишем oep 05A3FCC и он без проблем определяет все функции. Так что все просто и восстанавливать ни к чему=) Запускаем, все работает=) Можно поизвращаться, позаменять инструкции на альтернативные, а потом вручную восстановить на свое место. Но, учитывая, что прот крадет в среднем 100 байт (в данном случае 81, а неск. других 104 и 95)- это долго.
[Антиотладка]
Отключила все плагины для скрытия отладчика, но на антиотладку мне напороться так и не пришлось. Может, плохо искала? =)
[Где скачать]
_http://www.niceprotect.com/index.php?p=Download
Офф сайт протектора
На этом пока все=)
[Part I]
[Intro]
Начала эту статью писать еще до отпуска.. Сейчас нарыла в недрах винта и решила ее закончить наконец-то=) Начала писать потому, что материала было этому проту катастрофически мало. Скачала протектор, и начала его препарировать…
* Версия, используемая в этой статье – 2.5 – вм не используется, так как триал(
[Инструменты]
OllyDbg – отладчик
LordPe – дампер
ImpRec – восстановление импорта
CFF Explorer – Pe Editor
[Опции]
Посмотрим сначала на возможные опции защиты
*Protect original entry point ; защита оригинальной точки входа
*Encrypt code section ; шифрация кодовой секции
*Use anti-tracing ; анти-трассировка
*Use anti-debug ; анти-отладка
Здесь, думаю, все понятно
Также существует два метода защиты
*Include SEH frames
*Stolen bytes protection
Второй случай страшнее и продвинутей, первый – более простая защита.
[Исследование]
Распаковка на примере Пасьянс ”Паук” из стандартной поставки форточек.
Опции защиты – все.
1.Метод защиты – SEH.
Интересная функция прота – использование сигнатуры какого-то компилятора или протектора=) Чтобы ввести Peid в замешательство. Например в нашем случае entry point выглядит так
01008F00 > 55 PUSH EBP
01008F01 8BEC MOV EBP,ESP
01008F03 6A FF PUSH -1
01008F05 68 92240001 PUSH spider.01002492
01008F0A 68 92240001 PUSH spider.01002492
01008F0F 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
01008F15 50 PUSH EAX
01008F16 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
01008F1D 83C4 10 ADD ESP,10
01008F20 B8 00000000 MOV EAX,0
01008F25 8BE5 MOV ESP,EBP
01008F27 5D POP EBP
Peid самоуверенно заявляет, что файл ничем не запакован и определяет компилятор - Microsoft Visual C++=) Отлично. Пакер свое дело сделал=)
[ Нахождение OEP]
Логично использовать тот факт, что все графические приложения используют в своей работе определенный стандартный набор функций. При нахождении OEP в данном случае нам понадобятся две функции GetModuleHandleA и GetVersionExA. Если не срабатывает на этих функциях – попробуйте поставить бряк на юникод-версии этих функций (GetVersionExW и GetModuleHandleW). Поставили бряки. В Olly Dbg Go-to->Expression-> GetModuleHandleA -> брекпоинт на ret, также поступаем с GetVersion. Брекпоинт сработает несколько раз, нужно дождаться момента, когда адрес возврата будет соответствовать нашей запакованной программе. В данной проге функция-ориентир – как раз GetVersion, а не GetModuleHandle. Сначала я пробовала как раз второй вариант, но не получив результатов начала искать альтернативу. Альтернативой оказалась GetVersion.
01008FB2 6A 60 PUSH 60
01008FB4 68 48160001 PUSH spider.01001648
01008FB9 E8 B2110000 CALL spider.0100A170
01008FBE BF 94000000 MOV EDI,94
01008FC3 8BC7 MOV EAX,EDI
01008FC5 E8 06130000 CALL spider.0100A2D0
01008FCA 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
01008FCD 8BF4 MOV ESI,ESP
01008FCF 893E MOV DWORD PTR DS:[ESI],EDI
01008FD1 56 PUSH ESI
01008FD2 FF15 58110001 CALL DWORD PTR DS:[1001158] ; kernel32.GetVersionExA
01008FD8 8B4E 10 MOV ECX,DWORD PTR DS:[ESI+10] ; нажав f7 попали сюда
Типичный start-up. Снимаем дамп. Дамп снимается без проблем – антидамп не предусмотрен. Восстановим импорт. Ввожу OEP 0008FB2-> Iat auto search->Get Import. Все нашлось=) Склеиваю с дампом и все работает на ура. Нда. Работает на ура – а размер гигантский. 5,6 метров! С помощью CFF Explorer отрезаю 5-метровую секцию. Запускаю. Все работает.
Приступаем ко второму дублю распаковки. Участники те же=)
2.Метод защиты – Stolen Bytes.
OEP – находим так же. Только возвращаемся мы в секцию пакера.
015A3FCC . 6A 60 PUSH 60
015A3FCE . C74424 FC 48160001 MOV DWORD PTR SS:[ESP-4],spider.01001648
015A3FD6 . EB 01 JMP SHORT spider.015A3FD9
015A3FD8 E9 DB E9
015A3FD9 > 83EC 04 SUB ESP,4
015A3FDC . 68 ED3F5A01 PUSH spider.015A3FED
015A3FE1 . EB 01 JMP SHORT spider.015A3FE4
015A3FE3 E8 DB E8
015A3FE4 > 68 70A10001 PUSH spider.0100A170
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8
015A3FEC > C3 RETN
015A3FED . 68 00000094 PUSH 94000000
015A3FF2 . 5F POP EDI
015A3FF3 . 0FCF BSWAP EDI
015A3FF5 . 8BC7 MOV EAX,EDI
015A3FF7 . 68 08405A01 PUSH spider.015A4008
015A3FFC . EB 01 JMP SHORT spider.015A3FFF
015A3FFE E9 DB E9
015A3FFF > 68 D0A20001 PUSH spider.0100A2D0
015A4004 . EB 01 JMP SHORT spider.015A4007
015A4006 E8 DB E8
015A4007 > C3 RETN
015A4008 . 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
015A400B . 8BF4 MOV ESI,ESP
015A400D . 893E MOV DWORD PTR DS:[ESI],EDI
015A400F . 897424 FC MOV DWORD PTR SS:[ESP-4],ESI
015A4013 . 83EC 04 SUB ESP,4
015A4016 . FF15 58110001 CALL DWORD PTR DS:[<&KERNEL32.GetVersionExA>] ; \GetVersionExA
015A401C . 8B4E 10 MOV ECX,DWORD PTR DS:[ESI+10] ; возврат сюда
015A401F . 890D 6C300101 MOV DWORD PTR DS:[101306C],ECX
015A4025 . 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
015A4028 . A3 78300101 MOV DWORD PTR DS:[1013078],EAX
015A402D . 8B56 08 MOV EDX,DWORD PTR DS:[ESI+8]
015A4030 . 8915 7C300101 MOV DWORD PTR DS:[101307C],EDX
015A4036 . 8B76 0C MOV ESI,DWORD PTR DS:[ESI+C]
015A4039 . 81E6 FF7F0000 AND ESI,7FFF
015A403F . 9C PUSHFD
015A4040 . 9D POPFD
015A4041 . 8935 70300101 MOV DWORD PTR DS:[1013070],ESI
015A4047 . 83F9 02 CMP ECX,2
015A404A . 9C PUSHFD
015A404B . 9D POPFD
015A404C > 60 PUSHAD
015A404D . 68 03900001 PUSH spider.01009003 ; этот пуш+ следующий рет аналогичны инструкции jmp 01009003
Видно, что oep начинается с инструкции push 60 - так как прога на с++ написана. Проверим, действительно ли это сильно замусоренный стартовый код...
Посмотрим внимательнее ...
015A3FCE . C74424 FC 48160001 MOV DWORD PTR SS:[ESP-4],spider.01001648
015A3FD6 . EB 01 JMP SHORT spider.015A3FD9
015A3FD8 E9 DB E9
015A3FD9 > 83EC 04 SUB ESP,4
аналогично push 01001648...
015A3FE1 . EB 01 JMP SHORT spider.015A3FE4
015A3FE3 E8 DB E8
015A3FE4 > 68 70A10001 PUSH spider.0100A170
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8
015A3FEC > C3 RETN
Пара инструкций PUSH spider.0100A170 и ret аналогичны инструкции call 0100A170. Так дальше...
015A3FED . 68 00000094 PUSH 94000000
015A3FF2 . 5F POP EDI
015A3FF3 . 0FCF EDI
015A3FF5 . 8BC7 MOV EAX,EDI
Первые две инструкции можно заменить на mov edi,94000000.. Я не помнила, что такое BSWAP, поэтому поставила на инструкцию по адресу 015A3FED New origin here и после выполнения команды в edi оказалось число 94.
Теперь пора заменить эти инструкции на
mov edi,94
mov eax,edi
Что мы получили теперь
push 60
push 01001648
call 0100A170
mov edi,94
mov eax,edi
Похоже на oep. будем считать что это oep.
Такс… Много байт притырил себе. И мусора намешал, но это мы обошли, проанализировав код
015A3FE9 . EB 01 JMP SHORT spider.015A3FEC
015A3FEB E8 DB E8 ; это чтобы смутить отладчик=) следующие 4 байта будут неверно проанализированы
Восстанавливать не хочется. Да и зачем это надо? Крадет только с OEP байты + все это добро не в выделенной памяти. Значит дампим. Открываем Imprec, пишем oep 05A3FCC и он без проблем определяет все функции. Так что все просто и восстанавливать ни к чему=) Запускаем, все работает=) Можно поизвращаться, позаменять инструкции на альтернативные, а потом вручную восстановить на свое место. Но, учитывая, что прот крадет в среднем 100 байт (в данном случае 81, а неск. других 104 и 95)- это долго.
[Антиотладка]
Отключила все плагины для скрытия отладчика, но на антиотладку мне напороться так и не пришлось. Может, плохо искала? =)
[Где скачать]
_http://www.niceprotect.com/index.php?p=Download
Офф сайт протектора
На этом пока все=)