Page 1 of 2
Ограничения Демоверсии
Posted: Mon Oct 19, 2015 1:56 pm
by Александр
Тестирую сейчас демоверсию, в частности посмотрел что из себя представляет морф кода без виртуализации. В самом простейшем примере получилось что добавляются всего лишь мусорные инструкции:
Code: Select all
.vmp2:0056FCBD sub_56FCBD proc near ; CODE XREF: sub_418860j
.vmp2:0056FCBD push ebp
.vmp2:0056FCBE cwd ; мусор
.vmp2:0056FCC0 movsx dx, bh ; мусор
.vmp2:0056FCC4 mov ebp, esp
.vmp2:0056FCC6 xchg eax, edx ; мусор
.vmp2:0056FCC7 not edx ; мусор
.vmp2:0056FCC9 mov eax, off_41D628
.vmp2:0056FCCE xchg dh, dl ; мусор
.vmp2:0056FCD0 cmovns dx, di ; мусор
.vmp2:0056FCD4 mov edx, offset aMorphedCode ; "Morphed code"
.vmp2:0056FCD9 call sub_4050F0
.vmp2:0056FCDE call sub_4051F0
.vmp2:0056FCE3 call sub_404004
.vmp2:0056FCE8 pop ebp
.vmp2:0056FCE9 retn
.vmp2:0056FCE9 sub_56FCBD endp
Вопрос, в полной версии результаты морфа останутся такими же или это просто сама демонстрация как именно происходит морф?
Re: Ограничения Демоверсии
Posted: Tue Oct 20, 2015 9:11 am
by Александр
Ну и тоже по виртуальной машине. этот-же код накрытый через MAP файл:
Code: Select all
procedure Foo0;
begin
Writeln('ххх');
end;
виртуализация: всего 38 уникальных обработчиков, общее число циклов VM 435
виртуализация + мутация: всего 94 уникальных обработчика, общее число циклов VM 1001
виртуализация + мутация + привязка к серийному номеру: всего 107 уникальных обработчика, общее число циклов VM 14825
Маловато будет циклов, или это действительно просто ограничение демоверсии (один два прохода глубина виртуализации и обфускации)?
Re: Ограничения Демоверсии
Posted: Tue Oct 20, 2015 3:44 pm
by Александр
Все становится интересней.
Сейчас попросил покрыть тот-же проект у человека с легальной VMProt 3.0.5.
Мутация вообще не произведена:
Т.е все оставлено в том виде как и было
Code: Select all
CPU Disasm
Address Hex dump Command Comments
008AA311 55 PUSH EBP
008AA312 8BEC MOV EBP,ESP
008AA314 A1 C0D74D00 MOV EAX,DWORD PTR DS:[4DD7C0]
008AA319 BA 30534D00 MOV EDX,004D5330 ; UNICODE "Morphed code"
008AA31E E8 C5DCB5FF CALL 00407FE8
008AA323 E8 00DFB5FF CALL 00408228
008AA328 E8 CFC4B5FF CALL 004067FC
008AA32D 5D POP EBP
008AA32E C3 RETN
Это как так?
Ладно смотрю VM, общего цикла нет, уже хорошо. Инструкции пикода с ESI забираются непосредственно в хэндлерах, но...
Рассмотрим хэндлер:
Code: Select all
00899985 0FB606 MOVZX EAX,BYTE PTR [ESI]
00899988 81C6 01000000 ADD ESI,1
0089998E 33CC XOR ECX,ESP
00899990 03CF ADD ECX,EDI
00899992 32C3 XOR AL,BL
00899994 66:8BCF MOV CX,DI
00899997 0F98C5 SETS CH
0089999A FEC0 INC AL
0089999C 80D1 F5 ADC CL,0F5
0089999F F6D8 NEG AL
008999A1 0FBAF9 F1 BTC ECX,0F1 ; Shift out of range
008999A5 3AD4 CMP DL,AH
008999A7 66:81C9 0363 OR CX,6303
008999AC 34 65 XOR AL,65
008999AE 0FC9 BSWAP ECX
008999B0 66:81C1 8465 ADD CX,6584
008999B5 66:81E1 1559 AND CX,5915
008999BA 2C 96 SUB AL,96
008999BC 0FBFC9 MOVSX ECX,CX
008999BF 66:0FB6CF MOVZX CX,BH
008999C3 66:81E9 2B4F SUB CX,4F2B
008999C8 32D8 XOR BL,AL
008999CA F9 STC
008999CB 0FC9 BSWAP ECX
008999CD 8B4C25 00 MOV ECX,DWORD PTR [EBP]
008999D1 F5 CMC
008999D2 81C5 04000000 ADD EBP,4
008999D8 F8 CLC
008999D9 890C04 MOV DWORD PTR [EAX+ESP],ECX
008999DC C0C4 7D ROL AH,7D ; Shift out of range
008999DF 66:F7D8 NEG AX
008999E2 66:81FE BD10 CMP SI,10BD
008999E7 8B06 MOV EAX,DWORD PTR [ESI]
008999E9 66:85C6 TEST SI,AX
008999EC 81C6 04000000 ADD ESI,4
008999F2 85D8 TEST EAX,EBX
008999F4 33C3 XOR EAX,EBX
008999F6 F7D8 NEG EAX
008999F8 F7D0 NOT EAX
008999FA 40 INC EAX
008999FB 85C3 TEST EBX,EAX
008999FD F7D8 NEG EAX
008999FF F5 CMC
00899A00 F8 CLC
00899A01 33D8 XOR EBX,EAX
00899A03 03F8 ADD EDI,EAX
00899A05 57 PUSH EDI
00899A06 C3 RET
Вот мне страшно на такое смотреть ибо это даже руками чистится на глазок и превращается вот в такое:
Code: Select all
00899985 0FB606 MOVZX EAX,BYTE PTR [ESI]
00899988 81C6 01000000 ADD ESI,1
008999CD 8B4C25 00 MOV ECX,DWORD PTR [EBP]
00899992 32C3 XOR AL,BL
0089999A FEC0 INC AL
008999AC 34 65 XOR AL,65
008999BA 2C 96 SUB AL,96
008999C8 32D8 XOR BL,AL
008999D2 81C5 04000000 ADD EBP,4
008999D9 890C04 MOV DWORD PTR [EAX+ESP],ECX
008999E7 8B06 MOV EAX,DWORD PTR [ESI]
008999EC 81C6 04000000 ADD ESI,4
008999F4 33C3 XOR EAX,EBX
008999F6 F7D8 NEG EAX
008999F8 F7D0 NOT EAX
008999FA 40 INC EAX
008999FD F7D8 NEG EAX
00899A01 33D8 XOR EBX,EAX
00899A03 03F8 ADD EDI,EAX
00899A05 57 PUSH EDI
00899A06 C3 RET
А где обфускация?
Мы уже подали заявку на покупку вашего ПО, поэтому разъясните данные вопросы.
Re: Ограничения Демоверсии
Posted: Tue Oct 20, 2015 5:27 pm
by Александр
Еще, забыл момент.
Демоприложение собиралось со всеми отключенными опциями (защита памяти etc) проверялась только работа самого механизма защиты.
Под виртуалкой (ХР2 32 в среде от Парралелей) приложение закрывается сразу после появления сообщения о том, что защищено демонстрационной версией. (в отладчике умираем со статусом DEADCODE).
При этом на рабочей машине все работает отлично.
Re: Ограничения Демоверсии
Posted: Thu Oct 22, 2015 3:37 am
by Admin
Мы планируем улучшить качество обфускации в версии 3.1
Еще, забыл момент.
Демоприложение собиралось со всеми отключенными опциями (защита памяти etc) проверялась только работа самого механизма защиты.
Под виртуалкой (ХР2 32 в среде от Парралелей) приложение закрывается сразу после появления сообщения о том, что защищено демонстрационной версией. (в отладчике умираем со статусом DEADCODE).
При этом на рабочей машине все работает отлично.
Скорее всего включена опция "Обнаружение средств виртуализации" и закрытие приложения происходит по факту обнаружения Parallels.
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 10:37 am
by Александр
Понял, тогда следующий вопрос, планируются ли доработки вызова внешних фукнкций осуществляемых из виртуальной машины посредством:
sysenter/int 2E/ PUSH ret_addr + push call_addr+ ret/ call FS:[0xC0] {WOW64}, ну или обычный PUSH ret_addr + JMP call_addr
сейчас это не работает, как я понял неверно восстанавливается состояние стека при вызове таких инструкций (сильно пока не копал, но судя по всему причина именно в этом).
этот вопрос достаточно серьезный, т.к. старый протектор, от которого отказываемся (криптор) такие инструкции в принципе эмулировал и не хочется перелопачивать целые куски ядра защиты, в связи с невозможностью их частичной эмуляции в VM.
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 11:49 am
by Admin
Можете прислать простейший пример (оригинал EXE+MAP+VMP файлы), который не работает после VMProtect?
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 12:14 pm
by Александр
https://dl.dropboxusercontent.com/u/709 ... t_test.zip
исходник, бинарник, map и VMP
Единственный нюанс - не заработает если стоят антивирусы сплайсящие точки входа у используемых АПИ (DrWeb к примеру) и на Windows 10 64 бита.
В этом случае я не смогу получить чистые SDT индексы, поэтому лучше в песочнице запускать с чистой OS.
Примерчик старый, но суть в нем отображена полностью.
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 2:01 pm
by Admin
Проблема заключается в следующем:
Code: Select all
004198B9 lea eax, [004198DB]
004198BF push eax
004198C0 push eax
004198C1 movzx eax, byte ptr [ebp-11]
004198C5 or eax, eax
004198C7 jnz 004198D0 ↓
004198C9 mov edx, esp
004198CB mov eax, [ebp-10]
004198CE sysenter
004198D0 pop eax
004198D1 lea edx, [esp+04]
004198D5 mov eax, [ebp-10]
004198D8 int 2E
004198DA nop
004198DB mov [ebp-18], eax
При виртуализации этого куска протектор ничего не знает про неявный переход на 004198DB (lea eax, [004198DB] + push). В результате прыжка по этому адресу происходит падение, т.к. на этом месте надодится уже совершенно другой код (или пикод от ВМ или кусок исполнителя ВМ). Чтобы пример заработал нужно поменить 004198DB (и все аналогичный конструкции ниже) как "внешний адрес" через контекстное меню в дизасме.
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 4:47 pm
by Александр
спасибо, понял, проверю
Re: Ограничения Демоверсии
Posted: Fri Oct 23, 2015 4:57 pm
by Александр
Тогда еще вопрос, получается что мне при каждой сборке придется ручками помечать все такие внешние адреса, дабы не происходило падение.
А есть ли вариант это как-то оптимизировать на основе меток (код я вам прислал). В частности возьмем рассмотренный Вами выше код:
Code: Select all
lea eax, @FINALIZE
push eax
push eax
movzx eax, NeedInt2E
or eax, eax
jnz @NT_CODE
mov edx, esp
mov eax, SysCallArgument
sysenter
@FINALIZE:
можно ли как-то пометить маркер "@FINALIZE" чтобы о нем знал VMProt - к примеру той-же инлайн меткой как это применялось в крипторе.
В таком случае при каждом покрытии протектор сам будет держать в уме адреса таких внешних переходов и избавит разработчика от рутинной конфигурации релизного продукта.
Я уж не говорю о том, что на билдсервере автоматом выставить такие маркеры просто не представляется возможным, а вы сами знаете сколько сборок за день может быть сделано.
Re: Ограничения Демоверсии
Posted: Sat Oct 24, 2015 7:07 am
by Admin
можно ли как-то пометить маркер "@FINALIZE" чтобы о нем знал VMProt - к примеру той-же инлайн меткой как это применялось в крипторе.
А как это сделано в крипторе?
В любом случае я бы предложил вынести вызов sysenter/int2e в отдельную функцию:
Code: Select all
@SYSENTER:
mov edx,esp
sysenter
ret
а затем вызывать его уже по месту:
Code: Select all
movzx eax, NeedInt2E
or eax, eax
jnz @NT_CODE
mov eax, SysCallArgument
call SYSENTER
jmp @FINALIZE
@NT_CODE:
...
@FINALIZE:
При таком подходе вообще ничего не нужно будет делать на стороне VMProtect (кроме как добавить SYSENTER и INT2E в список защищаемых функций).
Re: Ограничения Демоверсии
Posted: Sat Oct 24, 2015 7:26 am
by Александр
У него помечались куски кода которые нужно было виртуализировать.
выглядело как
{$I crypt_xxx.inc}
внутри было 4 ничего не делающих джампа:
Code: Select all
asm db $EB, $06, $EB, $FC, $EB, $FC, $FF, $F8 end;
при покрытии он искал эти метки и виртуализировал код между ними.
У вас за это отвечают ваши внутренние апи.
Вот предлагаю сделать еще одну, которую разработчик может поставить в начало такого внешнего перехода и vmprot будет на них ориентироватся.
Re: Ограничения Демоверсии
Posted: Sat Oct 24, 2015 7:29 am
by Александр
Admin wrote:В любом случае я бы предложил вынести вызов sysenter/int2e в отдельную функцию:
Так это же ничего не даст, ошибка, как вы сами сказали, в адресе обработчика финализации, а не в вызове sysenter.
Да и еще, этот адрес размещенный на стеке, на него прыгает код из ядра после выполнения (т.е. он нужен для самого sysenter) т.о. вынос в отдельную процедуру не даст результата
Re: Ограничения Демоверсии
Posted: Sat Oct 24, 2015 7:36 am
by Admin
Так это же ничего не даст, ошибка, как вы сами сказали, в адресе обработчика финализации, а не в вызове sysenter.
Немного не так. VMprotect ничего не знает про LEA+PUSH+SYSENTER, а а вот про CALL он как раз знает, что на стек нужно поместить адрес возврата независимо от того что идет после CALL (в случае виртуализации CALL на стек запишется адрес переходника, который убежит обратно в ВМ выполнять следующую за CALL инструкцию).