parent
ff37bc98d5
commit
c610fd02d8
@ -1,22 +1,13 @@
|
||||
.CODE
|
||||
|
||||
;Machine structure
|
||||
;REGISTER = Register file(32 8 byte registers)
|
||||
;REGISTER = Instruction Pointer
|
||||
;REGISTER = Handler Table
|
||||
;
|
||||
|
||||
|
||||
ViEnter PROC
|
||||
MOV [RSP+8h],RCX
|
||||
MOV [RSP+10h],RDX
|
||||
MOV [RSP+18h],R8
|
||||
MOV [RSP+20h],R9
|
||||
mov [rsp+8h],rdi
|
||||
mov rdi,0FFFFFFFFFFFFFFFFh
|
||||
|
||||
PUSH RAX
|
||||
MOV RAX,0FFFFFFFFFFFFFFFFh
|
||||
;RAX NOW POINTER TO VMDATA STRUCT
|
||||
;store registers now
|
||||
|
||||
ret
|
||||
ViEnter ENDP
|
||||
|
||||
END
|
@ -1,18 +1,125 @@
|
||||
#ifndef __VMDEFS_H
|
||||
#define __VMDEFS_H
|
||||
|
||||
#include "Windas.h"
|
||||
|
||||
enum VM_ICLASS_ENUM : UCHAR
|
||||
union VM_IMM
|
||||
{
|
||||
UINT8 u8;
|
||||
UINT16 u16;
|
||||
UINT32 u32;
|
||||
UINT64 u64;
|
||||
|
||||
INT8 i8;
|
||||
INT16 i16;
|
||||
INT32 i32;
|
||||
INT64 i64;
|
||||
|
||||
PVOID Raw;
|
||||
};
|
||||
|
||||
enum VM_MEMOP_TYPE_ENUM : UCHAR
|
||||
{
|
||||
VM_MEMOP_B,
|
||||
VM_MEMOP_BD,
|
||||
VM_MEMOP_BIS,
|
||||
VM_MEMOP_BISD,
|
||||
VM_MEMOP_TYPE_COUNT
|
||||
};
|
||||
|
||||
enum VM_IREG_ENUM : UCHAR
|
||||
{
|
||||
VM_IREG_0,
|
||||
VM_IREG_1,
|
||||
VM_IREG_2,
|
||||
VM_IREG_COUNT,
|
||||
};
|
||||
|
||||
enum VM_OPERAND_SIZE_ENUM : UCHAR
|
||||
{
|
||||
VM_OPSIZE_1,
|
||||
VM_OPSIZE_2,
|
||||
VM_OPSIZE_4,
|
||||
VM_OPSIZE_8,
|
||||
VM_OPSIZE_COUNT
|
||||
};
|
||||
|
||||
enum VM_ICLASS_ENUM : USHORT
|
||||
{
|
||||
VM_ICLASS_ENTER,
|
||||
VM_ICLASS_EXIT,
|
||||
VM_ICLASS_MOV,
|
||||
VM_ICLASS_SX,
|
||||
VM_ICLASS_ZX,
|
||||
VM_ICLASS_ADD,
|
||||
VM_ICLASS_SUB,
|
||||
VM_ICLASS_MUL,
|
||||
VM_ICLASS_DIV,
|
||||
|
||||
//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
|
||||
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,
|
||||
|
||||
//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,
|
||||
|
||||
//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,
|
||||
|
||||
//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,
|
||||
|
||||
//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_COUNT,
|
||||
};
|
||||
|
||||
enum VM_REG_ENUM : UCHAR
|
||||
{
|
||||
VM_REG_0, //0-15 reserved for converted native registers.
|
||||
VM_REG_1,
|
||||
VM_REG_2,
|
||||
VM_REG_3,
|
||||
VM_REG_4,
|
||||
VM_REG_5,
|
||||
VM_REG_6,
|
||||
VM_REG_7,
|
||||
VM_REG_8,
|
||||
VM_REG_9,
|
||||
VM_REG_10,
|
||||
VM_REG_11,
|
||||
VM_REG_12,
|
||||
VM_REG_13,
|
||||
VM_REG_14,
|
||||
VM_REG_15,
|
||||
//VM_REG_16, //scratch registers
|
||||
//VM_REG_17,
|
||||
//VM_REG_18,
|
||||
//VM_REG_19,
|
||||
//VM_REG_20,
|
||||
//VM_REG_21,
|
||||
//VM_REG_22,
|
||||
//VM_REG_23,
|
||||
//VM_REG_24,
|
||||
//VM_REG_25,
|
||||
//VM_REG_26,
|
||||
//VM_REG_27,
|
||||
//VM_REG_28,
|
||||
//VM_REG_29,
|
||||
//VM_REG_30,
|
||||
//VM_REG_31,
|
||||
VM_REG_COUNT
|
||||
};
|
||||
|
||||
typedef struct _VM_HEADER
|
||||
{
|
||||
PVOID RegisterFile[VM_REG_COUNT];
|
||||
PVOID RegisterStorage[16];
|
||||
PVOID HandlerTable[1];
|
||||
|
||||
UINT HandlerTableSize;
|
||||
}VM_HEADER, * PVM_HEADER;
|
||||
|
||||
#endif
|
@ -0,0 +1,26 @@
|
||||
#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)
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#ifndef __VM_INST_EMITTER_H
|
||||
#define __VM_INST_EMITTER_H
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
#endif
|
@ -1,11 +1,196 @@
|
||||
#include "VirtualMachine.h"
|
||||
|
||||
|
||||
PUCHAR VmEmitVmEnter(PULONG Size)
|
||||
XED_REG_ENUM VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize)
|
||||
{
|
||||
return NULL;
|
||||
switch (OperandSize)
|
||||
{
|
||||
case VM_OPSIZE_1: return XED_REG_GPR8_FIRST;
|
||||
case VM_OPSIZE_2: return XED_REG_GPR16_FIRST;
|
||||
case VM_OPSIZE_4: return XED_REG_GPR32_FIRST;
|
||||
case VM_OPSIZE_8: return XED_REG_GPR64_FIRST;
|
||||
}
|
||||
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));
|
||||
}
|
||||
PUCHAR VmEmitVmExit(PULONG Size)
|
||||
else if (Reg >= XED_REG_GPR16_FIRST && Reg <= XED_REG_GPR16_LAST)
|
||||
{
|
||||
return NULL;
|
||||
return (XED_REG_ENUM)(VmOperandSizeToRegEnumBase(OperandSize) + (Reg - XED_REG_GPR16_FIRST));
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
XED_REG_ENUM VmIRegToXReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize)
|
||||
{
|
||||
switch (IReg)
|
||||
{
|
||||
case VM_IREG_0: return VmGetRegOfSize(XED_REG_RAX, OperandSize);
|
||||
case VM_IREG_1: return VmGetRegOfSize(XED_REG_RBX, OperandSize);
|
||||
case VM_IREG_2: return VmGetRegOfSize(XED_REG_RCX, OperandSize);
|
||||
}
|
||||
return XED_REG_INVALID;
|
||||
|
||||
//Less portable version.
|
||||
/*if (OperandSize == VM_OPSIZE_1)
|
||||
{
|
||||
return (XED_REG_ENUM)(XED_REG_AL + IReg);
|
||||
}
|
||||
return (XED_REG_ENUM)(XED_REG_AX + (16 * (OperandSize - 1)) + IReg);*/
|
||||
}
|
||||
|
||||
PUCHAR VmHandlerPrologue(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[3];
|
||||
InstructionSize += VM_HANDLER_PROLOGUE_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_PROLOGUE_SIZE)
|
||||
return Ret;
|
||||
|
||||
delete[] Ret;
|
||||
InstructionSize -= VM_HANDLER_PROLOGUE_SIZE;
|
||||
InstructionSize += *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 VmHandlerIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8,byte ptr[rdx+2]
|
||||
* mov r8, qword ptr[rbp+r8*8]
|
||||
* mov (ireg), (size) ptr[r8]
|
||||
*/
|
||||
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[2], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemB(XED_REG_R8, OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 3, OutSize);
|
||||
}
|
||||
PUCHAR VmHandlerIRegLoadMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8,byte ptr[rdx+2]
|
||||
* mov r8, qword ptr[rbp+r8*8]
|
||||
* mov r9, dword ptr[rdx+3]
|
||||
* mov (ireg), (size) ptr[r8+r9]
|
||||
*/
|
||||
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[3], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R9, 1, XedDisp(0, 0), OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 4, OutSize);
|
||||
}
|
||||
PUCHAR VmHandlerIRegLoadMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8,byte ptr[rdx+2]
|
||||
* mov r8, qword ptr[rbp+r8*8]
|
||||
* movzx r9, byte ptr[rdx+3]
|
||||
* mov r9, qword ptr[rbp+r9*8]
|
||||
* movzx r10, byte ptr[rdx+4] ;load scale value(unsigned)
|
||||
* imul r9,r10
|
||||
* mov (ireg), (size) ptr[r8+r9]
|
||||
*/
|
||||
|
||||
UINT OpSizeBits = VmOpSizeToBits(OperandSize);
|
||||
XED_ENCODER_INSTRUCTION InstList[7];
|
||||
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_MOV, 64, XedReg(XED_REG_R9), XedMemBISD(XED_REG_RBP, XED_REG_R9, 8, XedDisp(0, 0), 64));
|
||||
XedInst2(&InstList[4], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8));
|
||||
XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XED_REG_R9), XedReg(XED_REG_R10));
|
||||
XedInst2(&InstList[6], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R9, 1, XedDisp(0, 0), OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 7, OutSize);
|
||||
}
|
||||
PUCHAR VmHandlerIRegLoadMem_BISO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8, byte ptr[rdx+2]
|
||||
* mov r8, qword ptr[rbp+r8*8]
|
||||
* movzx r9, byte ptr[rdx+3]
|
||||
* mov r9, qword ptr[rbp+r9*8]
|
||||
* movzx r10, byte ptr[rdx+4] ;load scale value(unsigned)
|
||||
* imul r9, r10
|
||||
* movsxd r10, dword ptr[rdx+5] ;load immediate displacement
|
||||
* add r9, r10 ;add immediate displacement
|
||||
* mov (ireg), (size) ptr[r8+r9]
|
||||
*/
|
||||
|
||||
UINT OpSizeBits = VmOpSizeToBits(OperandSize);
|
||||
XED_ENCODER_INSTRUCTION InstList[9];
|
||||
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_MOV, 64, XedReg(XED_REG_R9), XedMemBISD(XED_REG_RBP, XED_REG_R9, 8, XedDisp(0, 0), 64));
|
||||
XedInst2(&InstList[4], XedGlobalMachineState, XED_ICLASS_MOVSX, 64, XedReg(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(4, 8), 8));
|
||||
XedInst2(&InstList[5], XedGlobalMachineState, XED_ICLASS_IMUL, 64, XedReg(XED_REG_R9), XedReg(XED_REG_R10));
|
||||
XedInst2(&InstList[6], XedGlobalMachineState, XED_ICLASS_MOVSXD, 64, XedReg(XED_REG_R10), XedMemBD(XED_REG_RDX, XedDisp(5, 8), 32));
|
||||
XedInst2(&InstList[7], XedGlobalMachineState, XED_ICLASS_ADD, 64, XedReg(XED_REG_R9), XedReg(XED_REG_R10));
|
||||
XedInst2(&InstList[8], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_R8, XED_REG_R9, 1, XedDisp(0, 0), OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 9, OutSize);
|
||||
}
|
||||
PUCHAR VmHandlerIRegLoadReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8,byte ptr[rdx+2]
|
||||
* mov (ireg), (size) ptr[rbp+r8*8]
|
||||
*/
|
||||
|
||||
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[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBISD(XED_REG_RBP, XED_REG_R8, 8, XedDisp(0, 0), OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 2, OutSize);
|
||||
}
|
||||
PUCHAR VmHandlerIRegStoreReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize)
|
||||
{
|
||||
/*
|
||||
* movzx r8,byte ptr[rdx+2]
|
||||
* mov (size) ptr[rbp+r8*8], (ireg)
|
||||
*/
|
||||
|
||||
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[1], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedMemBISD(XED_REG_RBP, XED_REG_R8, 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)
|
||||
{
|
||||
/*
|
||||
* mov (ireg), size ptr[rdx+2]
|
||||
*/
|
||||
|
||||
UINT OpSizeBits = VmOpSizeToBits(OperandSize);
|
||||
XED_ENCODER_INSTRUCTION InstList[1];
|
||||
XedInst2(&InstList[0], XedGlobalMachineState, XED_ICLASS_MOV, OpSizeBits, XedReg(VmIRegToXReg(IReg, OperandSize)), XedMemBD(XED_REG_RDX, XedDisp(2, 8), OpSizeBits));
|
||||
return XedEncodeInstructions(InstList, 1, OutSize);
|
||||
}
|
||||
|
@ -1,9 +1,44 @@
|
||||
#include "XedWrap.h"
|
||||
|
||||
VOID XedInit()
|
||||
VOID XedGlobalInit()
|
||||
{
|
||||
XedTablesInit();
|
||||
XedGlobalMachineState;
|
||||
XedGlobalMachineState.mmode = XED_MACHINE_MODE_LONG_64;
|
||||
XedGlobalMachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b;
|
||||
}
|
||||
|
||||
PUCHAR XedEncodeInstructions(XED_ENCODER_INSTRUCTION* InstList, UINT InstCount, PUINT OutSize)
|
||||
{
|
||||
XED_ENCODER_REQUEST EncoderRequest;
|
||||
UINT ReturnedSize = 0;
|
||||
UINT TotalSize = 0;
|
||||
XED_ERROR_ENUM Err = XED_ERROR_NONE;
|
||||
|
||||
*OutSize = 0;
|
||||
PUCHAR EncodeBuffer = new UCHAR[InstCount * 15];
|
||||
if (!EncodeBuffer)
|
||||
return NULL;
|
||||
|
||||
for (UINT i = 0; i < InstCount; i++)
|
||||
{
|
||||
XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState);
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
TotalSize += ReturnedSize;
|
||||
}
|
||||
|
||||
PUCHAR RetBuffer = new UCHAR[TotalSize];
|
||||
if (!RetBuffer)
|
||||
{
|
||||
delete[] EncodeBuffer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RtlCopyMemory(RetBuffer, EncodeBuffer, TotalSize);
|
||||
*OutSize = TotalSize;
|
||||
return RetBuffer;
|
||||
}
|
Loading…
Reference in new issue