Главная » Статьи » Распаковка

Реализация мини VM
[Image]
Далее хотел бы предложить идею реализации мини ВМ, для защиты кода в программе. Под мини ВМ подразумевается ВМ, с поддержкой ограниченного числа регистров и инструкций, по принципу чтения и исполнения байт кода/псевдокода. Реализовано на примере алгоритма TEA. Для начала посмотрим на дизассемблерный листинг алгоритма TEA. функция TEAEncrypt:
00401000 /. 55 PUSH EBP
00401001 |. 8BEC MOV EBP,ESP
00401003 |. 57 PUSH EDI
00401004 |. 56 PUSH ESI
00401005 |. 53 PUSH EBX
00401006 |. 8B75 08 MOV ESI,DWORD PTR SS:[EBP+8]
00401009 |. 8B06 MOV EAX,DWORD PTR DS:[ESI]
0040100B |. 8B56 04 MOV EDX,DWORD PTR DS:[ESI+4]
0040100E |. 33DB XOR EBX,EBX
00401010 |. 0FC8 BSWAP EAX
00401012 |. 0FCA BSWAP EDX
00401014 |. 81C3 B979379E ADD EBX,9E3779B9
-------------------------------------------
0040101A |. 8BCA |MOV ECX,EDX
0040101C |. C1E1 04 |SHL ECX,4
0040101F |. 8BFA |MOV EDI,EDX
00401021 |. 8D3413 |LEA ESI,DWORD PTR DS:[EBX+EDX]
00401024 |. 030D 20304000 |ADD ECX,DWORD PTR DS:[403020]
0040102A |. C1EF 05 |SHR EDI,5
0040102D |. 33CE |XOR ECX,ESI
0040102F |. 033D 24304000 |ADD EDI,DWORD PTR DS:[403024]
00401035 |. 33CF |XOR ECX,EDI
00401037 |. 03C1 |ADD EAX,ECX
-------------------------------------------
00401039 |. 8BC8 |MOV ECX,EAX
0040103B |. C1E1 04 |SHL ECX,4
0040103E |. 8BF8 |MOV EDI,EAX
00401040 |. 8D3403 |LEA ESI,DWORD PTR DS:[EBX+EAX]
00401043 |. 030D 28304000 |ADD ECX,DWORD PTR DS:[403028]
00401049 |. C1EF 05 |SHR EDI,5
0040104C |. 33CE |XOR ECX,ESI
0040104E |. 033D 2C304000 |ADD EDI,DWORD PTR DS:[40302C]
00401054 |. 33CF |XOR ECX,EDI
00401056 |. 03D1 |ADD EDX,ECX
-------------------------------------------
00401058 |. 81C3 B979379E |ADD EBX,9E3779B9
-------------------------------------------
0040105E |. 8BCA |MOV ECX,EDX
00401060 |. C1E1 04 |SHL ECX,4
00401063 |. 8BFA |MOV EDI,EDX
00401065 |. 8D3413 |LEA ESI,DWORD PTR DS:[EBX+EDX]
00401068 |. 030D 20304000 |ADD ECX,DWORD PTR DS:[403020]
0040106E |. C1EF 05 |SHR EDI,5
00401071 |. 33CE |XOR ECX,ESI
00401073 |. 033D 24304000 |ADD EDI,DWORD PTR DS:[403024]
00401079 |. 33CF |XOR ECX,EDI
0040107B |. 03C1 |ADD EAX,ECX
-------------------------------------------
0040107D |. 8BC8 |MOV ECX,EAX
0040107F |. C1E1 04 |SHL ECX,4
00401082 |. 8BF8 |MOV EDI,EAX
00401084 |. 8D3403 |LEA ESI,DWORD PTR DS:[EBX+EAX]
00401087 |. 030D 28304000 |ADD ECX,DWORD PTR DS:[403028]
0040108D |. C1EF 05 |SHR EDI,5
00401090 |. 33CE |XOR ECX,ESI
00401092 |. 033D 2C304000 |ADD EDI,DWORD PTR DS:[40302C]
00401098 |. 33CF |XOR ECX,EDI
0040109A |. 03D1 |ADD EDX,ECX
-------------------------------------------
0040109C |. 81FB 2037EFC6 |CMP EBX,C6EF3720
-------------------------------------------
004010A2 |.^0F85 6CFFFFFF \JNZ main.00401014
004010A8 |. 0FC8 BSWAP EAX
004010AA |. 0FCA BSWAP EDX
 
004010AC |. 8B75 0C MOV ESI,DWORD PTR SS:[EBP+C]
004010AF |. 8906 MOV DWORD PTR DS:[ESI],EAX
004010B1 |. 8956 04 MOV DWORD PTR DS:[ESI+4],EDX
 
