messy virtualizer

main
James 3 years ago
parent 2fc4a80810
commit 3bacefeb79

@ -1,14 +1,26 @@
#ifndef __CODE_H #ifndef __CODE_H
#define __CODE_H #define __CODE_H
#define CODE_FLAG_IS_LABEL (1<<0) /*
#define CODE_FLAG_IS_REL_JMP (1<<1) * 0-15 general flags for both vm and native
#define CODE_FLAG_IS_INST (1<<2) * 16-31 for vm or native specific use.
#define CODE_FLAG_DO_NOT_DIVIDE (1<<3) */
#define CODE_FLAG_GROUP_START (1<<4) #define CODE_FLAG_GENERAL_START 0
#define CODE_FLAG_GROUP_END (1<<5) #define CODE_FLAG_SPECIFIC_START 16
#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 DefineGeneralFlag(n) (1<<((n) + CODE_FLAG_GENERAL_START))
#define CODE_FLAG_DOESNT_READ_FLAGS (1<<8) #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 #endif

@ -1,5 +0,0 @@
#include "Obfuscator.h"
//Requires either being in the process address space, or relocations

@ -157,7 +157,6 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="CodeBlocks.cpp" />
<ClCompile Include="Flags.cpp" /> <ClCompile Include="Flags.cpp" />
<ClCompile Include="NativeCode.cpp" /> <ClCompile Include="NativeCode.cpp" />
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />

@ -78,9 +78,6 @@
<ClCompile Include="Flags.cpp"> <ClCompile Include="Flags.cpp">
<Filter>Code</Filter> <Filter>Code</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CodeBlocks.cpp">
<Filter>Obfuscator</Filter>
</ClCompile>
<ClCompile Include="PEFile.cpp"> <ClCompile Include="PEFile.cpp">
<Filter>File\PEFile</Filter> <Filter>File\PEFile</Filter>
</ClCompile> </ClCompile>

@ -10,6 +10,7 @@
#include "Random.h" #include "Random.h"
#include "VirtualMachine.h" #include "VirtualMachine.h"
#include "Virtualizer.h"
__declspec(dllexport) VOID CvInit() __declspec(dllexport) VOID CvInit()
{ {
@ -187,67 +188,104 @@ UCHAR IsEvenCode[]{
//EXTERN_C UINT64 RetNum(UINT64 Num); //EXTERN_C UINT64 RetNum(UINT64 Num);
//EXTERN_C BOOL IsEven(UINT64 Num); //EXTERN_C BOOL IsEven(UINT64 Num);
int main() int main()
{ {
XedGlobalInit(); XedGlobalInit();
srand(time(NULL)); srand(time(NULL));
UINT OutSize = 0; //UINT OutSize = 0;
PUCHAR Output = VmHandlerIRegMem_BISD(VM_IREG_3, VM_OPSIZE_16, FALSE, &OutSize); // VmHandlerPrologue(8, &OutSize); //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 = VmHandlerEncode2(XED_ICLASS_MOVZX, VM_OPSIZE_32, VM_OPSIZE_16, &OutSize);
//PUCHAR Output = VmHandlerPrologue(10, &OutSize); ////PUCHAR Output = VmHandlerPrologue(10, &OutSize);
if (Output && 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;
} }
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("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("\n");
}
for (UINT i = 0; i < VM_IREG_COUNT; i++)
/*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++)
{ {
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))); 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));
}
}*/
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)));
//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); //xed_operand_values_t* Operands = xed_decoded_inst_operands(&DecodedInst);

@ -2,6 +2,8 @@
#define __VMDEFS_H #define __VMDEFS_H
#include "Windas.h" #include "Windas.h"
#include "XedWrap.h"
union VM_IMM union VM_IMM
{ {
@ -44,38 +46,41 @@ enum VM_OPERAND_SIZE_ENUM : UCHAR
VM_OPSIZE_COUNT 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 enum VM_ICLASS_ENUM : USHORT
{ {
VM_ICLASS_ENTER, VM_ICLASS_ENTER = XED_ICLASS_LAST,
VM_ICLASS_EXIT, VM_ICLASS_EXIT,
//Loading from memory into internal registers //OPSIZE IS NOW HANDLED INSIDE OF THE VM_HANDLER STRUCTURE
//Need to support 3 modes: [BASE], [BASE+OFFSET], [BASE+INDEX*SCALE+OFFSET]
//for 4 possible sizes(1,2,4,8) //Loading into ireg from memory
//for 3 possible register spots(rax,rbx,rcx
//3 * 4 * 3 = 72
VM_ICLASS_LD_IREG_MEM_START, 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 //Storing internal registers into memory
VM_ICLASS_ST_IREG_MEM_START, 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 //Loading scratch registers into internal registers
VM_ICLASS_LD_IREG_REG_START, 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 //storing internal registers into scratch registers
VM_ICLASS_ST_IREG_REG_START, 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 //Loading Immediate Values into internal registers
VM_ICLASS_LD_IREG_IMM_START, 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_LD_IREG_IMM_END = VM_ICLASS_LD_IREG_IMM_START + (VM_IREG_COUNT) - 1,
VM_ICLASS_MOV_START,
VM_ICLASS_MOV_END = VM_ICLASS_MOV_START + VM_OPSIZE_COUNT - 1,
VM_ICLASS_COUNT, VM_ICLASS_COUNT,
}; };
@ -121,9 +126,49 @@ typedef struct _VM_HEADER
{ {
PVOID RegisterFile[VM_REG_COUNT]; PVOID RegisterFile[VM_REG_COUNT];
PVOID RegisterStorage[16]; PVOID RegisterStorage[16];
PVOID HandlerTable[1]; PVOID FlagsStorage;
UINT HandlerTableSize; UINT HandlerTableSize;
PVOID HandlerTable[1];
}VM_HEADER, * PVM_HEADER; }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 #endif

@ -1,26 +1,28 @@
#include "VirtualInstructionEmitter.h" #include "VirtualInstructionEmitter.h"
//
PVM_CODE_LINK VmEmitterIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base) //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;
PVM_CODE_LINK VmEmitterIRegLoadMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base, VM_IMM Offset) // 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)
} //{
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) //
{ //}
//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)
} //{
PVM_CODE_LINK VmEmitterIRegLoadReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg) //
{ //}
//PUCHAR VmEmitterIRegLoadReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize)
} //{
PVM_CODE_LINK VmEmitterIRegStoreReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg) //
{ //}
//PUCHAR VmEmitterIRegStoreReg(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Reg, PUINT OutSize)
} //{
PVM_CODE_LINK VmEmitterIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate) //
{ //}
//PUCHAR VmEmitterIRegLoadImm(UINT16 OpCode, VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_IMM Immediate, PUINT OutSize)
} //{
//
//}

