diff --git a/CodeVirtualizer/Code.h b/CodeVirtualizer/Code.h index 5fe39ea..cb03466 100644 --- a/CodeVirtualizer/Code.h +++ b/CodeVirtualizer/Code.h @@ -1,14 +1,26 @@ #ifndef __CODE_H #define __CODE_H -#define CODE_FLAG_IS_LABEL (1<<0) -#define CODE_FLAG_IS_REL_JMP (1<<1) -#define CODE_FLAG_IS_INST (1<<2) -#define CODE_FLAG_DO_NOT_DIVIDE (1<<3) -#define CODE_FLAG_GROUP_START (1<<4) -#define CODE_FLAG_GROUP_END (1<<5) -#define CODE_FLAG_HAS_ASM_OP (1<<6) //Call all of the pre assembly operations -#define CODE_FLAG_IS_RIP_REL (1<<7) //Figure out how to deal with this... -#define CODE_FLAG_DOESNT_READ_FLAGS (1<<8) +/* +* 0-15 general flags for both vm and native +* 16-31 for vm or native specific use. +*/ +#define CODE_FLAG_GENERAL_START 0 +#define CODE_FLAG_SPECIFIC_START 16 + +#define DefineGeneralFlag(n) (1<<((n) + CODE_FLAG_GENERAL_START)) +#define DefineSpecificFlag(n) (1<<((n) + CODE_FLAG_SPECIFIC_START)) + +#define CODE_FLAG_IS_LABEL DefineGeneralFlag(0) +#define CODE_FLAG_IS_REL_JMP DefineGeneralFlag(1) +#define CODE_FLAG_IS_INST DefineGeneralFlag(2) +#define CODE_FLAG_DO_NOT_DIVIDE DefineGeneralFlag(3) +#define CODE_FLAG_GROUP_START DefineGeneralFlag(4) +#define CODE_FLAG_GROUP_END DefineGeneralFlag(5) +#define CODE_FLAG_HAS_ASM_OP DefineGeneralFlag(6) //Call all of the pre assembly operations MOVE THESE TO SPECIFIC FLAGS AT SOME POINT +#define CODE_FLAG_IS_RIP_REL DefineGeneralFlag(7) //Figure out how to deal with this... +#define CODE_FLAG_DOESNT_READ_FLAGS DefineGeneralFlag(8) + + #endif \ No newline at end of file diff --git a/CodeVirtualizer/CodeBlocks.cpp b/CodeVirtualizer/CodeBlocks.cpp deleted file mode 100644 index c7a723b..0000000 --- a/CodeVirtualizer/CodeBlocks.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Obfuscator.h" - -//Requires either being in the process address space, or relocations - - diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj b/CodeVirtualizer/CodeVirtualizer.vcxproj index 2e0176f..044987b 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj @@ -157,7 +157,6 @@ - diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters index 78ec70e..e2c8140 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters @@ -78,9 +78,6 @@ Code - - Obfuscator - File\PEFile diff --git a/CodeVirtualizer/Main.cpp b/CodeVirtualizer/Main.cpp index 3a3ebab..619f5e2 100644 --- a/CodeVirtualizer/Main.cpp +++ b/CodeVirtualizer/Main.cpp @@ -10,6 +10,7 @@ #include "Random.h" #include "VirtualMachine.h" +#include "Virtualizer.h" __declspec(dllexport) VOID CvInit() { @@ -187,67 +188,104 @@ UCHAR IsEvenCode[]{ //EXTERN_C UINT64 RetNum(UINT64 Num); //EXTERN_C BOOL IsEven(UINT64 Num); + int main() { XedGlobalInit(); srand(time(NULL)); - UINT OutSize = 0; - PUCHAR Output = VmHandlerIRegMem_BISD(VM_IREG_3, VM_OPSIZE_16, FALSE, &OutSize); // VmHandlerPrologue(8, &OutSize); - //PUCHAR Output = VmHandlerEncode2(XED_ICLASS_MOVZX, VM_OPSIZE_32, VM_OPSIZE_16, &OutSize); - //PUCHAR Output = VmHandlerPrologue(10, &OutSize); - if (Output && OutSize) + //UINT OutSize = 0; + //PUCHAR Output = VmHandlerIRegMem_BISD(VM_IREG_3, VM_OPSIZE_16, FALSE, &OutSize); // VmHandlerPrologue(8, &OutSize); + ////PUCHAR Output = VmHandlerEncode2(XED_ICLASS_MOVZX, VM_OPSIZE_32, VM_OPSIZE_16, &OutSize); + ////PUCHAR Output = VmHandlerPrologue(10, &OutSize); + //if (Output && OutSize) + //{ + // PrintByteArr(Output, OutSize); + //} + //printf("\n"); + + //for (UINT i = 0; i < VM_IREG_COUNT; i++) + //{ + // printf("IReg: %u, %s %s %s %s\n", i, XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_8)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_16)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_32)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_64))); + //} + + //printf("Reg2: %s %s %s %s\n", XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_8)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_16)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_32)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_64))); + + //XED_REG_ENUM Reg = XED_REG_RCX; + //XED_REG_ENUM Base = VmOperandSizeToRegEnumBase(VM_OPSIZE_64); + //XED_REG_ENUM OfSize = VmGetRegOfSize(Reg, VM_OPSIZE_64); + + + UCHAR TestCode[] = { 0x48, 0x83, 0xC0, 0xFE }; // { 0x48, 0x6B, 0xC0, 0xFE }; // { 0x48, 0x01, 0xC8 }; // + XED_DECODED_INST DecodedInst; + XedDecodedInstZeroSetMode(&DecodedInst, &XedGlobalMachineState); + XED_ERROR_ENUM Err = XedDecode(&DecodedInst, TestCode, sizeof(TestCode)); + if (Err != XED_ERROR_NONE) { - PrintByteArr(Output, OutSize); + printf("Failed to decode.\n"); + system("pause"); + return -1; } - printf("\n"); - for (UINT i = 0; i < VM_IREG_COUNT; i++) + PVIRTUALIZER Virt = new VIRTUALIZER(); + + VM_CODE_BLOCK Block; + Block.End = Block.Start = NULL; + ViVirtualizeInst(Virt, &DecodedInst, &Block); + + for (PVM_CODE_LINK T = Block.Start; T && T != Block.End->Next; T = T->Next) { - printf("IReg: %u, %s %s %s %s\n", i, XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_8)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_16)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_32)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_64))); + printf("HandlerId: %s\n", ViIClassToString(T->HandlerId)); + if (T->HandlerId >= VM_ICLASS_LD_IREG_IMM_START && T->HandlerId <= VM_ICLASS_LD_IREG_IMM_END) + printf("Imm: %p\n\n", T->Imm.Immediate.Raw); + else if (T->HandlerId >= VM_ICLASS_ENTER) + printf("Reg: v%s\n\n", XedRegEnumToString((XED_REG_ENUM)(XED_REG_RAX + T->Reg.Register))); + else + printf("\n"); } - printf("Reg2: %s %s %s %s\n", XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_8)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_16)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_32)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_64))); + + /*XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&DecodedInst); + printf("IClass: %s\n", XedIClassEnumToString(IClass)); + + CONST xed_inst_t* Inst = XedDecodedInstInst(&DecodedInst); + UINT OperandCount = XedDecodedInstNumOperands(&DecodedInst); + + for (UINT i = 0; i < OperandCount; i++) + { + CONST xed_operand_t* Operand = XedInstOperand(Inst, i); + xed_operand_enum_t OperandName = XedOperandName(Operand); + printf("Operand Name: %s\n", XedOperandEnumToString(OperandName)); + printf("Operand Written: %i\n", XedOperandWritten(Operand)); + printf("Operand Read: %i\n", XedOperandRead(Operand)); + printf("Operand R/R: %i\n", XedOperandReadAndWritten(Operand)); + if (XedOperandIsRegister(OperandName)) + { + xed_reg_enum_t RegEnum = XedDecodedInstGetReg(&DecodedInst, OperandName); + printf("Reg: %s\n", XedRegEnumToString(RegEnum)); + } + if (OperandName == XED_OPERAND_MEM0 || OperandName == XED_OPERAND_MEM1) + { + UINT MemOpIndex = OperandName - XED_OPERAND_MEM0; + printf("MemOpIdx: %u\n", MemOpIndex); + printf("Base Reg: %s\n", XedRegEnumToString(XedDecodedInstGetBaseReg(&DecodedInst, MemOpIndex))); + printf("Index Reg: %s\n", XedRegEnumToString(XedDecodedInstGetIndexReg(&DecodedInst, MemOpIndex))); + printf("Scale: %u\n", XedDecodedInstGetScale(&DecodedInst, MemOpIndex)); + printf("Disp: %llu\n", XedDecodedInstGetMemoryDisplacement(&DecodedInst, MemOpIndex)); + printf("OpLength: %u\n", XedDecodedInstOperandLength(&DecodedInst, i)); + } + }*/ + + + + + + - //UCHAR TestCode[] = { 0x48, 0x8B, 0x84, 0xD1, 0xF0, 0x06, 0x00, 0x00 }; // { 0x48, 0x89, 0xC8 }; - //XED_DECODED_INST DecodedInst; - //XedDecodedInstZeroSetMode(&DecodedInst, &XedGlobalMachineState); - //XED_ERROR_ENUM Err = XedDecode(&DecodedInst, TestCode, sizeof(TestCode)); - //if (Err != XED_ERROR_NONE) - //{ - // printf("Failed to decode.\n"); - // system("pause"); - // return -1; - //} - //XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&DecodedInst); - //printf("IClass: %s\n", XedIClassEnumToString(IClass)); - // - //CONST xed_inst_t* Inst = XedDecodedInstInst(&DecodedInst); - //UINT OperandCount = XedDecodedInstNumOperands(&DecodedInst); - //for (UINT i = 0; i < OperandCount; i++) - //{ - // CONST xed_operand_t* Operand = XedInstOperand(Inst, i); - // xed_operand_enum_t OperandName = XedOperandName(Operand); - // printf("Operand Name: %s\n", XedOperandEnumToString(OperandName)); - // if (XedOperandIsRegister(OperandName)) - // { - // xed_reg_enum_t RegEnum = XedDecodedInstGetReg(&DecodedInst, OperandName); - // printf("Reg: %s\n", XedRegEnumToString(RegEnum)); - // } - // if (OperandName == XED_OPERAND_MEM0 || OperandName == XED_OPERAND_MEM1) - // { - // UINT MemOpIndex = OperandName - XED_OPERAND_MEM0; - // printf("MemOpIdx: %u\n", MemOpIndex); - // printf("Base Reg: %s\n", XedRegEnumToString(XedDecodedInstGetBaseReg(&DecodedInst, MemOpIndex))); - // printf("Index Reg: %s\n", XedRegEnumToString(XedDecodedInstGetIndexReg(&DecodedInst, MemOpIndex))); - // printf("Scale: %u\n", XedDecodedInstGetScale(&DecodedInst, MemOpIndex)); - // printf("Disp: %llu\n", XedDecodedInstGetMemoryDisplacement(&DecodedInst, MemOpIndex)); - // } - //} //xed_operand_values_t* Operands = xed_decoded_inst_operands(&DecodedInst); diff --git a/CodeVirtualizer/VMDefs.h b/CodeVirtualizer/VMDefs.h index 6f49eec..80db342 100644 --- a/CodeVirtualizer/VMDefs.h +++ b/CodeVirtualizer/VMDefs.h @@ -2,6 +2,8 @@ #define __VMDEFS_H #include "Windas.h" +#include "XedWrap.h" + union VM_IMM { @@ -44,38 +46,41 @@ enum VM_OPERAND_SIZE_ENUM : UCHAR VM_OPSIZE_COUNT }; +enum VM_REG_USAGE_ENUM +{ + VM_REG_HEADER = XED_REG_RDI, + VM_REG_HANDLER_TABLE = XED_REG_RSI, + VM_REG_IP = XED_REG_RDX, + VM_REG_REGISTER_FILE = XED_REG_RBP, + VM_REG_FLAG_STORAGE = XED_REG_RSP, +}; + enum VM_ICLASS_ENUM : USHORT { - VM_ICLASS_ENTER, + VM_ICLASS_ENTER = XED_ICLASS_LAST, VM_ICLASS_EXIT, - //Loading from memory into internal registers - //Need to support 3 modes: [BASE], [BASE+OFFSET], [BASE+INDEX*SCALE+OFFSET] - //for 4 possible sizes(1,2,4,8) - //for 3 possible register spots(rax,rbx,rcx - //3 * 4 * 3 = 72 + //OPSIZE IS NOW HANDLED INSIDE OF THE VM_HANDLER STRUCTURE + + //Loading into ireg from memory VM_ICLASS_LD_IREG_MEM_START, - VM_ICLASS_LD_IREG_MEM_END = VM_ICLASS_LD_IREG_MEM_START + (VM_IREG_COUNT * VM_OPSIZE_COUNT * VM_MEMOP_TYPE_COUNT) - 1, + VM_ICLASS_LD_IREG_MEM_END = VM_ICLASS_LD_IREG_MEM_START + (VM_IREG_COUNT * VM_MEMOP_TYPE_COUNT) - 1, //Storing internal registers into memory VM_ICLASS_ST_IREG_MEM_START, - VM_ICLASS_ST_IREG_MEM_END = VM_ICLASS_ST_IREG_MEM_START + (VM_IREG_COUNT * VM_OPSIZE_COUNT * VM_MEMOP_TYPE_COUNT) - 1, + VM_ICLASS_ST_IREG_MEM_END = VM_ICLASS_ST_IREG_MEM_START + (VM_IREG_COUNT * VM_MEMOP_TYPE_COUNT) - 1, //Loading scratch registers into internal registers VM_ICLASS_LD_IREG_REG_START, - VM_ICLASS_LD_IREG_REG_END = VM_ICLASS_LD_IREG_REG_START + (VM_IREG_COUNT * VM_OPSIZE_COUNT) - 1, + VM_ICLASS_LD_IREG_REG_END = VM_ICLASS_LD_IREG_REG_START + (VM_IREG_COUNT) - 1, //storing internal registers into scratch registers VM_ICLASS_ST_IREG_REG_START, - VM_ICLASS_ST_IREG_REG_END = VM_ICLASS_ST_IREG_REG_START + (VM_IREG_COUNT * VM_OPSIZE_COUNT) - 1, + VM_ICLASS_ST_IREG_REG_END = VM_ICLASS_ST_IREG_REG_START + (VM_IREG_COUNT) - 1, //Loading Immediate Values into internal registers VM_ICLASS_LD_IREG_IMM_START, - VM_ICLASS_LD_IREG_IMM_END = VM_ICLASS_LD_IREG_IMM_START + (VM_IREG_COUNT * VM_OPSIZE_COUNT) - 1, - - - VM_ICLASS_MOV_START, - VM_ICLASS_MOV_END = VM_ICLASS_MOV_START + VM_OPSIZE_COUNT - 1, + VM_ICLASS_LD_IREG_IMM_END = VM_ICLASS_LD_IREG_IMM_START + (VM_IREG_COUNT) - 1, VM_ICLASS_COUNT, }; @@ -121,9 +126,49 @@ typedef struct _VM_HEADER { PVOID RegisterFile[VM_REG_COUNT]; PVOID RegisterStorage[16]; - PVOID HandlerTable[1]; - + PVOID FlagsStorage; UINT HandlerTableSize; + PVOID HandlerTable[1]; }VM_HEADER, * PVM_HEADER; +#pragma pack(push,1) +struct IRegMem_B_Template +{ + UINT16 OpCode; + UINT8 Base; +}; +struct IRegMem_BD_Template +{ + UINT16 OpCode; + UINT8 Base; + INT32 Disp; +}; +struct IRegMem_BIS_Template +{ + UINT16 OpCode; + UINT8 Base; + UINT8 Index; + UINT8 Scale; +}; +struct IRegMem_BISD_Template +{ + UINT16 OpCode; + UINT8 Base; + UINT8 Index; + UINT8 Scale; + INT32 Disp; +}; +struct IRegReg_Template +{ + UINT16 OpCode; + UINT8 Reg; +}; +struct IRegImm_Template +{ + UINT16 OpCode; + VM_IMM Imm; +}; + +#pragma pack(pop) + #endif \ No newline at end of file diff --git a/CodeVirtualizer/VirtualInstructionEmitter.cpp b/CodeVirtualizer/VirtualInstructionEmitter.cpp index fcb4856..8124e0b 100644 --- a/CodeVirtualizer/VirtualInstructionEmitter.cpp +++ b/CodeVirtualizer/VirtualInstructionEmitter.cpp @@ -1,26 +1,28 @@ #include "VirtualInstructionEmitter.h" - -PVM_CODE_LINK VmEmitterIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base) -{ - -} -PVM_CODE_LINK VmEmitterIRegLoadMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_IMM Offset) -{ - -} -PVM_CODE_LINK VmEmitterIRegLoadMem_BISO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_REG_ENUM Index, VM_OPERAND_SIZE_ENUM Scale, VM_IMM Offset) -{ - -} -PVM_CODE_LINK VmEmitterIRegLoadReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg) -{ - -} -PVM_CODE_LINK VmEmitterIRegStoreReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg) -{ - -} -PVM_CODE_LINK VmEmitterIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate) -{ - -} \ No newline at end of file +// +//PUCHAR VmEmitterIRegLoadMem_B(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, PUINT OutSize) +//{ +// IRegLoadMem_B_Template* Template = (IRegLoadMem_B_Template*)(new UCHAR[sizeof(IRegLoadMem_B_Template)]); +// Template->OpCode = OpCode; +// Template->Base = IReg; +//} +//PUCHAR VmEmitterIRegLoadMem_BO(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, INT32 Displacement, PUINT OutSize) +//{ +// +//} +//PUCHAR VmEmitterIRegLoadMem_BISO(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_REG_ENUM Index, VM_OPERAND_SIZE_ENUM Scale, INT32 Displacement, PUINT OutSize) +//{ +// +//} +//PUCHAR VmEmitterIRegLoadReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize) +//{ +// +//} +//PUCHAR VmEmitterIRegStoreReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize) +//{ +// +//} +//PUCHAR VmEmitterIRegLoadImm(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate, PUINT OutSize) +//{ +// +//} \ No newline at end of file diff --git a/CodeVirtualizer/VirtualInstructionEmitter.h b/CodeVirtualizer/VirtualInstructionEmitter.h index 195104f..55909d0 100644 --- a/CodeVirtualizer/VirtualInstructionEmitter.h +++ b/CodeVirtualizer/VirtualInstructionEmitter.h @@ -4,12 +4,16 @@ #include "VmCode.h" #include "VMDefs.h" -PVM_CODE_LINK VmEmitterIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base); -PVM_CODE_LINK VmEmitterIRegLoadMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_IMM Offset); -PVM_CODE_LINK VmEmitterIRegLoadMem_BISO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_REG_ENUM Index, VM_OPERAND_SIZE_ENUM Scale, VM_IMM Offset); -PVM_CODE_LINK VmEmitterIRegLoadReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg); -PVM_CODE_LINK VmEmitterIRegStoreReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg); -PVM_CODE_LINK VmEmitterIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate); +//Im thinking these can all be macros. + + +//PUCHAR VmEmitterIRegLoadMem_B(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, PUINT OutSize); +//PUCHAR VmEmitterIRegLoadMem_BO(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, INT32 Displacement, PUINT OutSize); +//PUCHAR VmEmitterIRegLoadMem_BISO(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_REG_ENUM Index, VM_OPERAND_SIZE_ENUM Scale, INT32 Displacement, PUINT OutSize); +//PUCHAR VmEmitterIRegLoadReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize); +//PUCHAR VmEmitterIRegStoreReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize); +//PUCHAR VmEmitterIRegLoadImm(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate, PUINT OutSize); + #endif \ No newline at end of file diff --git a/CodeVirtualizer/VirtualMachine.cpp b/CodeVirtualizer/VirtualMachine.cpp index 47db8eb..c7245a4 100644 --- a/CodeVirtualizer/VirtualMachine.cpp +++ b/CodeVirtualizer/VirtualMachine.cpp @@ -12,28 +12,30 @@ XED_REG_ENUM VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize) } return XED_REG_INVALID; } - XED_REG_ENUM VmGetRegOfSize(XED_REG_ENUM Reg, VM_OPERAND_SIZE_ENUM OperandSize) { if (Reg >= XED_REG_GPR8_FIRST && Reg <= XED_REG_GPR8_LAST) - { return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR8_FIRST)); - } else if (Reg >= XED_REG_GPR16_FIRST && Reg <= XED_REG_GPR16_LAST) - { return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR16_FIRST)); - } else if (Reg >= XED_REG_GPR32_FIRST && Reg <= XED_REG_GPR32_LAST) - { return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR32_FIRST)); - } else if (Reg >= XED_REG_GPR64_FIRST && Reg <= XED_REG_GPR64_LAST) - { return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR64_FIRST)); - } return XED_REG_INVALID; } - +VM_OPERAND_SIZE_ENUM VmXRegToOpSize(XED_REG_ENUM Reg) +{ + if (Reg >= XED_REG_GPR8_FIRST && Reg <= XED_REG_GPR8_LAST) + return VM_OPSIZE_8; + else if (Reg >= XED_REG_GPR16_FIRST && Reg <= XED_REG_GPR16_LAST) + return VM_OPSIZE_16; + else if (Reg >= XED_REG_GPR32_FIRST && Reg <= XED_REG_GPR32_LAST) + return VM_OPSIZE_32; + else if (Reg >= XED_REG_GPR64_FIRST && Reg <= XED_REG_GPR64_LAST) + return VM_OPSIZE_64; + return VM_OPSIZE_COUNT; +} XED_REG_ENUM VmIRegToXReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize) { switch (IReg) @@ -51,36 +53,54 @@ XED_REG_ENUM VmIRegToXReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize) } return (XED_REG_ENUM)(XED_REG_AX + (16 * (OperandSize - 1)) + IReg);*/ } +VM_REG_ENUM VmXRegToVRegId(XED_REG_ENUM Reg) +{ + return (VM_REG_ENUM)(VmGetRegOfSize(Reg, VM_OPSIZE_64) - XED_REG_RAX); +} + +CONST CHAR* VmIClassToString(VM_ICLASS_ENUM IClass) +{ + if (IClass >= VM_ICLASS_COUNT) + return "VM_ICLASS_INVALID"; + else if (IClass == VM_ICLASS_EXIT) + return "VM_ICLASS_EXIT"; + else if (IClass >= VM_ICLASS_LD_IREG_MEM_START && IClass <= VM_ICLASS_LD_IREG_MEM_END) + return "VM_ICLASS_LD_IREG_MEM"; + else if (IClass >= VM_ICLASS_ST_IREG_MEM_START && IClass <= VM_ICLASS_ST_IREG_MEM_END) + return "VM_ICLASS_ST_IREG_MEM"; + else if (IClass >= VM_ICLASS_LD_IREG_MEM_START && IClass <= VM_ICLASS_LD_IREG_REG_END) + return "VM_ICLASS_LD_IREG_REG"; + else if (IClass >= VM_ICLASS_ST_IREG_REG_START && IClass <= VM_ICLASS_ST_IREG_REG_END) + return "VM_ICLASS_ST_IREG_REG"; + else if (IClass >= VM_ICLASS_LD_IREG_IMM_START && IClass <= VM_ICLASS_LD_IREG_IMM_END) + return "VM_ICLASS_LD_IREG_IMM"; +} -PUCHAR VmHandlerPrologue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip, XED_REG_ENUM HandlerTableReg) +PUCHAR VmHandlerEpilogue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip, XED_REG_ENUM HandlerTableReg) { // add rdx, InstructionSize + Prologue Size // movzx r8,byte ptr[rdx] // jmp qword ptr[rsi+r8*8h] - XED_ENCODER_INSTRUCTION InstList[5]; - InstructionSize += VM_HANDLER_PROLOGUE_SIZE; - XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32)); - XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); - XedInst1(&InstList[4], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64)); - PUCHAR Ret = XedEncodeInstructions(InstList, 5, OutSize); - if (*OutSize == VM_HANDLER_PROLOGUE_SIZE) + XED_ENCODER_INSTRUCTION InstList[3]; + InstructionSize += VM_HANDLER_EPILOGUE_SIZE; + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); + XedInst1(&InstList[2], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64)); + PUCHAR Ret = XedEncodeInstructions(InstList, 3, OutSize); + if (*OutSize == VM_HANDLER_EPILOGUE_SIZE) return Ret; delete[] Ret; - InstructionSize -= VM_HANDLER_PROLOGUE_SIZE; + InstructionSize -= VM_HANDLER_EPILOGUE_SIZE; InstructionSize += *OutSize; - XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32)); - XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); - XedInst1(&InstList[4], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64)); - return XedEncodeInstructions(InstList, 5, OutSize); + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); + XedInst1(&InstList[2], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64)); + return XedEncodeInstructions(InstList, 3, OutSize); } -PUCHAR VmHandlerIRegMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize) +PUCHAR VmHandlerIRegMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1) { /* * movzx r8,byte ptr[rdx+2] @@ -89,16 +109,16 @@ PUCHAR VmHandlerIRegMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, B */ UINT OpSizeBits = VmOpSizeToBits(OperandSize); XED_ENCODER_INSTRUCTION InstList[3]; - XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0,0), 64)); + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XReg1), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XReg1), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0,0), 64)); if (Load) - XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemB(XED_REG_R8, OpSizeBits)); + XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemB(XReg1, OpSizeBits)); else - XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemB(XED_REG_R8, OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); + XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemB(XReg1, OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); return XedEncodeInstructions(InstList, 3, OutSize); } -PUCHAR VmHandlerIRegMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize) +PUCHAR VmHandlerIRegMem_BD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1, XED_REG_ENUM XReg2) { /* * movzx r8,byte ptr[rdx+2] @@ -108,78 +128,81 @@ PUCHAR VmHandlerIRegMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, */ UINT OpSizeBits = VmOpSizeToBits(OperandSize); XED_ENCODER_INSTRUCTION InstList[4]; - XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), 64)); - XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 32)); + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XReg1), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XReg1), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0, 0), 64)); + XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XReg2), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 32)); if (Load) - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R9, 1, XedDisp(0, 0), OpSizeBits)); + XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XReg1, XReg2, 1, XedDisp(0, 0), OpSizeBits)); else - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_R8, XED_REG_R9, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); + XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XReg1, XReg2, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); return XedEncodeInstructions(InstList, 4, OutSize); } -PUCHAR VmHandlerIRegMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize) +PUCHAR VmHandlerIRegMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1, XED_REG_ENUM XReg2, XED_REG_ENUM XReg3) { /* * movzx r8,byte ptr[rdx+2] * mov r8, qword ptr[rbp+r8*8] * movzx r9, byte ptr[rdx+3] * movzx r10, byte ptr[rdx+4] ;load scale value(unsigned) - * pushfq * imul r10, qword ptr[rbp+r9*8] - * popfq * mov (ireg), (size) ptr[r8+r10] */ UINT OpSizeBits = VmOpSizeToBits(OperandSize); - XED_ENCODER_INSTRUCTION InstList[8]; - XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), 64)); - XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); - XedInst0(&InstList[4], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); - XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XED_REG_R10), XedMemBISD(XED_REG_RBP, XED_REG_R9, 8, XedDisp(0, 0), 64)); - XedInst0(&InstList[6], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XED_ENCODER_INSTRUCTION InstList[6]; + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XReg1), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XReg1), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0, 0), 64)); + XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg2), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); + XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg3), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); + XedInst2(&InstList[4], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XReg3), XedMemBISD(XED_REG_RBP, XReg2, 8, XedDisp(0, 0), 64)); if (Load) - XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R10, 1, XedDisp(0, 0), OpSizeBits)); + XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XReg1, XReg3, 1, XedDisp(0, 0), OpSizeBits)); else - XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_R8, XED_REG_R10, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); - return XedEncodeInstructions(InstList, 8, OutSize); + XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XReg1, XReg3, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); + return XedEncodeInstructions(InstList, 6, OutSize); } -PUCHAR VmHandlerIRegMem_BISD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize) +PUCHAR VmHandlerIRegMem_BISD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1, XED_REG_ENUM XReg2, XED_REG_ENUM XReg3) { /* * movzx r8, byte ptr[rdx+2] * mov r8, qword ptr[rbp+r8*8] * movzx r9, byte ptr[rdx+3] * movzx r10, byte ptr[rdx+4] ;load scale value(unsigned) - * pushfq * imul r10, qword ptr[rbp+r9*8] * movsxd r9, dword ptr[rdx+5] ;load immediate displacement * add r10, r9 ;add immediate displacement - * popfq * mov (ireg), (size) ptr[r8+r10] */ UINT OpSizeBits = VmOpSizeToBits(OperandSize); - XED_ENCODER_INSTRUCTION InstList[10]; - XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), 64)); - XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); - XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); - XedInst0(&InstList[4], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); - XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XED_REG_R10), XedMemBISD(XED_REG_RBP, XED_REG_R9, 8, XedDisp(0, 0), 64)); - XedInst2(&InstList[6], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(5, 8), 32)); - XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(XED_REG_R10), XedReg(XED_REG_R9)); - XedInst0(&InstList[8], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XED_ENCODER_INSTRUCTION InstList[8]; + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XReg1), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XReg1), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0, 0), 64)); + XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg2), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); + XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg3), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); + XedInst2(&InstList[4], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XReg3), XedMemBISD(XED_REG_RBP, XReg2, 8, XedDisp(0, 0), 64)); + XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XReg2), XedMemBD(XED_REG_RDX, XedDisp(5, 8), 32)); + XedInst2(&InstList[6], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(XReg3), XedReg(XReg2)); if (Load) - XedInst2(&InstList[9], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R10, 1, XedDisp(0, 0), OpSizeBits)); + XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XReg1, XReg3, 1, XedDisp(0, 0), OpSizeBits)); else - XedInst2(&InstList[9], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_R8, XED_REG_R10, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); + XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XReg1, XReg3, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); - return XedEncodeInstructions(InstList, 10, OutSize); + return XedEncodeInstructions(InstList, 8, OutSize); +} +PUCHAR VmHandlerIRegMem(VM_MEMOP_TYPE_ENUM MemOpType, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1, XED_REG_ENUM XReg2, XED_REG_ENUM XReg3) +{ + switch (MemOpType) + { + case VM_MEMOP_B: return VmHandlerIRegMem_B(IReg, OperandSize, Load, OutSize, XReg1); + case VM_MEMOP_BD: return VmHandlerIRegMem_BD(IReg, OperandSize, Load, OutSize, XReg1, XReg2); + case VM_MEMOP_BIS: return VmHandlerIRegMem_BIS(IReg, OperandSize, Load, OutSize, XReg1, XReg2, XReg3); + case VM_MEMOP_BISD: return VmHandlerIRegMem_BISD(IReg, OperandSize, Load, OutSize, XReg1, XReg2, XReg3); + } + return NULL; } -PUCHAR VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize) +PUCHAR VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1) { /* * movzx r8,byte ptr[rdx+2] @@ -188,14 +211,14 @@ PUCHAR VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOO UINT OpSizeBits = VmOpSizeToBits(OperandSize); XED_ENCODER_INSTRUCTION InstList[2]; - XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); + XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XReg1), XedMemBD(XED_REG_RDX, XedDisp(2, 8), 8)); if (Load) - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), OpSizeBits)); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0, 0), OpSizeBits)); else - XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); + XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize))); return XedEncodeInstructions(InstList, 2, OutSize); } -PUCHAR VmHandlerIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize) +PUCHAR VmHandlerIRegImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize) { /* * mov (ireg), size ptr[rdx+2] @@ -207,21 +230,35 @@ PUCHAR VmHandlerIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, return XedEncodeInstructions(InstList, 1, OutSize); } +PUCHAR VmHandlerEncode0(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize) +{ + XED_ENCODER_INSTRUCTION InstList[3]; + XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XedInst0(&InstList[1], XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize)); + XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); + return XedEncodeInstructions(InstList, 3, OutSize); +} PUCHAR VmHandlerEncode1(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize) { - XED_ENCODER_INSTRUCTION InstList; - XedInst1(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize))); - return XedEncodeInstructions(&InstList, 1, OutSize); + XED_ENCODER_INSTRUCTION InstList[3]; + XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XedInst1(&InstList[1], XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize))); + XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); + return XedEncodeInstructions(InstList, 3, OutSize); } PUCHAR VmHandlerEncode2(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, PUINT OutSize) { - XED_ENCODER_INSTRUCTION InstList; - XedInst2(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2))); - return XedEncodeInstructions(&InstList, 1, OutSize); + XED_ENCODER_INSTRUCTION InstList[3]; + XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XedInst2(&InstList[1], XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2))); + XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); + return XedEncodeInstructions(InstList, 3, OutSize); } PUCHAR VmHandlerEncode3(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, VM_OPERAND_SIZE_ENUM OperandSize3, PUINT OutSize) { - XED_ENCODER_INSTRUCTION InstList; - XedInst3(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2)), XedReg(VmIRegToXReg(VM_IREG_3, OperandSize3))); - return XedEncodeInstructions(&InstList, 1, OutSize); + XED_ENCODER_INSTRUCTION InstList[3]; + XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); + XedInst3(&InstList[1], XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2)), XedReg(VmIRegToXReg(VM_IREG_3, OperandSize3))); + XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); + return XedEncodeInstructions(InstList, 3, OutSize); } \ No newline at end of file diff --git a/CodeVirtualizer/VirtualMachine.h b/CodeVirtualizer/VirtualMachine.h index 03ee23d..b9037d7 100644 --- a/CodeVirtualizer/VirtualMachine.h +++ b/CodeVirtualizer/VirtualMachine.h @@ -7,19 +7,9 @@ #include "NativeCode.h" #include "VmCode.h" -#define VmIRegLoadMemDefaultCode(IReg, OpSize, MemOpType) (VM_ICLASS_LD_IREG_MEM_START + (VM_OPSIZE_COUNT * VM_MEMOP_TYPE_COUNT * (IReg)) + (VM_MEMOP_TYPE_COUNT * (OpSize)) + (MemOpType)) -#define VmIRegStoreMemDefaultCode(IReg, OpSize, MemOpType) (VM_ICLASS_ST_IREG_MEM_START + (VM_OPSIZE_COUNT * VM_MEMOP_TYPE_COUNT * (IReg)) + (VM_MEMOP_TYPE_COUNT * (OpSize)) + (MemOpType)) -#define VmIRegLoadRegDefaultCode(IReg, OpSize) (VM_ICLASS_LD_IREG_REG_START + (VM_OPSIZE_COUNT * (IReg)) + (OpSize)) -#define VmIRegStoreRegDefaultCode(IReg, OpSize) (VM_ICLASS_ST_IREG_REG_START + (VM_OPSIZE_COUNT * (IReg)) + (OpSize)) -#define VmIRegLoadImmDefaultCode(IReg, OpSize) (VM_ICLASS_LD_IREG_IMM_START + (VM_OPSIZE_COUNT * (IReg)) + (OpSize)) - #define VmOpSizeToBytes(OpSize) (pow(2, (UCHAR)OpSize)) #define VmOpSizeToBits(OpSize) (VmOpSizeToBytes(OpSize) * 8) -#define VmDefaultInstId(IClass, OperandSize) (((IClass) * VM_OPSIZE_COUNT) + OperandSize) -inline PUCHAR DefaultInstBuffers[XED_ICLASS_LAST * VM_OPSIZE_COUNT] = { NULL }; - - /* * Vm Structure: @@ -30,6 +20,7 @@ inline PUCHAR DefaultInstBuffers[XED_ICLASS_LAST * VM_OPSIZE_COUNT] = { NULL }; * RAX = IREG0 * RBX = IREG1 * RCX = IREG2 +* RSP = Storage for flags inside of VM_HEADER * * R8 = Not ever saved. Uses: HandlerJmp, * R9, R10 = Not saved. Uses: Temp storage inside handlers for IReg access. @@ -38,19 +29,24 @@ inline PUCHAR DefaultInstBuffers[XED_ICLASS_LAST * VM_OPSIZE_COUNT] = { NULL }; XED_REG_ENUM VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize); XED_REG_ENUM VmGetRegOfSize(XED_REG_ENUM Reg, VM_OPERAND_SIZE_ENUM OperandSize); XED_REG_ENUM VmIRegToXReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize); +VM_OPERAND_SIZE_ENUM VmXRegToOpSize(XED_REG_ENUM Reg); +VM_REG_ENUM VmXRegToVRegId(XED_REG_ENUM Reg); +#define VM_HANDLER_EPILOGUE_SIZE 15 +PUCHAR VmHandlerEpilogue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip = XED_REG_RDX, XED_REG_ENUM HandlerTableReg = XED_REG_RSI); -#define VM_HANDLER_PROLOGUE_SIZE 17 -PUCHAR VmHandlerPrologue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip = XED_REG_RDX, XED_REG_ENUM HandlerTableReg = XED_REG_RSI); +CONST CHAR* VmIClassToString(VM_ICLASS_ENUM IClass); //Internal register(IReg) store/load -PUCHAR VmHandlerIRegMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize); -PUCHAR VmHandlerIRegMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize); -PUCHAR VmHandlerIRegMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize); -PUCHAR VmHandlerIRegMem_BISD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize); -PUCHAR VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize); -PUCHAR VmHandlerIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); - +PUCHAR VmHandlerIRegMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8); +PUCHAR VmHandlerIRegMem_BD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8, XED_REG_ENUM XReg2 = XED_REG_R9); +PUCHAR VmHandlerIRegMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8, XED_REG_ENUM XReg2 = XED_REG_R9, XED_REG_ENUM XReg3 = XED_REG_R10); +PUCHAR VmHandlerIRegMem_BISD(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8, XED_REG_ENUM XReg2 = XED_REG_R9, XED_REG_ENUM XReg3 = XED_REG_R10); +PUCHAR VmHandlerIRegMem(VM_MEMOP_TYPE_ENUM MemOpType, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8, XED_REG_ENUM XReg2 = XED_REG_R9, XED_REG_ENUM XReg3 = XED_REG_R10); +PUCHAR VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT OutSize, XED_REG_ENUM XReg1 = XED_REG_R8); +PUCHAR VmHandlerIRegImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); + +PUCHAR VmHandlerEncode0(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); PUCHAR VmHandlerEncode1(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); PUCHAR VmHandlerEncode2(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, PUINT OutSize); PUCHAR VmHandlerEncode3(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, VM_OPERAND_SIZE_ENUM OperandSize3, PUINT OutSize); diff --git a/CodeVirtualizer/Virtualizer.cpp b/CodeVirtualizer/Virtualizer.cpp index 1b2c6ce..4dc6cd6 100644 --- a/CodeVirtualizer/Virtualizer.cpp +++ b/CodeVirtualizer/Virtualizer.cpp @@ -1,16 +1,39 @@ #include "Virtualizer.h" +#include "VirtualMachine.h" + +#define VmIRegLoadMemHandlerId(IReg, MemOpType) (VM_ICLASS_LD_IREG_MEM_START + VM_MEMOP_TYPE_COUNT * (IReg) + (MemOpType)) +#define VmIRegStoreMemHandlerId(IReg, MemOpType) (VM_ICLASS_ST_IREG_MEM_START + VM_MEMOP_TYPE_COUNT * (IReg) + (MemOpType)) +#define VmIRegLoadRegHandlerId(IReg) (VM_ICLASS_LD_IREG_REG_START + (IReg)) +#define VmIRegStoreRegHandlerId(IReg) (VM_ICLASS_ST_IREG_REG_START + (IReg)) +#define VmIRegLoadImmHandlerId(IReg) (VM_ICLASS_LD_IREG_IMM_START + (IReg)) + +PVM_HANDLER ViGetVmHandler(PVIRTUALIZER Virt, UINT Id) +{ + if (Virt->HandlerMap[Id] == 0) + { + Virt->Handlers.push_back(new VM_HANDLER()); + Virt->HandlerMap[Id] = (USHORT)(Virt->Handlers.size() - 1); + } + return Virt->Handlers[Virt->HandlerMap[Id]]; +} + +CONST CHAR* ViIClassToString(UINT IClass) +{ + if (IClass >= VM_ICLASS_ENTER) + return VmIClassToString((VM_ICLASS_ENUM)IClass); + return XedIClassEnumToString((XED_ICLASS_ENUM)IClass); +} BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link) { switch (XedDecodedInstGetIClass(&Link->XedInstruction)) { case XED_ICLASS_MOV: - return TRUE; } return FALSE; } -BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block) +BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Virt, PNATIVE_CODE_BLOCK Block) { for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) { @@ -32,16 +55,161 @@ BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block) } return TRUE; } -BOOL ViVirtualizeInst(PNATIVE_CODE_LINK Inst, PNATIVE_CODE_BLOCK) +BOOL ViVirtualizeInst(PVIRTUALIZER Virt, XED_DECODED_INST* DecodedInst, PVM_CODE_BLOCK Block) { - XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Inst->XedInstruction); - switch (IClass) + VM_CODE_BLOCK Prologue = { }; + VM_CODE_BLOCK Epilogue = { }; + + CONST XED_INST* Inst = XedDecodedInstInst(DecodedInst); + UINT OperandCount = XedDecodedInstNumOperands(DecodedInst); + XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(DecodedInst); + + STDVECTOR Operands = {}; + VM_OPERAND_SIZE_ENUM OpSize[3] = { VM_OPSIZE_8 }; + + for (UINT i = 0; i < OperandCount; i++) { - case XED_ICLASS_MOV: + CONST XED_OPERAND* Operand = XedInstOperand(Inst, i); + XED_OPERAND_ENUM OperandName = XedOperandName(Operand); + if (XedOperandIsRegister(OperandName) && XED_REG_RFLAGS == XedDecodedInstGetReg(DecodedInst, OperandName)) + continue; + + Operands.push_back(Operand); + OpSize[Operands.size() - 1] = (VM_OPERAND_SIZE_ENUM)(log2(XedDecodedInstOperandLength(DecodedInst, i))); + } + + for (UINT i = 0; i < Operands.size(); i++) { + CONST XED_OPERAND* Operand = Operands[i]; + XED_OPERAND_ENUM OperandName = XedOperandName(Operand); + VM_IREG_ENUM IReg = (VM_IREG_ENUM)(VM_IREG_1 + i); - return TRUE; + if (XedOperandIsRegister(OperandName)) + { + if (XedOperandRead(Operand)) + { + USHORT HandlerId = VmIRegLoadRegHandlerId(IReg); + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, HandlerId)->GetDesc(OpSize); + if (!Desc->Data) Desc->Data = VmHandlerIRegReg(IReg, OpSize[i], TRUE, &Desc->DataSize); + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = HandlerId; + Link->Flags |= CODE_FLAG_IREG_OPERATION; + Link->Reg.Register = VmXRegToVRegId(XedDecodedInstGetReg(DecodedInst, OperandName)); + VcAppendToBlock(&Prologue, Link); + } + if (XedOperandWritten(Operand)) + { + USHORT HandlerId = VmIRegStoreRegHandlerId(IReg); + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, HandlerId)->GetDesc(OpSize); + if (!Desc->Data) Desc->Data = VmHandlerIRegReg(IReg, OpSize[i], FALSE, &Desc->DataSize); + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = HandlerId; + Link->Flags |= CODE_FLAG_IREG_OPERATION; + Link->Reg.Register = VmXRegToVRegId(XedDecodedInstGetReg(DecodedInst, OperandName)); + VcAppendToBlock(&Epilogue, Link); + } + } + else if (OperandName == XED_OPERAND_MEM0/* || OperandName == XED_OPERAND_MEM1*/) + { + UINT MemOpIndex = OperandName - XED_OPERAND_MEM0; + XED_REG_ENUM Base = XedDecodedInstGetBaseReg(DecodedInst, MemOpIndex); + XED_REG_ENUM Index = XedDecodedInstGetIndexReg(DecodedInst, MemOpIndex); + UINT Scale = XedDecodedInstGetScale(DecodedInst, MemOpIndex); + LONGLONG Displacement = XedDecodedInstGetMemoryDisplacement(DecodedInst, MemOpIndex); + UINT MemOpType = VM_MEMOP_TYPE_COUNT; + if (Base != XED_REG_INVALID) MemOpType = VM_MEMOP_B; + if (Index != XED_REG_INVALID) MemOpType = VM_MEMOP_BIS; + if (Displacement != 0) MemOpType += 1; + + if (XedOperandRead(Operand)) + { + USHORT HandlerId = VmIRegLoadMemHandlerId(IReg, MemOpType); + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, HandlerId)->GetDesc(OpSize); + if (!Desc->Data) Desc->Data = VmHandlerIRegMem((VM_MEMOP_TYPE_ENUM)MemOpType, IReg, OpSize[i], TRUE, &Desc->DataSize); + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = HandlerId; + Link->Flags |= CODE_FLAG_IREG_OPERATION; + Link->Mem.Base = VmXRegToVRegId(Base); + Link->Mem.Index = VmXRegToVRegId(Index); + Link->Mem.Scale = Scale; + Link->Mem.Displacement = Displacement; + VcAppendToBlock(&Prologue, Link); + } + if (XedOperandWritten(Operand)) + { + USHORT HandlerId = VmIRegStoreMemHandlerId(IReg, MemOpType); + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, HandlerId)->GetDesc(OpSize); + if (!Desc->Data) Desc->Data = VmHandlerIRegMem((VM_MEMOP_TYPE_ENUM)MemOpType, IReg, OpSize[i], FALSE, &Desc->DataSize); + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = HandlerId; + Link->Flags |= CODE_FLAG_IREG_OPERATION; + Link->Mem.Base = VmXRegToVRegId(Base); + Link->Mem.Index = VmXRegToVRegId(Index); + Link->Mem.Scale = Scale; + Link->Mem.Displacement = Displacement; + VcAppendToBlock(&Epilogue, Link); + } + } + else if (OperandName == XED_OPERAND_IMM0) + { + USHORT HandlerId = VmIRegLoadImmHandlerId(IReg); + if (Operands.size() > 1) + OpSize[i] = OpSize[i - 1]; + else + OpSize[i] = VM_OPSIZE_64; //assume 16 for 1 operand imm instructions + + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, HandlerId)->GetDesc(OpSize); + if (!Desc->Data) Desc->Data = VmHandlerIRegImm(IReg, OpSize[i], &Desc->DataSize); + + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = HandlerId; + Link->Flags |= CODE_FLAG_IREG_OPERATION; + + if (XedDecodedInstGetImmediateIsSigned(DecodedInst)) + Link->Imm.Immediate.i64 = (INT64)XedDecodedInstGetSignedImmediate(DecodedInst); + else + Link->Imm.Immediate.u64 = XedDecodedInstGetUnsignedImmediate(DecodedInst); + + /*else + { + ULONG64 ImmRaw = xed_decoded_inst_get_unsigned_immediate(DecodedInst); + memcpy(&Link->Imm.Immediate.Raw, &ImmRaw, VmOpSizeToBytes(OpSize[i])); + }*/ + VcAppendToBlock(&Prologue, Link); + } + } + + switch (IClass) + { + default: + PVM_CODE_LINK Link = new VM_CODE_LINK(); + Link->HandlerId = IClass; + Link->Flags |= CODE_FLAG_NATIVE_OPERATION; + PVM_HANDLER_DESCRIPTOR Desc = ViGetVmHandler(Virt, IClass)->GetDesc(OpSize); + if (!Desc->Data) + { + switch (Operands.size()) + { + case 1: Desc->Data = VmHandlerEncode1(IClass, OpSize[0], &Desc->DataSize); break; + case 2: Desc->Data = VmHandlerEncode2(IClass, OpSize[0], OpSize[1], &Desc->DataSize); break; + case 3: Desc->Data = VmHandlerEncode3(IClass, OpSize[0], OpSize[1], OpSize[2], &Desc->DataSize); break; + } + } +#ifdef VM_DEBUG_INFO + Link->Debug.NativeOp.OpCount = Operands.size(); +#endif + VcAppendToBlock(&Prologue, Link); } + + if (Epilogue.Start) + { + Prologue.End->Next = Epilogue.Start; + Epilogue.Start = Prologue.End; + Prologue.End = Epilogue.End; } - return FALSE; + + Block->Start = Prologue.Start; + Block->End = Prologue.End; + + return TRUE; } \ No newline at end of file diff --git a/CodeVirtualizer/Virtualizer.h b/CodeVirtualizer/Virtualizer.h index 71600a3..2533492 100644 --- a/CodeVirtualizer/Virtualizer.h +++ b/CodeVirtualizer/Virtualizer.h @@ -5,25 +5,64 @@ #include "VmCode.h" #include "NativeCode.h" #include "VMDefs.h" +#include "VirtualMachine.h" + + +#define VM_HANDLER_DESC_COUNT (VM_OPSIZE_COUNT * VM_OPSIZE_COUNT * VM_OPSIZE_COUNT) +typedef struct _VM_HANDLER_DESCRIPTOR +{ + PUCHAR Data; + UINT DataSize; +}VM_HANDLER_DESCRIPTOR, * PVM_HANDLER_DESCRIPTOR; +typedef struct _VM_HANDLER +{ + VM_HANDLER_DESCRIPTOR Descriptors[VM_HANDLER_DESC_COUNT]; + inline _VM_HANDLER() + { + for (UINT i = 0; i < VM_HANDLER_DESC_COUNT; i++) + { + Descriptors[i].Data = NULL; + Descriptors[i].DataSize = NULL; + } + } + inline PVM_HANDLER_DESCRIPTOR Tripple(VM_OPERAND_SIZE_ENUM OpSize1, VM_OPERAND_SIZE_ENUM OpSize2, VM_OPERAND_SIZE_ENUM OpSize3) + { + return &Descriptors[(OpSize1 * (VM_OPSIZE_COUNT * VM_OPSIZE_COUNT)) + (OpSize2 * VM_OPSIZE_COUNT) + OpSize3]; + } + inline PVM_HANDLER_DESCRIPTOR Double(VM_OPERAND_SIZE_ENUM OpSize1, VM_OPERAND_SIZE_ENUM OpSize2) + { + return Tripple(OpSize1, OpSize2, VM_OPSIZE_8); + } + inline PVM_HANDLER_DESCRIPTOR Single(VM_OPERAND_SIZE_ENUM OpSize1) + { + return Tripple(OpSize1, OpSize1, VM_OPSIZE_8); + } + inline PVM_HANDLER_DESCRIPTOR GetDesc(VM_OPERAND_SIZE_ENUM* OpSize) + { + return Tripple(OpSize[0], OpSize[1], OpSize[2]); + } +}VM_HANDLER, * PVM_HANDLER; -/* -* Structure: -* -* Instructions: -* - Two byte opcode -* - -* -* Replace the code of the original code with random bytes and somewhere within it put the entry into the vm -* Put the address of the virtual function code into rax, then jmp to vmenter. -*/ typedef struct _VIRTUALIZER { - UCHAR DefaultInstructions[VM_ICLASS_COUNT]; - PNATIVE_CODE_BLOCK Block; + USHORT HandlerMap[VM_ICLASS_COUNT]; + STDVECTOR Handlers; + + inline _VIRTUALIZER() + { + Handlers.clear(); + Handlers.push_back(NULL); + + for (UINT i = 0; i < VM_ICLASS_COUNT; i++) + HandlerMap[i] = 0; + } }VIRTUALIZER, *PVIRTUALIZER; +PVM_HANDLER ViGetVmHandler(PVIRTUALIZER Virt, UINT Id); +CONST CHAR* ViIClassToString(UINT IClass); BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link); -BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block); +BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Virt, PNATIVE_CODE_BLOCK Block); +BOOL ViVirtualizeInst(PVIRTUALIZER Virt, XED_DECODED_INST* DecodedInst, PVM_CODE_BLOCK Block); #endif \ No newline at end of file diff --git a/CodeVirtualizer/VmCode.cpp b/CodeVirtualizer/VmCode.cpp index 92cb1dd..a2704c6 100644 --- a/CodeVirtualizer/VmCode.cpp +++ b/CodeVirtualizer/VmCode.cpp @@ -4,11 +4,8 @@ _VM_CODE_LINK::_VM_CODE_LINK() { Flags = 0; Next = Prev = NULL; - Label = 0; - InstData = NULL; - InstDataSize = 0UL; - PrologueData = NULL; - PrologueDataSize = 0UL; + Label = 0; + HandlerId = 0; } _VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId) @@ -16,4 +13,29 @@ _VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId) { Label = LabelId; Flags = CODE_FLAG_IS_LABEL; +} + +_VM_CODE_BLOCK::_VM_CODE_BLOCK(PVM_CODE_LINK S, PVM_CODE_LINK E) +{ + Start = S; + End = E; +} + +VOID VcAppendToBlock(PVM_CODE_BLOCK Block, PVM_CODE_LINK Link) +{ + if (!Link) + return; + + Link->Prev = Block->End; + Link->Next = NULL; + + if (!Block->End || !Block->Start) + { + Block->Start = Block->End = Link; + } + else + { + Block->End->Next = Link; + Block->End = Link; + } } \ No newline at end of file diff --git a/CodeVirtualizer/VmCode.h b/CodeVirtualizer/VmCode.h index d473243..5f03129 100644 --- a/CodeVirtualizer/VmCode.h +++ b/CodeVirtualizer/VmCode.h @@ -3,6 +3,11 @@ #include "Windas.h" #include "Code.h" +#include "VMDefs.h" + + +#define CODE_FLAG_IREG_OPERATION DefineSpecificFlag(0) +#define CODE_FLAG_NATIVE_OPERATION DefineSpecificFlag(1) typedef struct _VM_CODE_LINK { @@ -12,11 +17,26 @@ typedef struct _VM_CODE_LINK UINT Flags; UINT Label; - PUCHAR InstData; - UINT InstDataSize; - - PUCHAR PrologueData; - PUCHAR PrologueDataSize; + USHORT HandlerId; + union + { + struct + { + VM_REG_ENUM Base; + VM_REG_ENUM Index; + UINT8 Scale; + INT32 Displacement; + }Mem; + struct + { + VM_REG_ENUM Register; + }Reg; + struct + { + VM_IMM Immediate; + VM_OPERAND_SIZE_ENUM ImmSize; + }Imm; + }; _VM_CODE_LINK(); _VM_CODE_LINK(UINT LabelId); @@ -26,6 +46,11 @@ typedef struct _VM_CODE_BLOCK { PVM_CODE_LINK Start; PVM_CODE_LINK End; + _VM_CODE_BLOCK(PVM_CODE_LINK S = NULL, PVM_CODE_LINK E = NULL); }VM_CODE_BLOCK, *PVM_CODE_BLOCK; +VOID VcAppendToBlock(PVM_CODE_BLOCK Block, PVM_CODE_LINK Link); +VOID VcPrint(PVM_CODE_LINK Link); +BOOL VcEmitCodeLink(PVM_CODE_LINK Link, PUCHAR Buffer, USHORT OpCode); + #endif \ No newline at end of file diff --git a/CodeVirtualizer/Windas.h b/CodeVirtualizer/Windas.h index 9bd06ee..2cf8c7c 100644 --- a/CodeVirtualizer/Windas.h +++ b/CodeVirtualizer/Windas.h @@ -1,6 +1,8 @@ #ifndef __WINDAS_H #define __WINDAS_H +#pragma warning(disable : 26812) + #include #include #include diff --git a/CodeVirtualizer/XedWrap.cpp b/CodeVirtualizer/XedWrap.cpp index 90af4bd..357c666 100644 --- a/CodeVirtualizer/XedWrap.cpp +++ b/CodeVirtualizer/XedWrap.cpp @@ -26,6 +26,7 @@ PUCHAR XedEncodeInstructions(XED_ENCODER_INSTRUCTION* InstList, UINT InstCount, if (!XedConvertToEncoderRequest(&EncoderRequest, &InstList[i]) || XED_ERROR_NONE != (Err = XedEncode(&EncoderRequest, &EncodeBuffer[TotalSize], 15, &ReturnedSize))) { printf("Error encoding instruction: %u, %s\n", i, XedErrorEnumToString(Err)); + delete[] EncodeBuffer; return NULL; } TotalSize += ReturnedSize; diff --git a/CodeVirtualizer/XedWrap.h b/CodeVirtualizer/XedWrap.h index 538f024..a79bc0b 100644 --- a/CodeVirtualizer/XedWrap.h +++ b/CodeVirtualizer/XedWrap.h @@ -46,6 +46,11 @@ extern "C" #define XedDecodedInstGetIndexReg xed_decoded_inst_get_index_reg #define XedDecodedInstGetScale xed_decoded_inst_get_scale #define XedDecodedInstGetMemoryDisplacement xed_decoded_inst_get_memory_displacement +#define XedDecodedInstOperandLength xed_decoded_inst_operand_length +#define XedDecodedInstOperandLengthBits xed_decoded_inst_operand_length_bits +#define XedDecodedInstGetImmediateIsSigned xed_decoded_inst_get_immediate_is_signed +#define XedDecodedInstGetSignedImmediate xed_decoded_inst_get_signed_immediate +#define XedDecodedInstGetUnsignedImmediate xed_decoded_inst_get_unsigned_immediate #define XedInstOperand xed_inst_operand