004010B4 |. 5B POP EBX
004010B5 |. 5E POP ESI
004010B6 |. 5F POP EDI
004010B7 |. C9 LEAVE
004010B8 \. C2 0800 RETN 8
Первым делом надо выписать все инструкции что здесь используются, это:
PUSH,POP,MOV,XOR,BSWAP,ADD,SUB,SHL,SHR,LEA,JNZ,CMP,LEAVE,RETN
Потом для упращения задачи, отсортировать инструкции и привести к общему виду:
PUSH REG32
POP REG32
MOV REG32, REG32
MOV REG32, DWORD PTR [REG32]
MOV REG32, DWORD PTR [REG32 + imm8]
MOV DWORD PTR [REG32], REG32
MOV DWORD PTR [REG32 + imm8], REG32
XOR REG32, REG32
BSWAP REG32
ADD REG32, REG32
ADD REG32, imm32
ADD REG32, DWORD PTR[imm32]
SUB REG32, REG32
SUB REG32, imm32
SHL REG32, imm8
SHR REG32, imm8
LEA REG32, DWORD PTR [REG32 + REG32]
CMP REG32, IMM32
JNZ imm32
LEAVE
RETN imm16
Как и у любой другой ВМ, у нас должны быть регистры, их мы объявим в типе «MYCONTEXT». Всего нам потребуется 10 регистров: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP, EFLAGS (регистр флагов). Остальные трогать нет необходимости из-за «узконаправленной цели».

MYCONTEXT struct
 ; Registers
 r_EAX dd ?
 r_ECX dd ?
 r_EDX dd ?
 r_EBX dd ?
 r_ESP dd ?
 r_EBP dd ?
 r_ESI dd ?
 r_EDI dd ?
 r_EIP dd ?
 ; FLAGS Register
 flags dd ?
MYCONTEXT ends
Теперь переходим к составлению системы команд. В Функциях TEAEncrypt и TEADecrypt всего используется 14 инструкций, следовательно на эти 14 инструкций мы можем затратить 4 бита под описание, а в остальных битах держать какую либо другую информацию. К примеру возьмём инструкцию «PUSH REG32», описать её можно таким видом:
1 БАЙТ 0 0 0 0 0 0 0 0
БИТ № 7 6 5 4 3 2 1 0
Биты под номерами 7-4 будут указывать ВМ на то, что это инструкция PUSH, а в битах 3-0 логично будет держать индекс регистра. Далее приведу таблицу индексов регистров
EAX 0000b
ECX 0001b
EDX 0010b
EBX 0011b
ESP 0100b
EBP 0101b
ESI 0110b
EDI 0111b
Исходя из таблицы, можно смело утверждать, что мы использовали «PUSH EAX». Для более конкретного примера возьмём инструкцию «SUB REG32, REG32»
2 БАЙТА 1010 0000 0000 0000
БИТ № 7654 3210 7654 3210
Как вы заметили инструкция SUB, занимает уже 2 байта, потому как в 4 бита первого байта описать 2 регистра будет не возможно. Они будут описаны во втором байте в битах под номерами 5-3 и 2-0. Ниже перечислен полный список системы команд «заточенной» под алгоритм TEA.
Мнемоника инструкции BYTE (1) BYTE (2) IMM8 / IMM32
 PUSH 0000 REG32 - -
 POP 0001 REG32 - -
 BSWAP 0010 REG32 - -
 SHL 0011 REG32 - -
 SHR 0100 REG32 - -
 LEAVE 0101 - - -
 RETN 0110 0000 IMM16
 MOV 0111 EXT* REG32, REG32 IMM8/IMM32
 XOR 1000 0000 REG32, REG32 -
 ADD 1001 EXT* REG32, REG32 IMM32
 SUB 1010 EXT* REG32, REG32 IMM32
 LEA 1011 REG32 REG32, REG32 -
 JNZ 1100 0000 IMM32
 CMP 1101 0000 IMM32
*EXT – означает, что инструкция имеет расширение, от значения которого зависит наличие дополнительных параметров/метода адресации и т.д. Рассмотрим параметр EXT подробнее: EXT Дополнительные Параметры
 
 0001 REG32, REG32
 0010 REG32, DWORD PTR [REG32]
 0011 REG32, DWORD PTR [IMM32]
 0100 REG32, DWORD PTR [REG32 + imm8]
 0101 MOV REG32, IMM32
Стоит объяснить на примере смысл значения EXT.
OPCODE EXT BYTE 2 IMM8
0111 0100 00001010 020h
По полю «OPCODE» видно, что используется инструкция «MOV», по параметру «EXT» из таблицы можно понять, какой метод адресации используется в данной инструкции, получается вид: «REG32, DWORD PTR [REG32 + imm8]» далее по второму байту, в котором хранятся индексы двух регистров можно смело утверждать, что первый регистр будет ECX, а второй EDX, из третьего байта возьмём IMM8. В результате имеем следующее:
MOV ECX, DWORD PTR [EDX + 020h]


Итак, будем считать, что система команд у нас готова. Далее следует реализация псевдокода. В этом примере я использовал макросы для генерации оного. Описание приводить здесь не буду, посмотрите исходник в архиве «macros.inc», ничего сложного там нет, всё сделано по табличке системы комманд.

P.S. Хотелось бы добавить ещё мысли по поводу индексов регистров в системе комманд. Можно заменить индексы, прямыми адресами переменных под регистры, что уменьшит скорость обращения к ним, но увеличит размер псевдокода, но данную причину не расцениваю как недостаток, ведь всёравно быстрее чем на реальном процессоре выполнить псевдокод не получится. [Image]Скачать | Dowload Скачать исходники для статьи (мини VM) (3.79 Kb)
Категория: Распаковка | Добавил: -=Hellsing=- (28.12.2009) | Автор: JakoLerto
Просмотров: 2543 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]