Главная » Статьи » Распаковка |
Реализация мини VM
Далее хотел бы предложить идею реализации мини ВМ, для защиты кода в программе.
Под мини ВМ подразумевается ВМ, с поддержкой ограниченного числа регистров и инструкций, по принципу чтения и исполнения байт кода/псевдокода.
Реализовано на примере алгоритма 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. Хотелось бы добавить ещё мысли по поводу индексов регистров в системе комманд. Можно заменить индексы, прямыми адресами переменных под регистры, что уменьшит скорость обращения к ним, но увеличит размер псевдокода, но данную причину не расцениваю как недостаток, ведь всёравно быстрее чем на реальном процессоре выполнить псевдокод не получится. Скачать | Dowload Скачать исходники для статьи (мини VM) (3.79 Kb) | |
Просмотров: 2608 | Рейтинг: 0.0/0 |
Всего комментариев: 0 | |