@ -4,12 +4,16 @@
#include "VmCode.h" #include "VmCode.h"
#include "VMDefs.h" #include "VMDefs.h"
PVM_CODE_LINK VmEmitterIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, VM_REG_ENUM Base); //Im thinking these can all be macros.
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);
//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 #endif

@ -12,28 +12,30 @@ XED_REG_ENUM VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize)
} }
return XED_REG_INVALID; return XED_REG_INVALID;
} }
XED_REG_ENUM VmGetRegOfSize(XED_REG_ENUM Reg, VM_OPERAND_SIZE_ENUM OperandSize) XED_REG_ENUM VmGetRegOfSize(XED_REG_ENUM Reg, VM_OPERAND_SIZE_ENUM OperandSize)
{ {
if (Reg >= XED_REG_GPR8_FIRST && Reg <= XED_REG_GPR8_LAST) if (Reg >= XED_REG_GPR8_FIRST && Reg <= XED_REG_GPR8_LAST)
{
return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR8_FIRST)); return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR8_FIRST));
}
else if (Reg >= XED_REG_GPR16_FIRST && Reg <= XED_REG_GPR16_LAST) else if (Reg >= XED_REG_GPR16_FIRST && Reg <= XED_REG_GPR16_LAST)
{
return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR16_FIRST)); return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR16_FIRST));
}
else if (Reg >= XED_REG_GPR32_FIRST && Reg <= XED_REG_GPR32_LAST) else if (Reg >= XED_REG_GPR32_FIRST && Reg <= XED_REG_GPR32_LAST)
{
return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR32_FIRST)); return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR32_FIRST));
}
else if (Reg >= XED_REG_GPR64_FIRST && Reg <= XED_REG_GPR64_LAST) 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_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR64_FIRST));
}
return XED_REG_INVALID; 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) XED_REG_ENUM VmIRegToXReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize)
{ {
switch (IReg) 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);*/ 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 // add rdx, InstructionSize + Prologue Size
// movzx r8,byte ptr[rdx] // movzx r8,byte ptr[rdx]
// jmp qword ptr[rsi+r8*8h] // jmp qword ptr[rsi+r8*8h]
XED_ENCODER_INSTRUCTION InstList[5]; XED_ENCODER_INSTRUCTION InstList[3];
InstructionSize += VM_HANDLER_PROLOGUE_SIZE; InstructionSize += VM_HANDLER_EPILOGUE_SIZE;
XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32));
XedInst2(&InstList[1], 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));
XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); XedInst1(&InstList[2], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64));
XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); PUCHAR Ret = XedEncodeInstructions(InstList, 3, OutSize);
XedInst1(&InstList[4], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64)); if (*OutSize == VM_HANDLER_EPILOGUE_SIZE)
PUCHAR Ret = XedEncodeInstructions(InstList, 5, OutSize);
if (*OutSize == VM_HANDLER_PROLOGUE_SIZE)
return Ret; return Ret;
delete[] Ret; delete[] Ret;
InstructionSize -= VM_HANDLER_PROLOGUE_SIZE; InstructionSize -= VM_HANDLER_EPILOGUE_SIZE;
InstructionSize += *OutSize; InstructionSize += *OutSize;
XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(Vip), XedImm0(InstructionSize, 32));
XedInst2(&InstList[1], 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));
XedInst0(&InstList[2], XedGlobalMachineState, XED_ICLASS_POPFQ, 64); XedInst1(&InstList[2], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64));
XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVZX, 64, XedReg(XED_REG_R8), XedMemB(Vip, 16)); return XedEncodeInstructions(InstList, 3, OutSize);
XedInst1(&InstList[4], XedGlobalMachineState, XED_ICLASS_JMP, 64, XedMemBISD(HandlerTableReg, XED_REG_R8, 8, XedDisp(0, 0), 64));
return XedEncodeInstructions(InstList, 5, 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] * 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); UINT OpSizeBits = VmOpSizeToBits(OperandSize);
XED_ENCODER_INSTRUCTION InstList[3]; 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[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(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0,0), 64)); XedInst2(&InstList[1], XedGlobalMachineState, XED_ICLASS_MOV, 64, XedReg(XReg1), XedMemBISD(XED_REG_RBP, XReg1, 8, XedDisp(0,0), 64));
if (Load) 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 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); 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] * 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); UINT OpSizeBits = VmOpSizeToBits(OperandSize);
XED_ENCODER_INSTRUCTION InstList[4]; 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[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(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), 64)); 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(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 32)); XedInst2(&InstList[2], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XReg2), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 32));
if (Load) 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 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); 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] * movzx r8,byte ptr[rdx+2]
* mov r8, qword ptr[rbp+r8*8] * mov r8, qword ptr[rbp+r8*8]
* movzx r9, byte ptr[rdx+3] * movzx r9, byte ptr[rdx+3]
* movzx r10, byte ptr[rdx+4] ;load scale value(unsigned) * movzx r10, byte ptr[rdx+4] ;load scale value(unsigned)
* pushfq
* imul r10, qword ptr[rbp+r9*8] * imul r10, qword ptr[rbp+r9*8]
* popfq
* mov (ireg), (size) ptr[r8+r10] * mov (ireg), (size) ptr[r8+r10]
*/ */
UINT OpSizeBits = VmOpSizeToBits(OperandSize); UINT OpSizeBits = VmOpSizeToBits(OperandSize);
XED_ENCODER_INSTRUCTION InstList[8]; XED_ENCODER_INSTRUCTION InstList[6];
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));
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[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(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); 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(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg3), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8));
XedInst0(&InstList[4], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); 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_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);
if (Load) 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 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))); XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XReg1, XReg3, 1, XedDisp(0, 0), OpSizeBits), XedReg(VmIRegToXReg(IReg, OperandSize)));
return XedEncodeInstructions(InstList, 8, OutSize); 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] * movzx r8, byte ptr[rdx+2]
* mov r8, qword ptr[rbp+r8*8] * mov r8, qword ptr[rbp+r8*8]
* movzx r9, byte ptr[rdx+3] * movzx r9, byte ptr[rdx+3]
* movzx r10, byte ptr[rdx+4] ;load scale value(unsigned) * movzx r10, byte ptr[rdx+4] ;load scale value(unsigned)
* pushfq
* imul r10, qword ptr[rbp+r9*8] * imul r10, qword ptr[rbp+r9*8]
* movsxd r9, dword ptr[rdx+5] ;load immediate displacement * movsxd r9, dword ptr[rdx+5] ;load immediate displacement
* add r10, r9 ;add immediate displacement * add r10, r9 ;add immediate displacement
* popfq
* mov (ireg), (size) ptr[r8+r10] * mov (ireg), (size) ptr[r8+r10]
*/ */
UINT OpSizeBits = VmOpSizeToBits(OperandSize); UINT OpSizeBits = VmOpSizeToBits(OperandSize);
XED_ENCODER_INSTRUCTION InstList[10]; 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[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(XED_REG_R8), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), 64)); 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(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(3, 8), 8)); 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(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8)); XedInst2(&InstList[3], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XReg3), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8));
XedInst0(&InstList[4], XedGlobalMachineState, XED_ICLASS_PUSHFQ, 64); 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_IMUL, 64, XedReg(XED_REG_R10), XedMemBISD(XED_REG_RBP, XED_REG_R9, 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_MOVSXD, 64, XedReg(XED_REG_R9), XedMemBD(XED_REG_RDX, XedDisp(5, 8), 32)); XedInst2(&InstList[6], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(XReg3), XedReg(XReg2));
XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(XED_REG_R10), XedReg(XED_REG_R9));
XedInst0(&InstList[8], XedGlobalMachineState, XED_ICLASS_POPFQ, 64);
if (Load) 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 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] * 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); UINT OpSizeBits = VmOpSizeToBits(OperandSize);
XED_ENCODER_INSTRUCTION InstList[2]; 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) 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 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); 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] * 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); 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) PUCHAR VmHandlerEncode1(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
{ {
XED_ENCODER_INSTRUCTION InstList; XED_ENCODER_INSTRUCTION InstList[3];
XedInst1(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize))); XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64);
return XedEncodeInstructions(&InstList, 1, OutSize); 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) PUCHAR VmHandlerEncode2(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, PUINT OutSize)
{ {
XED_ENCODER_INSTRUCTION InstList; XED_ENCODER_INSTRUCTION InstList[3];
XedInst2(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2))); XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64);
return XedEncodeInstructions(&InstList, 1, OutSize); 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) 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; XED_ENCODER_INSTRUCTION InstList[3];
XedInst3(&InstList, XedGlobalMachineState, IClass, VmOpSizeToBits(OperandSize1), XedReg(VmIRegToXReg(VM_IREG_1, OperandSize1)), XedReg(VmIRegToXReg(VM_IREG_2, OperandSize2)), XedReg(VmIRegToXReg(VM_IREG_3, OperandSize3))); XedInst0(&InstList[0], XedGlobalMachineState, XED_ICLASS_POPFQ, 64);
return XedEncodeInstructions(&InstList, 1, OutSize); 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);
} }

