Repository: NIKJOO/x86-Code-Virtualizer Branch: master Commit: a735af94e931 Files: 30 Total size: 88.3 KB Directory structure: gitextract_b3mfdzwd/ ├── LICENSE ├── README.md ├── VM Project/ │ ├── BEAInclude/ │ │ ├── basic_types.h │ │ └── export.h │ ├── BeaEngine.exp │ ├── BeaEngine.h │ ├── BeaEngine.lib │ ├── InstructionLogger.cpp │ ├── InstructionLogger.h │ ├── PEInjector.cpp │ ├── PEInjector.h │ ├── VM Project.aps │ ├── VM Project.cpp │ ├── VM Project.h │ ├── VM Project.rc │ ├── VM Project.vcxproj │ ├── VM Project.vcxproj.filters │ ├── VM Project.vcxproj.user │ ├── VM ProjectDlg.cpp │ ├── VM ProjectDlg.h │ ├── VMCompiler.cpp │ ├── VMCompiler.h │ ├── VMHandlerProcessor.cpp │ ├── VMHandlerProcessor.h │ ├── res/ │ │ └── VMProject.rc2 │ ├── resource.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h └── VM Project.sln ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 NIMA Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # x86 Code Virtualizer (Code Obfuscator) Open-source and lite application to obfuscate binary codes and makes challenge for reverse engineers to understand code. Features ------- Protect and obfuscate sensitive area of code using virtual machine protection ( translation of byte-code to PCode and run them inside Virtual Machine ) Project has been writen in Microsoft VC++ & little pure asm code and uses BeaEngine as disassembler engine. It's not enough secure to use in commercial projects so try to learn how it works and make it better. Supported x86 opcodes : Mov,Call,Push,Pop,Jump,Inc,Add,Xor,Cmp,Shl,Shr,Not,Or,Sub,Conditional Jumps. Contact ------- Email : nima.nikjoo@gmail.com Twitter : https://twitter.com/N_Nikjoo LinkedIn : https://www.linkedin.com/in/nimanikjoo/ ___________________ Published under MIT License ================================================ FILE: VM Project/BEAInclude/basic_types.h ================================================ /** * @file basic_types.h * @author * @date Thu Dec 24 19:31:22 2009 * * @brief Definitions of fixed-size integer types for various platforms * * This file is part of BeaEngine. * * BeaEngine is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BeaEngine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with BeaEngine. If not, see . */ #ifndef __BEA_BASIC_TYPES_HPP__ #define __BEA_BASIC_TYPES_HPP__ #include #if defined(__GNUC__) || defined (__INTEL_COMPILER) || defined(__LCC__) #include #endif #if defined(_MSC_VER) /* * Windows/Visual C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed __int64 Int64; typedef unsigned __int64 UInt64; #if defined(_WIN64) #define BEA_PTR_IS_64_BIT 1 typedef signed __int64 IntPtr; typedef unsigned __int64 UIntPtr; #else typedef signed long IntPtr; typedef size_t UIntPtr; #endif #define BEA_HAVE_INT64 1 #elif defined(__GNUC__) || defined(__LCC__) /* * Unix/GCC */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef intptr_t IntPtr; typedef uintptr_t UIntPtr; #if defined(__LP64__) #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 typedef signed long Int64; typedef unsigned long UInt64; #else #if defined (__INTEL_COMPILER) || defined (__ICC) || defined (_ICC) typedef __int64 Int64; typedef unsigned __int64 UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif #endif #define BEA_HAVE_INT64 1 #elif defined(__DECCXX) /* * Compaq C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed __int64 Int64; typedef unsigned __int64 UInt64; #if defined(__VMS) #if defined(__32BITS) typedef signed long IntPtr; typedef unsigned long UIntPtr; #else typedef Int64 IntPtr; typedef UInt64 UIntPtr; #define BEA_PTR_IS_64_BIT 1 #endif #else typedef signed long IntPtr; typedef unsigned long UIntPtr; #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 #endif #define BEA_HAVE_INT64 1 #elif defined(__HP_aCC) /* * HP Ansi C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed long IntPtr; typedef unsigned long UIntPtr; #if defined(__LP64__) #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 typedef signed long Int64; typedef unsigned long UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif #define BEA_HAVE_INT64 1 #elif defined(__SUNPRO_CC) || defined(__SUNPRO_C) /* * SUN Forte C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed long IntPtr; typedef unsigned long UIntPtr; #if defined(__sparcv9) #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 typedef signed long Int64; typedef unsigned long UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif #define BEA_HAVE_INT64 1 #elif defined(__IBMCPP__) /* * IBM XL C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed long IntPtr; typedef unsigned long UIntPtr; #if defined(__64BIT__) #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 typedef signed long Int64; typedef unsigned long UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif #define BEA_HAVE_INT64 1 #elif defined(__BORLANDC__) /* * Borland C/C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef unsigned __int64 Int64; typedef signed __int64 UInt64; typedef unsigned long UIntPtr; #define BEA_HAVE_INT64 1 #elif defined(__WATCOMC__) /* * Watcom C/C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef unsigned __int64 Int64; typedef signed __int64 UInt64; #define BEA_HAVE_INT64 1 typedef size_t UIntPtr; #elif defined(__sgi) /* * MIPSpro C++ */ typedef signed char Int8; typedef unsigned char UInt8; typedef signed short Int16; typedef unsigned short UInt16; typedef signed int Int32; typedef unsigned int UInt32; typedef signed long IntPtr; typedef unsigned long UIntPtr; #if _MIPS_SZLONG == 64 #define BEA_PTR_IS_64_BIT 1 #define BEA_LONG_IS_64_BIT 1 typedef signed long Int64; typedef unsigned long UInt64; #else typedef signed long long Int64; typedef unsigned long long UInt64; #endif #define BEA_HAVE_INT64 1 #endif #if defined(_MSC_VER) || defined(__BORLANDC__) #define W64LIT(x) x##ui64 #else #define W64LIT(x) x##ULL #endif #ifndef C_STATIC_ASSERT #define C_STATIC_ASSERT(tag_name, x) \ typedef int cache_static_assert_ ## tag_name[(x) * 2-1] #endif C_STATIC_ASSERT(sizeof_Int8 , (sizeof(Int8) == 1)); C_STATIC_ASSERT(sizeof_UInt8, (sizeof(UInt8) == 1)); C_STATIC_ASSERT(sizeof_Int16 , (sizeof(Int16) == 2)); C_STATIC_ASSERT(sizeof_UInt16, (sizeof(UInt16) == 2)); C_STATIC_ASSERT(sizeof_Int32 , (sizeof(Int32) == 4)); C_STATIC_ASSERT(sizeof_UInt32, (sizeof(UInt32) == 4)); C_STATIC_ASSERT(sizeof_Int64 , (sizeof(Int64) == 8)); C_STATIC_ASSERT(sizeof_UInt64, (sizeof(UInt64) == 8)); #endif ================================================ FILE: VM Project/BEAInclude/export.h ================================================ /** * @file export.h * @author igor.gutnik@gmail.com * @date Mon Sep 22 09:28:54 2008 * * @brief This file sets things up for C dynamic library function definitions and * static inlined functions * * This file is part of BeaEngine. * * BeaEngine is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * BeaEngine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with BeaEngine. If not, see . */ #ifndef __BEA_EXPORT_H__ #define __BEA_EXPORT_H__ /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus #define CPP_VISIBLE_BEGIN extern "C" { #define CPP_VISIBLE_END } #else #define CPP_VISIBLE_BEGIN #define CPP_VISIBLE_END #endif #if defined(_MSC_VER) #pragma warning( disable: 4251 ) #endif /* Some compilers use a special export keyword */ #ifndef bea__api_export__ # if defined(__BEOS__) # if defined(__GNUC__) # define bea__api_export__ __declspec(dllexport) # else # define bea__api_export__ __declspec(export) # endif # elif defined(_WIN32) || defined(_WIN64) # ifdef __BORLANDC__ # define bea__api_export__ __declspec(dllexport) # define bea__api_import__ __declspec(dllimport) # elif defined(__WATCOMC__) # define bea__api_export__ __declspec(dllexport) # define bea__api_import__ # else # define bea__api_export__ __declspec(dllexport) # define bea__api_import__ __declspec(dllimport) # endif # elif defined(__OS2__) # ifdef __WATCOMC__ # define bea__api_export__ __declspec(dllexport) # define bea__api_import__ # else # define bea__api_export__ # define bea__api_import__ # endif # else # if defined(_WIN32) && defined(__GNUC__) && __GNUC__ >= 4 # define bea__api_export__ __attribubea__ ((visibility("default"))) # define bea__api_import__ __attribubea__ ((visibility("default"))) # else # define bea__api_export__ # define bea__api_import__ # endif # endif #endif /* Use C calling convention by default*/ #ifndef __bea_callspec__ #if defined(BEA_USE_STDCALL) #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_WIN64) #if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(_MSC_VER) || defined(__MINGW32__) || defined(__POCC__) #define __bea_callspec__ __stdcall #else #define __bea_callspec__ #endif #else #ifdef __OS2__ #define __bea_callspec__ _System #else #define __bea_callspec__ #endif #endif #else #define __bea_callspec__ #endif #endif #ifdef __SYMBIAN32__ # ifndef EKA2 # undef bea__api_export__ # undef bea__api_import__ # define bea__api_export__ # define bea__api_import__ # elif !defined(__WINS__) # undef bea__api_export__ # undef bea__api_import__ # define bea__api_export__ __declspec(dllexport) # define bea__api_import__ __declspec(dllexport) # endif /* !EKA2 */ #endif /* __SYMBIAN32__ */ #if defined(__GNUC__) && (__GNUC__ > 2) #define BEA_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) #define BEA_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) #else #define BEA_EXPECT_CONDITIONAL(c) (c) #define BEA_UNEXPECT_CONDITIONAL(c) (c) #endif /* Set up compiler-specific options for inlining functions */ #ifndef BEA_HAS_INLINE #if defined(__GNUC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) #define BEA_HAS_INLINE #else /* Add any special compiler-specific cases here */ #if defined(_MSC_VER) || defined(__BORLANDC__) || \ defined(__DMC__) || defined(__SC__) || \ defined(__WATCOMC__) || defined(__LCC__) || \ defined(__DECC) || defined(__EABI__) #ifndef __inline__ #define __inline__ __inline #endif #define BEA_HAS_INLINE #else #if !defined(__MRC__) && !defined(_SGI_SOURCE) #ifndef __inline__ #define __inline__ inline #endif #define BEA_HAS_INLINE #endif /* Not a funky compiler */ #endif /* Visual C++ */ #endif /* GNU C */ #endif /* CACHE_HAS_INLINE */ /* If inlining isn't supported, remove "__inline__", turning static inlined functions into static functions (resulting in code bloat in all files which include the offending header files) */ #ifndef BEA_HAS_INLINE #define __inline__ #endif /* fix a bug with gcc under windows */ #if defined(__WIN32__) || defined(WIN32) || defined(_WIN32) || defined(_WIN64) #if defined(__MINGW32__) #define const__ #else #define const__ const #endif #else #define const__ const #endif #endif ================================================ FILE: VM Project/BeaEngine.h ================================================ #pragma once /* Header for BeaEngine 4.x */ #ifndef _BEA_ENGINE_ #define _BEA_ENGINE_ #include "BEAInclude/export.h" #include "BEAInclude/basic_types.h" #if !defined(BEA_ENGINE_STATIC) #if defined(BUILD_BEA_ENGINE_DLL) #define BEA_API bea__api_export__ #else #define BEA_API bea__api_import__ #endif #else #define BEA_API #endif #define INSTRUCT_LENGTH 64 #pragma pack(1) typedef struct { UInt8 W_; UInt8 R_; UInt8 X_; UInt8 B_; UInt8 state; } REX_Struct ; #pragma pack() #pragma pack(1) typedef struct { int Number; int NbUndefined; UInt8 LockPrefix; UInt8 OperandSize; UInt8 AddressSize; UInt8 RepnePrefix; UInt8 RepPrefix; UInt8 FSPrefix; UInt8 SSPrefix; UInt8 GSPrefix; UInt8 ESPrefix; UInt8 CSPrefix; UInt8 DSPrefix; UInt8 BranchTaken; UInt8 BranchNotTaken; REX_Struct REX; } PREFIXINFO ; #pragma pack() #pragma pack(1) typedef struct { UInt8 OF_; UInt8 SF_; UInt8 ZF_; UInt8 AF_; UInt8 PF_; UInt8 CF_; UInt8 TF_; UInt8 IF_; UInt8 DF_; UInt8 NT_; UInt8 RF_; UInt8 alignment; } EFLStruct ; #pragma pack() #pragma pack(4) typedef struct { Int32 BaseRegister; Int32 IndexRegister; Int32 Scale; Int64 Displacement; } MEMORYTYPE ; #pragma pack() #pragma pack(1) typedef struct { Int32 Category; Int32 Opcode; char Mnemonic[16]; Int32 BranchType; EFLStruct Flags; UInt64 AddrValue; Int64 Immediat; UInt32 ImplicitModifiedRegs; } INSTRTYPE; #pragma pack() #pragma pack(1) typedef struct { char ArgMnemonic[32]; Int32 ArgType; Int32 ArgSize; Int32 ArgPosition; UInt32 AccessMode; MEMORYTYPE Memory; UInt32 SegmentReg; } ARGTYPE; #pragma pack() #pragma pack(1) typedef struct _Disasm { UIntPtr EIP; UInt64 VirtualAddr; UInt32 SecurityBlock; char CompleteInstr[INSTRUCT_LENGTH]; UInt32 Archi; UInt64 Options; INSTRTYPE Instruction; ARGTYPE Argument1; ARGTYPE Argument2; ARGTYPE Argument3; PREFIXINFO Prefix; UInt32 Reserved_[40]; } DISASM, *PDISASM, *LPDISASM; #pragma pack() #define ESReg 1 #define DSReg 2 #define FSReg 3 #define GSReg 4 #define CSReg 5 #define SSReg 6 #define InvalidPrefix 4 #define SuperfluousPrefix 2 #define NotUsedPrefix 0 #define MandatoryPrefix 8 #define InUsePrefix 1 #define LowPosition 0 #define HighPosition 1 enum INSTRUCTION_TYPE { GENERAL_PURPOSE_INSTRUCTION = 0x10000, FPU_INSTRUCTION = 0x20000, MMX_INSTRUCTION = 0x40000, SSE_INSTRUCTION = 0x80000, SSE2_INSTRUCTION = 0x100000, SSE3_INSTRUCTION = 0x200000, SSSE3_INSTRUCTION = 0x400000, SSE41_INSTRUCTION = 0x800000, SSE42_INSTRUCTION = 0x1000000, SYSTEM_INSTRUCTION = 0x2000000, VM_INSTRUCTION = 0x4000000, UNDOCUMENTED_INSTRUCTION = 0x8000000, AMD_INSTRUCTION = 0x10000000, ILLEGAL_INSTRUCTION = 0x20000000, AES_INSTRUCTION = 0x40000000, CLMUL_INSTRUCTION = (int)0x80000000, DATA_TRANSFER = 0x1, ARITHMETIC_INSTRUCTION, LOGICAL_INSTRUCTION, SHIFT_ROTATE, BIT_UInt8, CONTROL_TRANSFER, STRING_INSTRUCTION, InOutINSTRUCTION, ENTER_LEAVE_INSTRUCTION, FLAG_CONTROL_INSTRUCTION, SEGMENT_REGISTER, MISCELLANEOUS_INSTRUCTION, COMPARISON_INSTRUCTION, LOGARITHMIC_INSTRUCTION, TRIGONOMETRIC_INSTRUCTION, UNSUPPORTED_INSTRUCTION, LOAD_CONSTANTS, FPUCONTROL, STATE_MANAGEMENT, CONVERSION_INSTRUCTION, SHUFFLE_UNPACK, PACKED_SINGLE_PRECISION, SIMD128bits, SIMD64bits, CACHEABILITY_CONTROL, FP_INTEGER_CONVERSION, SPECIALIZED_128bits, SIMD_FP_PACKED, SIMD_FP_HORIZONTAL , AGENT_SYNCHRONISATION, PACKED_ALIGN_RIGHT , PACKED_SIGN, PACKED_BLENDING_INSTRUCTION, PACKED_TEST, PACKED_MINMAX, HORIZONTAL_SEARCH, PACKED_EQUALITY, STREAMING_LOAD, INSERTION_EXTRACTION, DOT_PRODUCT, SAD_INSTRUCTION, ACCELERATOR_INSTRUCTION, /* crc32, popcnt (sse4.2) */ ROUND_INSTRUCTION }; enum EFLAGS_STATES { TE_ = 1, MO_ = 2, RE_ = 4, SE_ = 8, UN_ = 0x10, PR_ = 0x20 }; enum BRANCH_TYPE { JO = 1, JC, JE, JA, JS, JP, JL, JG, JB, JECXZ, JmpType, CallType, RetType, JNO = -1, JNC = -2, JNE = -3, JNA = -4, JNS = -5, JNP = -6, JNL = -7, JNG = -8, JNB = -9 }; enum ARGUMENTS_TYPE { NO_ARGUMENT = 0x10000000, REGISTER_TYPE = 0x20000000, MEMORY_TYPE = 0x40000000, CONSTANT_TYPE = (int)0x80000000, MMX_REG = 0x10000, GENERAL_REG = 0x20000, FPU_REG = 0x40000, SSE_REG = 0x80000, CR_REG = 0x100000, DR_REG = 0x200000, SPECIAL_REG = 0x400000, MEMORY_MANAGEMENT_REG = 0x800000, SEGMENT_REG = 0x1000000, RELATIVE_ = 0x4000000, ABSOLUTE_ = 0x8000000, READ = 0x1, WRITE = 0x2, REG0 = 0x1, REG1 = 0x2, REG2 = 0x4, REG3 = 0x8, REG4 = 0x10, REG5 = 0x20, REG6 = 0x40, REG7 = 0x80, REG8 = 0x100, REG9 = 0x200, REG10 = 0x400, REG11 = 0x800, REG12 = 0x1000, REG13 = 0x2000, REG14 = 0x4000, REG15 = 0x8000 }; enum SPECIAL_INFO { UNKNOWN_OPCODE = -1, OUT_OF_BLOCK = 0, /* === mask = 0xff */ NoTabulation = 0x00000000, Tabulation = 0x00000001, /* === mask = 0xff00 */ MasmSyntax = 0x00000000, GoAsmSyntax = 0x00000100, NasmSyntax = 0x00000200, ATSyntax = 0x00000400, /* === mask = 0xff0000 */ PrefixedNumeral = 0x00010000, SuffixedNumeral = 0x00000000, /* === mask = 0xff000000 */ ShowSegmentRegs = 0x01000000 }; #ifdef __cplusplus extern "C" #endif int __bea_callspec__ Disasm (LPDISASM pDisAsm); BEA_API const__ char* __bea_callspec__ BeaEngineVersion (void); BEA_API const__ char* __bea_callspec__ BeaEngineRevision (void); #endif ================================================ FILE: VM Project/InstructionLogger.cpp ================================================ #include "stdafx.h" #include "InstructionLogger.h" // Just log all translated instructions ... CInstructionLogger::CInstructionLogger(CVMHandlerProcessor &HandlerProcessor):iVMHandler(HandlerProcessor) { LogCount=0; CareCount=0; pOriginalVATable=(PDWORD)malloc(TableMemorySize); pVMVATable=(PDWORD)malloc(TableMemorySize); pMemTable=(PDWORD)malloc(TableMemorySize); pCareTargetAddr=(PDWORD)malloc(TableMemorySize); pCareVMMem=(PDWORD)malloc(TableMemorySize); } CInstructionLogger::~CInstructionLogger(void) { } void CInstructionLogger::Clear() { CareCount=0; LogCount=0; ZeroMemory(pOriginalVATable,TableMemorySize); ZeroMemory(pVMVATable,TableMemorySize); ZeroMemory(pMemTable,TableMemorySize); ZeroMemory(pCareTargetAddr,TableMemorySize); ZeroMemory(pCareVMMem,TableMemorySize); } void CInstructionLogger::AddToLog(DWORD OriginalVirtualAddr,DWORD VMAddr,LPBYTE MemByte) { pOriginalVATable[LogCount]=OriginalVirtualAddr; pVMVATable[LogCount]=VMAddr; pMemTable[LogCount]=(DWORD)MemByte; LogCount++; } void CInstructionLogger::AddToCare(LPBYTE MemVM,DWORD TargetVAddr) { pCareVMMem[CareCount]=(DWORD)MemVM; pCareTargetAddr[CareCount]=TargetVAddr; CareCount++; } LPBYTE CInstructionLogger::GetMemFromVA(DWORD VirtualAddr) { LPBYTE iResult=(LPBYTE)0xFFFFFFFF; for (DWORD i=0;i #define TableMemorySize 0x10000 class CInstructionLogger { private: CVMHandlerProcessor &iVMHandler; public: DWORD LogCount; DWORD CareCount; LPDWORD pOriginalVATable; LPDWORD pVMVATable; LPDWORD pMemTable; LPDWORD pCareVMMem; LPDWORD pCareTargetAddr; void Clear(); void AddToLog(DWORD OriginalVirtualAddr,DWORD VMAddr,LPBYTE MemByte); void AddToCare(LPBYTE MemVM,DWORD TargetVAddr); LPBYTE GetMemFromVA(DWORD VirtualAddr); CInstructionLogger(CVMHandlerProcessor &HandlerProcessor); ~CInstructionLogger(void); void FixCare(); }; ================================================ FILE: VM Project/PEInjector.cpp ================================================ #include "stdafx.h" #include "PEInjector.h" // This Class Used to Read PE data and add some data to it // this data can stored as new section or any thing else CPEInjector::CPEInjector(void) { pPEBytes=0; pOverlay=0; OverlaySize=0; PEFileSize=0; } CPEInjector::~CPEInjector(void) { } void CPEInjector::LoadFile(LPWSTR iFile) { if (pPEBytes) delete[] pPEBytes; if (pOverlay) delete[] pOverlay; HANDLE hFile; DWORD tmp; hFile=CreateFileW(iFile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); PEFileSize=GetFileSize(hFile,0); pPEBytes=(LPBYTE)malloc(PEFileSize); ReadFile(hFile,pPEBytes,PEFileSize,&tmp,0); CloseHandle(hFile); DOSHeader=(PIMAGE_DOS_HEADER)pPEBytes; NTHeader=(PIMAGE_NT_HEADERS)(pPEBytes + DOSHeader->e_lfanew); SectionHeader=(PIMAGE_SECTION_HEADER)((LPBYTE)&(NTHeader->OptionalHeader) + NTHeader->FileHeader.SizeOfOptionalHeader); } DWORD CPEInjector::GetNewSectionVA() { DWORD NewVA; NewVA=SectionHeader[NTHeader->FileHeader.NumberOfSections-1].VirtualAddress + SectionHeader[NTHeader->FileHeader.NumberOfSections-1].Misc.VirtualSize; NewVA=AlignSize(NewVA,NTHeader->OptionalHeader.SectionAlignment); NewVA+=NTHeader->OptionalHeader.ImageBase; return NewVA; } DWORD CPEInjector::GetNewSectionOffset() { DWORD NewOffset; NewOffset=SectionHeader[NTHeader->FileHeader.NumberOfSections-1].PointerToRawData + SectionHeader[NTHeader->FileHeader.NumberOfSections-1].SizeOfRawData; NewOffset=AlignSize(NewOffset,NTHeader->OptionalHeader.FileAlignment); return NewOffset; } void CPEInjector:: AddNewSection(LPBYTE SectionMem,size_t MemSize) { char SectionName[8]=".XVM"; DWORD NewRVA=GetNewSectionVA()-NTHeader->OptionalHeader.ImageBase; DWORD NewOffset=GetNewSectionOffset(); DWORD NewSize=AlignSize(MemSize,NTHeader->OptionalHeader.SectionAlignment); DWORD i=NTHeader->FileHeader.NumberOfSections; SectionHeader[i].Characteristics=0xE00000A0; SectionHeader[i].Misc.VirtualSize=NewSize; SectionHeader[i].SizeOfRawData=NewSize; SectionHeader[i].VirtualAddress=NewRVA; SectionHeader[i].PointerToRawData=NewOffset; CopyMemory(SectionHeader[i].Name,SectionName,8); NTHeader->FileHeader.NumberOfSections++; NTHeader->OptionalHeader.SizeOfImage+=NewSize; NewSectionMem=SectionMem; NewSectionSize=MemSize; } void CPEInjector:: SaveFile(LPSTR destAddr) { HANDLE hFile; DWORD tmp; hFile=CreateFileA(destAddr,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,0,0); WriteFile(hFile,pPEBytes,PEFileSize,&tmp,0); WriteFile(hFile,NewSectionMem,NewSectionSize,&tmp,0); CloseHandle(hFile); } DWORD CPEInjector:: AlignSize(DWORD dwSize, DWORD dwAlign) { return (dwSize + (dwAlign - ((dwSize % dwAlign) ? (dwSize % dwAlign) : dwAlign))); } DWORD CPEInjector::FindSectionNum(DWORD VA) { VA-=NTHeader->OptionalHeader.ImageBase; for (int i=0;iFileHeader.NumberOfSections;i++) { if (VA>=SectionHeader[i].VirtualAddress && VA<(SectionHeader[i].VirtualAddress + SectionHeader[i].Misc.VirtualSize)) return i; } return -1; } DWORD CPEInjector::V2O(DWORD VA) { int i=FindSectionNum(VA); if (i!=-1) { VA-=NTHeader->OptionalHeader.ImageBase; VA-=SectionHeader[i].VirtualAddress; VA+=SectionHeader[i].PointerToRawData; return VA; } return -1; } ================================================ FILE: VM Project/PEInjector.h ================================================ #pragma once #include #include using namespace std; class CPEInjector { public: LPWSTR strFileName; CPEInjector(void); ~CPEInjector(void); void LoadFile(LPWSTR); DWORD GetNewSectionVA(); DWORD GetNewSectionOffset(); void AddNewSection(LPBYTE,size_t Size); DWORD AlignSize(DWORD,DWORD); void SaveFile(LPSTR); DWORD FindSectionNum(DWORD VA); DWORD V2O(DWORD VA); LPBYTE pPEBytes; size_t PEFileSize; LPBYTE pOverlay; size_t OverlaySize; LPBYTE NewSectionMem; size_t NewSectionSize; PIMAGE_DOS_HEADER DOSHeader; PIMAGE_NT_HEADERS NTHeader; PIMAGE_SECTION_HEADER SectionHeader; }; ================================================ FILE: VM Project/VM Project.cpp ================================================ // VM Project.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "VM Project.h" #include "VM ProjectDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CVMProjectApp BEGIN_MESSAGE_MAP(CVMProjectApp, CWinApp) ON_COMMAND(ID_HELP, &CWinApp::OnHelp) END_MESSAGE_MAP() // CVMProjectApp construction CVMProjectApp::CVMProjectApp() { // support Restart Manager m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; // TODO: add construction code here, // Place all significant initialization in InitInstance } // The one and only CVMProjectApp object CVMProjectApp theApp; // CVMProjectApp initialization BOOL CVMProjectApp::InitInstance() { // InitCommonControlsEx() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // Set this to include all the common control classes you want to use // in your application. InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); // Create the shell manager, in case the dialog contains // any shell tree view or shell list view controls. CShellManager *pShellManager = new CShellManager; // Activate "Windows Native" visual manager for enabling themes in MFC controls CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO: You should modify this string to be something appropriate // such as the name of your company or organization SetRegistryKey(_T("Local AppWizard-Generated Applications")); CVMProjectDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } else if (nResponse == -1) { TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n"); TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n"); } // Delete the shell manager created above. if (pShellManager != NULL) { delete pShellManager; } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } ================================================ FILE: VM Project/VM Project.h ================================================ // VM Project.h : main header file for the PROJECT_NAME application // #pragma once #ifndef __AFXWIN_H__ #error "include 'stdafx.h' before including this file for PCH" #endif #include "resource.h" // main symbols // CVMProjectApp: // See VM Project.cpp for the implementation of this class // class CVMProjectApp : public CWinApp { public: CVMProjectApp(); // Overrides public: virtual BOOL InitInstance(); // Implementation DECLARE_MESSAGE_MAP() }; extern CVMProjectApp theApp; ================================================ FILE: VM Project/VM Project.vcxproj ================================================  Debug Win32 Release Win32 {50DC5327-0CAD-4787-B236-F3B0127AA8A9} VMProject MFCProj Application true v110 Unicode Static Application false v110 true Unicode Static true false Use Level3 Disabled WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) true StdCall Windows true false true BEAENGINE.lib CRT.lib false true _DEBUG;%(PreprocessorDefinitions) 0x0409 _DEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Level3 Use MaxSpeed true true WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) true StdCall Windows true true true BEAENGINE.lib CRT.lib false false true NDEBUG;%(PreprocessorDefinitions) 0x0409 NDEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Create Create ================================================ FILE: VM Project/VM Project.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Resource Files Resource Files ================================================ FILE: VM Project/VM Project.vcxproj.user ================================================  NativeOnly ================================================ FILE: VM Project/VM ProjectDlg.cpp ================================================ // VM ProjectDlg.cpp : implementation file // #include "stdafx.h" #include "VM Project.h" #include "VM ProjectDlg.h" #include "afxdialogex.h" #include "PEInjector.h" #include "VMHandlerProcessor.h" #include "BeaEngine.h" #include "VMCompiler.h" CPEInjector InjectionEngine; CVMHandlerProcessor VMHProcessor; CVMCompiler iVMCompiler(VMHProcessor); #ifdef _DEBUG #define new DEBUG_NEW #endif // CVMProjectDlg dialog CVMProjectDlg::CVMProjectDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CVMProjectDlg::IDD, pParent) , txtLog(_T("")) , strVAStart(_T("")) , strVAEnd(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CVMProjectDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_Log, txtLog); DDX_Text(pDX, IDC_VAStart, strVAStart); DDX_Text(pDX, IDC_VAeND, strVAEnd); } BEGIN_MESSAGE_MAP(CVMProjectDlg, CDialogEx) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_SelectFile, &CVMProjectDlg::OnBnClickedSelectfile) ON_BN_CLICKED(IDC_DoVirtualize, &CVMProjectDlg::OnBnClickedDovirtualize) ON_BN_CLICKED(IDC_Exit, &CVMProjectDlg::OnBnClickedExit) END_MESSAGE_MAP() // CVMProjectDlg message handlers BOOL CVMProjectDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here strVAStart="0x"; strVAEnd="0x"; UpdateData(false); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CVMProjectDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CVMProjectDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } void CVMProjectDlg::OnBnClickedSelectfile() { // Select Standard PE File and read some information from it .... // Read OEP , NumberOfSections and Section Names UpdateData(true); OPENFILENAMEW op; CFileDialog* ofd = new CFileDialog(TRUE, NULL, NULL, OFN_FILEMUSTEXIST| OFN_HIDEREADONLY , _T("Executable Files (*.exe)|*.exe|Dynamic-Link Libraries (*.dll)|*.dll|All Files (*.*)|*.*||"), NULL, 0); if(ofd->DoModal() == IDOK) { op = ofd->GetOFN(); InjectionEngine.strFileName=op.lpstrFile; InjectionEngine.LoadFile(op.lpstrFile); txtLog=""; AddLog("OEP: ",false); AddLog(InjectionEngine.NTHeader->OptionalHeader.ImageBase + InjectionEngine.NTHeader->OptionalHeader.AddressOfEntryPoint,true); AddLog("Number Of Section: ",false); AddLog(InjectionEngine.NTHeader->FileHeader.NumberOfSections,true); for (int i=0;iFileHeader.NumberOfSections;i++) { AddLog("------->",false); AddLog((LPSTR)InjectionEngine.SectionHeader[i].Name,true); } } } void CVMProjectDlg::AddLog(LPWSTR iLine,bool GoNextLine) { // Add text log to memo object txtLog+=(iLine); if (GoNextLine) txtLog+=(L"\r\n"); UpdateData(0); } void CVMProjectDlg::AddLog(LPSTR iLine,bool GoNextLine) { // Add text log to memo object txtLog+=(iLine); if (GoNextLine) txtLog+=("\r\n"); UpdateData(0); } void CVMProjectDlg::AddLog(DWORD iNUM,bool GoNextLine) { // Add text log to memo object char iLine[12]; wsprintfA(iLine,"%08X",iNUM); //CharUpperA(iLine); txtLog+=(iLine); if (GoNextLine) txtLog+=("\r\n"); UpdateData(0); } void CVMProjectDlg::OnBnClickedDovirtualize() { // Start of Virtualization Routine if (InjectionEngine.strFileName == LPWSTR (NULL) ) { MessageBoxA(0,"Can't Open Target File.","Error", MB_OK && MB_ICONERROR); return; } // New Section information (.VM Section) const DWORD SectionSize=0x10000; BYTE tmpBytes[16]; LPBYTE NewSection=(LPBYTE)VirtualAlloc(0,SectionSize,0x3000,0x40); ZeroMemory(NewSection,SectionSize); DWORD NewSectionVA=InjectionEngine.GetNewSectionVA(); DWORD iCaveVA=NewSectionVA; LPBYTE iCaveMem=NewSection; // Add new empty section to file InjectionEngine.AddNewSection(NewSection,SectionSize); UpdateData(true); DWORD VAStart=wcstol(strVAStart.GetBuffer(), NULL, 16); DWORD VAEnd=wcstol(strVAEnd.GetBuffer(), NULL, 16);; DWORD iVA=VAStart; LPBYTE iCode=InjectionEngine.pPEBytes + InjectionEngine.V2O(iVA); DISASM iDiASM; int iSize; ZeroMemory(&iDiASM,sizeof(DISASM)); iDiASM.VirtualAddr=iVA; iDiASM.EIP=(uintptr_t)iCode; // Get Virtual Addresses iVMCompiler.VAStart=VAStart; iVMCompiler.VAEnd=VAEnd; iVMCompiler.VMOpcodeBase=NewSectionVA; while (iVAAddToLog(Addr,VMOpcodeBase+UsedSize,&OpcodeTable[UsedSize]); //------0:CALL Imm //------1: x86 bool bHandled=false; AddressTable[AddressTableCount][0]=Addr; AddressTable[AddressTableCount][1]=UsedSize; LPBYTE iOpcode=&OpcodeTable[UsedSize]; DWORD iVMOpcode=VMOpcodeBase+UsedSize; DWORD tmp; DWORD T1=0; DWORD T2=0; switch (Opcode[0]) { case 0xE8: iOpcode[0]=iVMHandler.GetHandlerIndex(VM_CALL); tmp=*(LPDWORD(&Opcode[1])) + Addr + 5; *(LPDWORD(&iOpcode[1]))=tmp; UsedSize+=5; break; case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x7C: case 0x7D: case 0x7E: case 0x7F: case 0xEB: T1=iDiASM.Instruction.AddrValue; Process_JCC(Opcode,T1); break; case 0x68: tmp=*(LPDWORD(&Opcode[1])); Compile_PUSH_Imm32(tmp); break; case 0x6A: tmp=*(LPDWORD(&Opcode[1])); tmp&=0xFF; __asm { push eax mov eax,tmp movsx eax,al mov tmp,eax pop eax } Compile_PUSH_Imm32(tmp); break; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: ProcessPUSHR32(Opcode[0]); break; case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F: ProcessPOPR32(Opcode[0]); break; //------------------------------ default: if ((Opcode[0]==0xF && (Opcode[1]==0x82 || Opcode[1]==0x83 || Opcode[1]==0x84 || Opcode[1]==0x85 || Opcode[1]==0x86 || Opcode[1]==0x87|| Opcode[1]==0x8C || Opcode[1]==0x8D ||Opcode[1]==0x8E || Opcode[1]==0x8F)) || Opcode[0]==0xE9) { T1=iDiASM.Instruction.AddrValue; Process_JCC(Opcode,T1); } else if ((Opcode[0]==0x89 || Opcode[0]==0x8B) && Opcode[1]>=0xC0 && Opcode[1]<=0xFF ) { ProcessMOVR32R32(Opcode); } else if ((Opcode[0]==0x81 || Opcode[0]==0x83) && Opcode[1]>=0xC0 && Opcode[1]<0xC8 ) { ProcessADDR32_Imm(Opcode); } else if (Opcode[0]>=0x40 && Opcode[0]<0x50) { ProcessINC_DECR32(Opcode); } else if ((Opcode[0]==0x81 || Opcode[0]==0x83) && Opcode[1]>=0xE8 && Opcode[1]<0xF0 ) { ProcessSUBR32_Imm(Opcode); } else if (Opcode[0]==0x89 &&Opcode[1]>=0x40 && Opcode[1]<0x80 ) { ProcessMOV_MemR32Imm8_R32(Opcode); } else if (Opcode[0]==0x89 &&Opcode[1]>=0x40 && Opcode[1]<0xC0 ) { ProcessMOV_MemR32Imm32_R32(Opcode); } else if (Opcode[0]==0xC7 &&Opcode[1]>=0x80 && Opcode[1]<0x88 ) { ProcessMOV_MemR32Imm32_Imm32(Opcode); } else if (Opcode[0]==0x8B &&Opcode[1]>=0x80 && Opcode[1]<0xC0 ) { ProcessMOV_R32_MemR32Imm32(Opcode); } else if (Opcode[0]==0x8B &&Opcode[1]>=0x40 && Opcode[1]<0x80 ) { ProcessMOV_R32_MemR32Imm8(Opcode); } else if (Opcode[0]==0x8D && Opcode[1]>=0x80 && Opcode[1]<0xC0 ) { ProcessLEA_R32_MemR32Imm32(Opcode); } else if ((Opcode[0]==0x33 || Opcode[0]==0x31) && Opcode[1]>=0xC0 && Opcode[1]<=0xFF ) { ProcessXORR32_R32(Opcode); } else if (Opcode[0]>=0xB8 && Opcode[0]<=0xBF) { ProcessMOVR32_Imm(Opcode); } else if (Opcode[0]==0xA1 || ((Opcode[0]==0x8B) && (Opcode[1]==0xD || Opcode[1]==0x15 || Opcode[1]==0x1D || Opcode[1]==0x25 || Opcode[1]==0x2D || Opcode[1]==0x35 || Opcode[1]==0x3D ))) { ProcessMOVR32_MemImm(Opcode); } else if (Opcode[0]==0xA3 || ((Opcode[0]==0x89) && (Opcode[1]==0xD || Opcode[1]==0x15 || Opcode[1]==0x1D || Opcode[1]==0x25 || Opcode[1]==0x2D || Opcode[1]==0x35 || Opcode[1]==0x3D ))) { ProcessMOVMemImm_R32(Opcode); } else if (Opcode[0]==0x25 || ((Opcode[0]==0x81) && Opcode[1]>=0xE0 && Opcode[1]<0xE8 )) { ProcessANDR32_Imm(Opcode); } else if (Opcode[0]==0xD || ((Opcode[0]==0x83 || Opcode[0]==0x81) && Opcode[1]>=0xC8 && Opcode[1]<0xD0 )) { ProcessORR32_Imm(Opcode); } else if (Opcode[0]==0x3D || ((Opcode[0]==0x83 || Opcode[0]==0x81) && Opcode[1]>=0xF8 && Opcode[1]<=0xFF )) { ProcessCMPR32_Imm(Opcode); } else if (Opcode[0]==0xC1 && Opcode[1]>=0xE0 && Opcode[1]<0xE8 ) { ProcessSHLR32_Imm(Opcode); } else if (Opcode[0]==0xC1 && Opcode[1]>=0xE8 && Opcode[1]<0xF0 ) { ProcessSHRR32_Imm(Opcode); } else if (Opcode[0]==0xF7 && Opcode[1]>=0xD0 && Opcode[1]<0xD8) { ProcessNOTR32(Opcode); } else { iOpcode[0]=iVMHandler.GetHandlerIndex(VM_X86); iOpcode[1]=iSize; CopyMemory(&iOpcode[2],Opcode,iSize); UsedSize+=iSize+2; } break; } } void CVMCompiler::Finalize() { InstructionLog->FixCare(); } void CVMCompiler::Compile_PUSH_Imm32(DWORD Imm) { // Generate VM Opcode of "Push" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_PUSHImmDW); *(LPDWORD(&OpcodeTable[UsedSize+1]))=Imm; UsedSize+=5; } void CVMCompiler::Compile_PUSH_R32(unsigned int RegisterOffset) { // Generate VM Opcode of "Push Register" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_PUSHR32); OpcodeTable[UsedSize+1]=RegisterOffset; UsedSize+=2; } void CVMCompiler::Compile_POP_R32(unsigned int RegisterOffset) { // Generate VM Opcode of "POP" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_POPR32); OpcodeTable[UsedSize+1]=RegisterOffset; UsedSize+=2; } void CVMCompiler::Compile_AND_32() { // Generate VM Opcode of "AND" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_AND32); UsedSize++; } void CVMCompiler::Compile_NOT_32() { // Generate VM Opcode of "NOT" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_NOT32); UsedSize++; } void CVMCompiler::Compile_SHL_32() { // Generate VM Opcode of "SHL" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SHL32); UsedSize++; } void CVMCompiler::Compile_SHR_32() { // Generate VM Opcode of "SHR" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SHR32); UsedSize++; } void CVMCompiler::Compile_JCCIn() { // Generate VM Opcode of "JCC" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_JCCIn); UsedSize++; } void CVMCompiler::Compile_ADD_32() { // Generate VM Opcode of "ADD" OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_ADD32); UsedSize++; } void CVMCompiler::Compile_OR_32() { // Generate VM Opcode of "OR" Compile_NOT_32(); Compile_POP_R32(0x24); Compile_NOT_32(); Compile_AND_32(); Compile_POP_R32(0x28); Compile_NOT_32(); Compile_POP_R32(0x24); Compile_PUSH_R32(0x24); Compile_PUSH_R32(0x24); Compile_AND_32(); } void CVMCompiler::Compile_CMP_32() { // Generate VM Opcode of "CMP" Compile_SUB_32(); Compile_POP_R32(0x24); Compile_POP_R32(0x28); Compile_PUSH_R32(0x24); } void CVMCompiler::Compile_SUB_32() { // Generate VM Opcode of "SUB" Compile_NOT_32(); Compile_PUSH_Imm32(1); Compile_ADD_32(); Compile_POP_R32(0x24); Compile_ADD_32(); } void CVMCompiler::Compile_NOTBit() { // Generate VM Opcode of "NOT" Bit Compile_PUSH_Imm32(1); Compile_ADD_32(); Compile_POP_R32(0x28); Compile_PUSH_Imm32(1); Compile_AND_32(); Compile_POP_R32(0x28); } void CVMCompiler::Compile_GetDWORDDS() { // Generate VM Opcode of "GetDWORDS" (all type of opcodes that get DWORD data) OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_GetDWORDDS); UsedSize++; } void CVMCompiler::Compile_SetDWORDDS() { // Generate VM Opcode of "GetDWORDS" (all type of opcodes that set DWORD data) OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SetDWORDDS); UsedSize++; } void CVMCompiler::Process_JCC(LPBYTE Opcode,DWORD Dest) { // Generate VM Opcode of "JCC" DWORD *dwNext; if (Dest>=VAStart && DestAddToCare((LPBYTE)(OpcodeTable+UsedSize),Dest); Compile_PUSH_Imm32(Dest); dwNext=(LPDWORD)&OpcodeTable[UsedSize+1]; Compile_PUSH_Imm32(0); if (Opcode[0]==0xEB || Opcode[0]==0xE9) { Compile_PUSH_Imm32(1); Compile_JCCIn(); } else if (Opcode[0]==0x77 || Opcode[0]==0x76 || (Opcode[0]==0xF && (Opcode[1]==0x87 || Opcode[1]==0x86))) { Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(1); Compile_AND_32(); Compile_POP_R32(0x24); Compile_NOTBit(); Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x40); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_R32(6); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_NOTBit(); Compile_AND_32(); Compile_POP_R32(0x24); if (Opcode[0]==0x76 || (Opcode[0]==0xF && Opcode[1]==0x86)) Compile_NOTBit(); Compile_JCCIn(); *dwNext=VMOpcodeBase+UsedSize; } else if (Opcode[0]==0x75 || Opcode[0]==0x74 || (Opcode[0]==0xF && (Opcode[1]==0x84 ||Opcode[1]==0x85 )) ) { Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x40); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(6); Compile_SHR_32(); Compile_POP_R32(0x24); if (Opcode[0]==0x75 || (Opcode[0]==0xF && Opcode[1]==0x85)) //NOT Compile_NOTBit(); Compile_JCCIn(); *dwNext=VMOpcodeBase+UsedSize; } else if (Opcode[0]==0x72 || Opcode[0]==0x73 || (Opcode[0]==0xF && (Opcode[1]==0x82 ||Opcode[1]==0x83 )) ) { Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(1); Compile_AND_32(); Compile_POP_R32(0x24); if (Opcode[0]==0x73 || (Opcode[0]==0xF && Opcode[1]==0x83)) Compile_NOTBit(); Compile_JCCIn(); *dwNext=VMOpcodeBase+UsedSize; } else if (Opcode[0]==0x7E || Opcode[0]==0x7F || (Opcode[0]==0xF && (Opcode[1]==0x8E ||Opcode[1]==0x8F )) ) { Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x40); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(6); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_NOTBit(); Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x800); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(11); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x80); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(7); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_CMP_32(); Compile_PUSH_Imm32(0x40); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(6); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_AND_32(); Compile_POP_R32(0x24); if (Opcode[0]==0x7E || (Opcode[0]==0xF && Opcode[1]==0x8E)) Compile_NOTBit(); Compile_JCCIn(); *dwNext=VMOpcodeBase+UsedSize; } else if (Opcode[0]==0x7C || Opcode[0]==0x7D || (Opcode[0]==0xF && (Opcode[1]==0x8C ||Opcode[1]==0x8D )) ) { Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x800); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(11); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_PUSH_R32(0x20); Compile_PUSH_Imm32(0x80); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(7); Compile_SHR_32(); Compile_POP_R32(0x24); Compile_CMP_32(); Compile_PUSH_Imm32(0x40); Compile_AND_32(); Compile_POP_R32(0x24); Compile_PUSH_Imm32(6); Compile_SHR_32(); Compile_POP_R32(0x24); if (Opcode[0]==0x7C || (Opcode[0]==0xF && Opcode[1]==0x8C)) Compile_NOTBit(); Compile_JCCIn(); *dwNext=VMOpcodeBase+UsedSize; } } else { } } void CVMCompiler::ProcessPUSHR32(BYTE iOpcode) { // Generate VM Opcode of "Push Register" if (iOpcode!=0x54) Compile_PUSH_R32(0x1C - (iOpcode-0x50)*4); else { OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_PUSHESP); UsedSize++; Compile_PUSH_Imm32(4); Compile_ADD_32(); Compile_POP_R32(0x30); } } void CVMCompiler::ProcessPOPR32(BYTE iOpcode) { // Generate VM Opcode of "POP Register" if (iOpcode!=0x5C) Compile_POP_R32(0x1C - (iOpcode-0x58)*4); else { OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_POPESP); UsedSize++; } } void CVMCompiler::ProcessMOVR32R32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Register/Register" int rDEST; int rSRC; if (iOpcode[0]==0x89) { rDEST=(iOpcode[1]-0xC0)%8; rSRC=(iOpcode[1]-0xC0)/8; } else { rSRC=(iOpcode[1]-0xC0)%8; rDEST=(iOpcode[1]-0xC0)/8; } ProcessPUSHR32(0x50+rSRC); ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessADDR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "Add Register/Register" if (iOpcode[0]!=0x81 && iOpcode[0]!=0x83) return ; DWORD dwImm=*(LPDWORD)(&iOpcode[2]); if (iOpcode[0]==0x83) { __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } } int rDEST=iOpcode[1]-0xC0; ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x20); ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessSUBR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "SUB" if (iOpcode[0]!=0x81 && iOpcode[0]!=0x83) return ; long dwImm=*(LPLONG)(&iOpcode[2]); if (iOpcode[0]==0x83) { __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } } dwImm=dwImm*-1; int rDEST=iOpcode[1]-0xE8; ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x20); ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessMOV_MemR32Imm8_R32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Register/Memory" DWORD dwImm; int rSRC; int rDEST; if ((iOpcode[1]-0x44)%8==4) { dwImm=*(LPDWORD)(&iOpcode[2]); __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } rSRC=(iOpcode[1]-0x40)/8; rDEST=(iOpcode[1]-0x40)%8; } else { dwImm=*(LPDWORD)(&iOpcode[3]); __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } rSRC=(iOpcode[1]-0x44)/8;; if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rDEST=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rDEST=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rDEST=0xE0; rDEST=(iOpcode[2]-rDEST)%8; } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); ProcessPUSHR32(0x50 + rSRC); if (rSRC==4)//SRC ESP { Compile_PUSH_Imm32(4); Compile_ADD_32(); Compile_POP_R32(0x30); } OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SetDWORDDS); UsedSize++; } void CVMCompiler::ProcessMOV_MemR32Imm32_R32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Memory/Register" DWORD dwImm; int rSRC; int rDEST; if ((iOpcode[1]-0x80)%8!=4) { dwImm=*(LPDWORD)(&iOpcode[2]); rSRC=(iOpcode[1]-0x80)/8; rDEST=(iOpcode[1]-0x80)%8; } else { dwImm=*(LPDWORD)(&iOpcode[3]); rSRC=(iOpcode[1]-0x84)/8; if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rDEST=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rDEST=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rDEST=0xE0; rDEST=(iOpcode[2]-rDEST)%8; } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); ProcessPUSHR32(0x50 + rSRC); if (rSRC==4)//SRC ESP { Compile_PUSH_Imm32(4); Compile_ADD_32(); Compile_POP_R32(0x30); } OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SetDWORDDS); UsedSize++; } void CVMCompiler::ProcessMOV_MemR32Imm32_Imm32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Memory/Memory" DWORD dwSRCImm; DWORD dwDestImm; int rDEST; if ((iOpcode[1]-0x80)%8!=4) { dwDestImm=*(LPDWORD)(&iOpcode[2]); dwSRCImm=*(LPDWORD)(&iOpcode[6]); rDEST=(iOpcode[1]-0x80)%8; } else { dwDestImm=*(LPDWORD)(&iOpcode[3]); dwSRCImm=*(LPDWORD)(&iOpcode[7]); if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rDEST=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rDEST=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rDEST=0xE0; rDEST=(iOpcode[2]-rDEST)%8; } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwDestImm); Compile_ADD_32(); Compile_POP_R32(0x30); Compile_PUSH_Imm32(dwSRCImm); OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_SetDWORDDS); UsedSize++; } void CVMCompiler::ProcessMOV_R32_MemR32Imm32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Mem32/Register32" DWORD dwImm; int rSRC; int rDEST; if ((iOpcode[1]-0x80)%8!=4) { dwImm=*(LPDWORD)(&iOpcode[2]); rDEST=(iOpcode[1]-0x80)/8; rSRC=(iOpcode[1]-0x80)%8; } else { dwImm=*(LPDWORD)(&iOpcode[3]); rDEST=(iOpcode[1]-0x84)/8; if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rSRC=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rSRC=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rSRC=0xE0; rSRC=(iOpcode[2]-rSRC)%8; } ProcessPUSHR32(0x50 + rSRC); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_GetDWORDDS); UsedSize++; ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessMOV_R32_MemR32Imm8(LPBYTE iOpcode) { // Generate VM Opcode of "Memory / DWORD Memory" DWORD dwImm; int rSRC; int rDEST; if ((iOpcode[1]-0x40)%8!=4) { dwImm=*(LPDWORD)(&iOpcode[2]); rDEST=(iOpcode[1]-0x40)/8; rSRC=(iOpcode[1]-0x40)%8; } else { dwImm=*(LPDWORD)(&iOpcode[3]); rDEST=(iOpcode[1]-0x44)/8; if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rSRC=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rSRC=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rSRC=0xE0; rSRC=(iOpcode[2]-rSRC)%8; } __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } ProcessPUSHR32(0x50 + rSRC); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); OpcodeTable[UsedSize]=iVMHandler.GetHandlerIndex(VM_GetDWORDDS); UsedSize++; ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessLEA_R32_MemR32Imm32(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Mem/16 bit Register" DWORD dwImm; int rSRC; int rDEST; if ((iOpcode[1]-0x80)%8!=4) { dwImm=*(LPDWORD)(&iOpcode[2]); rDEST=(iOpcode[1]-0x80)/8; rSRC=(iOpcode[1]-0x80)%8; } else { dwImm=*(LPDWORD)(&iOpcode[3]); rDEST=(iOpcode[1]-0x84)/8; if (iOpcode[2]>=0x20 && iOpcode[2]<0x28) rSRC=0x20; else if (iOpcode[2]>=0x60 && iOpcode[2]<0x68) rSRC=0x60; else if (iOpcode[2]>=0xE0 && iOpcode[2]<0xE8) rSRC=0xE0; rSRC=(iOpcode[2]-rSRC)%8; } ProcessPUSHR32(0x50 + rSRC); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessXORR32_R32(LPBYTE iOpcode) { // Generate VM Opcode of "XOR" if (iOpcode[0]!=0x33 && iOpcode[0]!=0x31 ) return; int rSRC=(iOpcode[1]-0xC0)/8; int rDEST=(iOpcode[1]-0xC0)%8; ProcessPUSHR32(0x50+rSRC); ProcessPUSHR32(0x50+rDEST); Compile_NOT_32(); Compile_AND_32(); Compile_POP_R32(0x30); ProcessPUSHR32(0x50+rDEST); ProcessPUSHR32(0x50+rSRC); Compile_NOT_32(); Compile_AND_32(); Compile_POP_R32(0x30); Compile_ADD_32(); Compile_POP_R32(0x30); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessMOVR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Register16/Register16" (16 means 16 bit) if (iOpcode[0]<0xB8 || iOpcode[0]>0xBF) return; DWORD dwImm=*(LPDWORD)(&iOpcode[1]); Compile_PUSH_Imm32(dwImm); ProcessPOPR32(0x58 + iOpcode[0] - 0xB8); } void CVMCompiler::ProcessMOVR32_MemImm(LPBYTE iOpcode) { // Generate VM Opcode of "Mov Register16/memory16" (16 means 16 bit) DWORD dwImm; int rDEST; if (iOpcode[0]==0xA1) { dwImm=*(LPDWORD)(&iOpcode[1]); rDEST=0; } else { dwImm=*(LPDWORD)(&iOpcode[2]); rDEST=(iOpcode[1]-0xD)/8 + 1; } Compile_PUSH_Imm32(dwImm); Compile_GetDWORDDS(); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessMOVMemImm_R32(LPBYTE iOpcode) { DWORD dwImm; int rSRC; if (iOpcode[0]==0xA3) { dwImm=*(LPDWORD)(&iOpcode[1]); rSRC=0; } else { dwImm=*(LPDWORD)(&iOpcode[2]); rSRC=(iOpcode[1]-0xD)/8 + 1; } Compile_PUSH_Imm32(dwImm); ProcessPUSHR32(0x50+rSRC); Compile_SetDWORDDS(); } void CVMCompiler::ProcessANDR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "AND Register" DWORD dwImm; int rDEST; if (iOpcode[0]==0x25) { dwImm=*(LPDWORD)(&iOpcode[1]); rDEST=0; } else { dwImm=*(LPDWORD)(&iOpcode[2]); rDEST=(iOpcode[1]-0xE0); } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_AND_32(); Compile_POP_R32(0x30); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessORR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "OR Register/memory" DWORD dwImm; int rDEST; if (iOpcode[0]==0xD) { dwImm=*(LPDWORD)(&iOpcode[1]); rDEST=0; } else { dwImm=*(LPDWORD)(&iOpcode[2]); if (iOpcode[0]==0x83) { __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } } rDEST=(iOpcode[1]-0xC8); } ProcessPUSHR32(0x50 + rDEST); Compile_NOT_32(); Compile_PUSH_Imm32(dwImm^0xFFFFFFFF); Compile_AND_32(); Compile_POP_R32(0x30); Compile_NOT_32(); Compile_PUSH_Imm32(0xFFFFFFFF); Compile_AND_32(); Compile_POP_R32(0x20); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessSHLR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "SHL Register - memory" int rDEST=iOpcode[1]-0xE0; DWORD dwImm; __asm { push eax mov eax,iOpcode movzx eax,byte ptr ds:[eax+2] mov dwImm,eax pop eax } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_SHL_32(); Compile_POP_R32(0x30); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessSHRR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "SHR Register - memory" int rDEST=iOpcode[1]-0xE8; DWORD dwImm; __asm { push eax mov eax,iOpcode movzx eax,byte ptr ds:[eax+2] mov dwImm,eax pop eax } ProcessPUSHR32(0x50 + rDEST); Compile_PUSH_Imm32(dwImm); Compile_SHR_32(); Compile_POP_R32(0x30); ProcessPOPR32(0x58 + rDEST); } void CVMCompiler::ProcessNOTR32(LPBYTE iOpcode) { // Generate VM Opcode of "NOT Register" int rDEST=iOpcode[1]-0xD0; ProcessPUSHR32(0x50+rDEST); Compile_NOT_32(); ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessINC_DECR32(LPBYTE iOpcode) { // Generate VM Opcode of "DEC Register" int rDEST; int dwAdd; if (iOpcode[0]<0x48) { dwAdd=1; rDEST=iOpcode[0]-0x40; } else { dwAdd=0xFFFFFFFF; rDEST=iOpcode[0]-0x48; } ProcessPUSHR32(0x50+rDEST); Compile_PUSH_Imm32(dwAdd); Compile_ADD_32(); Compile_POP_R32(0x20); ProcessPOPR32(0x58+rDEST); } void CVMCompiler::ProcessCMPR32_Imm(LPBYTE iOpcode) { // Generate VM Opcode of "CMP Register - Memory" if (iOpcode[0]!=0x81 && iOpcode[0]!=0x83 && iOpcode[0]!=0x3D) return ; DWORD dwImm; int rDEST=0; if (iOpcode[0]!=0x3D) { rDEST=iOpcode[1]-0xF8; dwImm=*(LPDWORD)(&iOpcode[2]); if (iOpcode[0]==0x83) { __asm { push eax mov eax,dwImm movsx eax,al mov dwImm,eax pop eax } } } else dwImm=*(LPDWORD)(&iOpcode[1]); // Finalize ... ProcessPUSHR32(0x50 + rDEST); Compile_NOT_32(); Compile_PUSH_Imm32(dwImm); Compile_ADD_32(); Compile_POP_R32(0x30); Compile_PUSH_R32(0x30); Compile_PUSH_Imm32(0x815); Compile_AND_32(); Compile_POP_R32(0x34); Compile_POP_R32(0x38); Compile_NOT_32(); Compile_POP_R32(0x34); Compile_PUSH_R32(0x34); Compile_PUSH_R32(0x34); Compile_AND_32(); Compile_PUSH_Imm32(0x815); Compile_NOT_32(); Compile_AND_32(); Compile_POP_R32(0x30); Compile_PUSH_R32(0x38); Compile_ADD_32(); Compile_POP_R32(0x20); Compile_POP_R32(0x20); Compile_POP_R32(0x30); } ================================================ FILE: VM Project/VMCompiler.h ================================================ #pragma once #include "VMHandlerProcessor.h" #include "BeaEngine.h" class CVMCompiler { private: CVMHandlerProcessor &iVMHandler; public: DWORD VAStart; DWORD VAEnd; DWORD VMOpcodeBase; LPBYTE OpcodeTable; DWORD UsedSize; DWORD AddressTable[1000][2]; DWORD AddressTableCount; void Finalize(); void CompileNow(DWORD,LPBYTE,DWORD,DISASM&); //------------------------------ void Compile_PUSH_R32(unsigned int RegisterOffset); void Compile_POP_R32(unsigned int RegisterOffset); void Compile_PUSH_Imm32(DWORD Imm); void Compile_AND_32(); void Compile_NOT_32(); void Compile_JCCIn(); void Compile_SHR_32(); void Compile_SHL_32(); void Compile_ADD_32(); void Compile_OR_32(); void Compile_CMP_32(); void Compile_SUB_32(); void Compile_GetDWORDDS(); void Compile_SetDWORDDS(); void Compile_NOTBit(); void Process_JCC(LPBYTE Opcode,DWORD Dest); void ProcessPUSHR32(BYTE iOpcode); void ProcessPOPR32(BYTE iOpcode); void ProcessMOVR32R32(LPBYTE iOpcode); void ProcessADDR32_Imm(LPBYTE iOpcode); void ProcessSUBR32_Imm(LPBYTE iOpcode); void ProcessMOV_MemR32Imm8_R32(LPBYTE iOpcode); void ProcessMOV_MemR32Imm32_R32(LPBYTE iOpcode); void ProcessMOVR32_Imm(LPBYTE iOpcode); void ProcessMOVR32_MemImm(LPBYTE iOpcode); void ProcessMOVMemImm_R32(LPBYTE iOpcode); void ProcessMOV_MemR32Imm32_Imm32(LPBYTE iOpcode); void ProcessMOV_R32_MemR32Imm32(LPBYTE iOpcode); void ProcessMOV_R32_MemR32Imm8(LPBYTE iOpcode); void ProcessLEA_R32_MemR32Imm32(LPBYTE iOpcode); void ProcessXORR32_R32(LPBYTE iOpcode); void ProcessANDR32_Imm(LPBYTE iOpcode); void ProcessORR32_Imm(LPBYTE iOpcode); void ProcessSHLR32_Imm(LPBYTE iOpcode); void ProcessSHRR32_Imm(LPBYTE iOpcode); void ProcessCMPR32_Imm(LPBYTE iOpcode); void ProcessNOTR32(LPBYTE iOpcode); void ProcessINC_DECR32(LPBYTE iOpcode); //------------------------------- CVMCompiler(CVMHandlerProcessor &HandlerProcessor); ~CVMCompiler(void); }; ================================================ FILE: VM Project/VMHandlerProcessor.cpp ================================================ #include "stdafx.h" #include "VMHandlerProcessor.h" CVMHandlerProcessor::CVMHandlerProcessor(void) { HandlerCount=0; } CVMHandlerProcessor::~CVMHandlerProcessor(void) { } unsigned CVMHandlerProcessor::GetHandlerIndex(VMHandlerCodes iType) { // Main VM Handler unsigned int Result=0xFFFFFFFF; for (unsigned int i=0;i // MFC core and standard components #include // MFC extensions #ifndef _AFX_NO_OLE_SUPPORT #include // MFC support for Internet Explorer 4 Common Controls #endif #ifndef _AFX_NO_AFXCMN_SUPPORT #include // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT #include // MFC support for ribbons and control bars #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #endif ================================================ FILE: VM Project/targetver.h ================================================ #pragma once // Including SDKDDKVer.h defines the highest available Windows platform. // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. #include ================================================ FILE: VM Project.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VM Project", "VM Project\VM Project.vcxproj", "{50DC5327-0CAD-4787-B236-F3B0127AA8A9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {50DC5327-0CAD-4787-B236-F3B0127AA8A9}.Debug|Win32.ActiveCfg = Debug|Win32 {50DC5327-0CAD-4787-B236-F3B0127AA8A9}.Debug|Win32.Build.0 = Debug|Win32 {50DC5327-0CAD-4787-B236-F3B0127AA8A9}.Debug|Win32.Deploy.0 = Debug|Win32 {50DC5327-0CAD-4787-B236-F3B0127AA8A9}.Release|Win32.ActiveCfg = Release|Win32 {50DC5327-0CAD-4787-B236-F3B0127AA8A9}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal