Ограничения Демоверсии

Issues related to VMProtect
Александр
Posts: 14
Joined: Mon Oct 19, 2015 1:50 pm

Re: Ограничения Демоверсии

Post by Александр »

Да, но адрес возврата для sysenter это как раз вот этот пресловутый lea+push :)
Admin
Site Admin
Posts: 2584
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: Ограничения Демоверсии

Post by Admin »

Да, но адрес возврата для sysenter это как раз вот этот пресловутый lea+push :)
А зачем вам тогда вот эта штука? :))

Code: Select all

mov edx, esp
На самом деле EDX - это указатель на стек, откуда будет взят адрес возврата, поэтому совершенно без разницы откуда он там появится - как результат LEA+PUSH или как результат от CALL.

P.S. Походу у вас там еще и проблемы со стеком (один из push eax лишний)
Admin
Site Admin
Posts: 2584
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: Ограничения Демоверсии

Post by Admin »

На самом в вашем коде проблемы еще и в ветке IsWow64Process == 1 (все тотже самый неявный переход на адрес, о котором VMProtect ничего не знает):

Code: Select all

0041989D 		lea eax, [004198B4]
004198A3 		push eax
004198A4 		push eax
004198A5 		mov eax, [ebp-0C]
004198A8 		push eax
004198A9 		mov eax, [ebp-10]
004198AC 		xor ecx, ecx
004198AE 		lea edx, [esp+0C]
004198B3 		ret
Александр
Posts: 14
Joined: Mon Oct 19, 2015 1:50 pm

Re: Ограничения Демоверсии

Post by Александр »

До работы доеду, распишу более подробно.
А этот код отрабатывает на 64 битных системах, переходник на wow64 шлюз :)
Admin
Site Admin
Posts: 2584
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: Ограничения Демоверсии

Post by Admin »

Да, я уже дошел до JMPFAR, поэтому эту штуку лучше вынести в отдельную функцию и вызывать её через CALL по аналогии с SYSENTER/INT2E
Александр
Posts: 14
Joined: Mon Oct 19, 2015 1:50 pm

Re: Ограничения Демоверсии

Post by Александр »

Так, теперь по коду, у нас есть три участка производящие вызов в ядро.

1. через WOW64
2. через sysenter для XP и выше
3. через INT 2E для W2K (в принципе это устарело - не рассматриваем, работает так же как и sysenter)

общий код для всех трех переходников одинаков, это инициализация параметров вызова функции, размещенных на стеке, бо stdcall.

К примеру пусть это будет вызов NtSetInformationThread

Code: Select all

      xor  eax, eax
      push eax
      push eax
      push 17
      mov  eax, hThread
      push eax
для начала sysenter

Code: Select all

      lea  eax, @FINALIZE ; получаем адрес на который будет происходить переход после выполнения sysenter
      push eax ; и пушим его на стек
      push eax ; второй параметр в оригинале (KiFastSystemCall) обнулён, но если положить туда любое число поведение не меняется, поэтому пушим еще раз
      mov edx, esp ; указываем значение верхушки стека
      mov eax, SysCallArgument ; указываем SDT индекс
      sysenter ; производим вызов
суть: если на стеке не разместить адрес возврата на @FINALIZE то после выполнения sysenter мы попадем туда, откуда нам уже не выползти.

теперь вызов WOW

Code: Select all

    lea  eax, @64bit ; получаем адрес на который будет происходить переход после выполнения WOW64 перехода {переключения режимов 32 и 64 бита}
    push eax ; и пушим его на стек
    push eax ; это по аналогу с sysenter, бо не ясно что он от нас хочет, но должен быть
    mov  eax, WOW64Addr ; берем адрес WOW64 (FS:[0xC0])
    push eax ; пушим на стек для последующего ret
    mov  eax, SysCallArgument  ; указываем SDT индекс
    xor  ecx, ecx ; ECX обязательно должен быть обнулён
    lea  edx, dword ptr ss:[esp+4*3] ; в EDX указатель на адрес начала параметров функции на стеке
    ret ; производим вызов

  @64bit:
    add esp, 4 ; чистим
    jmp @FINALIZE
в данном случае VMProt не распознает lea eax, @64bit и мы опять после выполнения уйдем в нирвану.

В итоге вопрос.
Для чего выносить код во внешнюю функцию, когда адреса возврата из sysenter или WOW должны быть на стеке, а VMProt их не сможет распознать?
Даже если я вынесу вызов во внешку, то там эти адреса возврата все равно должны присутствовать и получается что я опять не смогу завиртуализировать этот кусок кода.

Поэтому мое изначальное предложение о автоматической пометке внешних адресов (которые плывут при каждом ребилде проекта) остается в силе.

ЗЫ: вариант с ret в случае WOW64 делался из-за особенностей криптора, который не умеет работать с FS сегментом, т.е. mov eax, FS:[0xC0] или call FS:[0xC0] им не виртуализировались и падали.
Admin
Site Admin
Posts: 2584
Joined: Mon Aug 21, 2006 8:19 pm
Location: Russia, E-burg
Contact:

Re: Ограничения Демоверсии

Post by Admin »

Для чего выносить код во внешнюю функцию, когда адреса возврата из sysenter или WOW должны быть на стеке, а VMProt их не сможет распознать?
Даже если я вынесу вызов во внешку, то там эти адреса возврата все равно должны присутствовать и получается что я опять не смогу завиртуализировать этот кусок кода.
Если SYSENTER/INT2E будут оформлены в виде отдельной функции, то при её вызове через CALL на стеке будет адрес возврата, который поддерживается VMProtect. Скиньте телефон или скайп в личку - так будет проще объяснить :))

Нарисую для наглядности:

Code: Select all

function SysEnter(param)
asm
   mov edx, esp
   mov eax, param
   sysenter
end;

function foo()
begin
  ...
  SysEnter(param);
  ...
  Int2E(param);
  ...
end;
Александр
Posts: 14
Joined: Mon Oct 19, 2015 1:50 pm

Re: Ограничения Демоверсии

Post by Александр »

Сейчас в аську стукну
Post Reply