@ -7,19 +7,9 @@
#include "NativeCode.h" #include "NativeCode.h"
#include "VmCode.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 VmOpSizeToBytes(OpSize) (pow(2, (UCHAR)OpSize))
#define VmOpSizeToBits(OpSize) (VmOpSizeToBytes(OpSize) * 8) #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: * Vm Structure:
@ -30,6 +20,7 @@ inline PUCHAR DefaultInstBuffers[XED_ICLASS_LAST * VM_OPSIZE_COUNT] = { NULL };
* RAX = IREG0 * RAX = IREG0
* RBX = IREG1 * RBX = IREG1
* RCX = IREG2 * RCX = IREG2
* RSP = Storage for flags inside of VM_HEADER
* *
* R8 = Not ever saved. Uses: HandlerJmp, * R8 = Not ever saved. Uses: HandlerJmp,
* R9, R10 = Not saved. Uses: Temp storage inside handlers for IReg access. * 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 VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize);
XED_REG_ENUM VmGetRegOfSize(XED_REG_ENUM Reg, 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); 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 CONST CHAR* VmIClassToString(VM_ICLASS_ENUM IClass);
PUCHAR VmHandlerPrologue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip = XED_REG_RDX, XED_REG_ENUM HandlerTableReg = XED_REG_RSI);
//Internal register(IReg) store/load //Internal register(IReg) store/load
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 = XED_REG_R8);
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_R8, XED_REG_ENUM XReg2 = XED_REG_R9);
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_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); 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 VmHandlerIRegReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, BOOL Load, PUINT 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_R8, XED_REG_ENUM XReg2 = XED_REG_R9, XED_REG_ENUM XReg3 = XED_REG_R10);
PUCHAR VmHandlerIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); 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 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 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); PUCHAR VmHandlerEncode3(XED_ICLASS_ENUM IClass, VM_OPERAND_SIZE_ENUM OperandSize1, VM_OPERAND_SIZE_ENUM OperandSize2, VM_OPERAND_SIZE_ENUM OperandSize3, PUINT OutSize);

@ -1,16 +1,39 @@
#include "Virtualizer.h" #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) BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link)
{ {
switch (XedDecodedInstGetIClass(&Link->XedInstruction)) switch (XedDecodedInstGetIClass(&Link->XedInstruction))
{ {
case XED_ICLASS_MOV: case XED_ICLASS_MOV:
return TRUE; return TRUE;
} }
return FALSE; 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) 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; 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); VM_CODE_BLOCK Prologue = { };
switch (IClass) VM_CODE_BLOCK Epilogue = { };
CONST XED_INST* Inst = XedDecodedInstInst(DecodedInst);
UINT OperandCount = XedDecodedInstNumOperands(DecodedInst);
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(DecodedInst);
STDVECTOR<CONST XED_OPERAND*> 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);
} }
return FALSE; }
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;
}
Block->Start = Prologue.Start;
Block->End = Prologue.End;
return TRUE;
} }

@ -5,25 +5,64 @@
#include "VmCode.h" #include "VmCode.h"
#include "NativeCode.h" #include "NativeCode.h"
#include "VMDefs.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 typedef struct _VIRTUALIZER
{ {
UCHAR DefaultInstructions[VM_ICLASS_COUNT]; USHORT HandlerMap[VM_ICLASS_COUNT];
PNATIVE_CODE_BLOCK Block; STDVECTOR<PVM_HANDLER> Handlers;
inline _VIRTUALIZER()
{
Handlers.clear();
Handlers.push_back(NULL);
for (UINT i = 0; i < VM_ICLASS_COUNT; i++)
HandlerMap[i] = 0;
}
}VIRTUALIZER, *PVIRTUALIZER; }VIRTUALIZER, *PVIRTUALIZER;
PVM_HANDLER ViGetVmHandler(PVIRTUALIZER Virt, UINT Id);
CONST CHAR* ViIClassToString(UINT IClass);
BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link); 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 #endif

@ -5,10 +5,7 @@ _VM_CODE_LINK::_VM_CODE_LINK()
Flags = 0; Flags = 0;
Next = Prev = NULL; Next = Prev = NULL;
Label = 0; Label = 0;
InstData = NULL; HandlerId = 0;
InstDataSize = 0UL;
PrologueData = NULL;
PrologueDataSize = 0UL;
} }
_VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId) _VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId)
@ -17,3 +14,28 @@ _VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId)
Label = LabelId; Label = LabelId;
Flags = CODE_FLAG_IS_LABEL; 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;
}
}

@ -3,6 +3,11 @@
#include "Windas.h" #include "Windas.h"
#include "Code.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 typedef struct _VM_CODE_LINK
{ {
@ -12,11 +17,26 @@ typedef struct _VM_CODE_LINK
UINT Flags; UINT Flags;
UINT Label; UINT Label;
PUCHAR InstData; USHORT HandlerId;
UINT InstDataSize; union
{
PUCHAR PrologueData; struct
PUCHAR PrologueDataSize; {
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();
_VM_CODE_LINK(UINT LabelId); _VM_CODE_LINK(UINT LabelId);
@ -26,6 +46,11 @@ typedef struct _VM_CODE_BLOCK
{ {
PVM_CODE_LINK Start; PVM_CODE_LINK Start;
PVM_CODE_LINK End; PVM_CODE_LINK End;
_VM_CODE_BLOCK(PVM_CODE_LINK S = NULL, PVM_CODE_LINK E = NULL);
}VM_CODE_BLOCK, *PVM_CODE_BLOCK; }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 #endif

@ -1,6 +1,8 @@
#ifndef __WINDAS_H #ifndef __WINDAS_H
#define __WINDAS_H #define __WINDAS_H
#pragma warning(disable : 26812)
#include <Windows.h> #include <Windows.h>
#include <string> #include <string>
#include <vector> #include <vector>

@ -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))) 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)); printf("Error encoding instruction: %u, %s\n", i, XedErrorEnumToString(Err));
delete[] EncodeBuffer;
return NULL; return NULL;
} }
TotalSize += ReturnedSize; TotalSize += ReturnedSize;

@ -46,6 +46,11 @@ extern "C"
#define XedDecodedInstGetIndexReg xed_decoded_inst_get_index_reg #define XedDecodedInstGetIndexReg xed_decoded_inst_get_index_reg
#define XedDecodedInstGetScale xed_decoded_inst_get_scale #define XedDecodedInstGetScale xed_decoded_inst_get_scale
#define XedDecodedInstGetMemoryDisplacement xed_decoded_inst_get_memory_displacement #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 #define XedInstOperand xed_inst_operand

Loading…
Cancel
Save