From c610fd02d89375cc77f42a46ab9ea97a9d529b6d Mon Sep 17 00:00:00 2001 From: Iizerd Date: Thu, 30 Dec 2021 02:16:14 -0800 Subject: [PATCH] started vm --- CodeVirtualizer/CodeVirtualizer.h | 2 +- CodeVirtualizer/CodeVirtualizer.vcxproj | 2 + .../CodeVirtualizer.vcxproj.filters | 6 + CodeVirtualizer/Main.cpp | 137 +++++++------ CodeVirtualizer/NativeCode.cpp | 63 +++--- CodeVirtualizer/NativeCode.h | 26 +-- CodeVirtualizer/Obfuscator.cpp | 12 +- CodeVirtualizer/Obfuscator.h | 8 +- CodeVirtualizer/OpaqueBranching.cpp | 20 +- CodeVirtualizer/PEFile.cpp | 2 +- CodeVirtualizer/Random.cpp | 2 +- CodeVirtualizer/RipMovInst.cpp | 18 +- CodeVirtualizer/VMAssembly.asm | 17 +- CodeVirtualizer/VMDefs.h | 123 ++++++++++- CodeVirtualizer/VirtualInstructionEmitter.cpp | 26 +++ CodeVirtualizer/VirtualInstructionEmitter.h | 15 ++ CodeVirtualizer/VirtualMachine.cpp | 193 +++++++++++++++++- CodeVirtualizer/VirtualMachine.h | 48 +++-- CodeVirtualizer/Virtualizer.cpp | 24 ++- CodeVirtualizer/Virtualizer.h | 27 +-- CodeVirtualizer/VmCode.cpp | 8 +- CodeVirtualizer/VmCode.h | 14 +- CodeVirtualizer/Windas.h | 1 + CodeVirtualizer/XedWrap.cpp | 37 +++- CodeVirtualizer/XedWrap.h | 10 +- 25 files changed, 616 insertions(+), 225 deletions(-) create mode 100644 CodeVirtualizer/VirtualInstructionEmitter.cpp create mode 100644 CodeVirtualizer/VirtualInstructionEmitter.h diff --git a/CodeVirtualizer/CodeVirtualizer.h b/CodeVirtualizer/CodeVirtualizer.h index 6a170c6..fe79204 100644 --- a/CodeVirtualizer/CodeVirtualizer.h +++ b/CodeVirtualizer/CodeVirtualizer.h @@ -6,7 +6,7 @@ __declspec(dllexport) VOID CvInit(); -__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize, PULONG OutSize, ULONG BranchCount, FLOAT MaxBranchSizePercentage); +__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, UINT CodeSize, PUINT OutSize, UINT BranchCount, FLOAT MaxBranchSizePercentage); __declspec(dllexport) VOID CvDeleteCode(PVOID Code); diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj b/CodeVirtualizer/CodeVirtualizer.vcxproj index 76146e3..2e0176f 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj @@ -172,6 +172,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters index 4608faa..78ec70e 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters @@ -39,6 +39,9 @@ File\Symbols + + Virtualizer\VM + @@ -87,6 +90,9 @@ Obfuscator + + Virtualizer\VM + diff --git a/CodeVirtualizer/Main.cpp b/CodeVirtualizer/Main.cpp index 3eec1d0..0bcfa37 100644 --- a/CodeVirtualizer/Main.cpp +++ b/CodeVirtualizer/Main.cpp @@ -9,13 +9,15 @@ #include "Obfuscator.h" #include "Random.h" +#include "VirtualMachine.h" + __declspec(dllexport) VOID CvInit() { XedTablesInit(); srand(time(NULL)); } -__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize, PULONG OutSize, ULONG BranchCount, FLOAT MaxBranchSizePercentage) +__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, UINT CodeSize, PUINT OutSize, UINT BranchCount, FLOAT MaxBranchSizePercentage) { //trip 0xCC alignment at end of code while (((PUCHAR)Code)[CodeSize - 1] == 0xCC) @@ -49,7 +51,7 @@ __declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize Obf.RandomizeSpaceBetweenBranches = TRUE; Obf.BranchRemainingInstructions = TRUE; Obf.BranchChance = 75; - ULONG BranchesMade = */ + UINT BranchesMade = */ while (BranchCount) { @@ -70,7 +72,7 @@ __declspec(dllexport) VOID CvDeleteCode(PVOID Code) } -VOID PrintByteArr(PVOID Buff, ULONG BufSize) +VOID PrintByteArr(PVOID Buff, UINT BufSize) { for (uint32_t i = 0; i < BufSize; i++) { @@ -78,7 +80,7 @@ VOID PrintByteArr(PVOID Buff, ULONG BufSize) } } -PVOID MakeExecutableBuffer(PVOID Buffer, ULONG BufferSize) +PVOID MakeExecutableBuffer(PVOID Buffer, UINT BufferSize) { PVOID ExecBuffer = VirtualAlloc(nullptr, BufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!ExecBuffer) @@ -90,7 +92,7 @@ PVOID MakeExecutableBuffer(PVOID Buffer, ULONG BufferSize) return ExecBuffer; } -VOID PutToFile(PVOID Buffer, ULONG BufferSize) +VOID PutToFile(PVOID Buffer, UINT BufferSize) { std::ofstream fout; // @@ -100,12 +102,12 @@ VOID PutToFile(PVOID Buffer, ULONG BufferSize) fout.close(); } -ULONG64 TestShelcode(ULONG64 v1, ULONG64 v2, ULONG64 v3, ULONG64 v4) +UINT64 TestShelcode(UINT64 v1, UINT64 v2, UINT64 v3, UINT64 v4) { if (v4 == 0) v4 = 2; - ULONG64 Value = 1; + UINT64 Value = 1; for (int i = 1; i <= v1; i++) { Value *= i; @@ -117,7 +119,7 @@ ULONG64 TestShelcode(ULONG64 v1, ULONG64 v2, ULONG64 v3, ULONG64 v4) return Value; } -ULONG64 Nextfunction(ULONG64 v1) +UINT64 Nextfunction(UINT64 v1) { return v1 + 1; } @@ -139,7 +141,7 @@ UCHAR TestBuffer[] = { 0x48, 0x87, 0x04, 0x24, 0xC3, }; -ULONG TestBufferSize = sizeof(TestBuffer); +UINT TestBufferSize = sizeof(TestBuffer); UCHAR meme1[] = { 0x31, 0xc0, @@ -182,56 +184,69 @@ UCHAR IsEvenCode[]{ 0xC3, }; -//EXTERN_C ULONG64 RetNum(ULONG64 Num); -//EXTERN_C BOOL IsEven(ULONG64 Num); +//EXTERN_C UINT64 RetNum(UINT64 Num); +//EXTERN_C BOOL IsEven(UINT64 Num); int main() { XedGlobalInit(); srand(time(NULL)); - UCHAR TestCode[] = { 0x48, 0x8B, 0x84, 0xD1, 0xF0, 0x06, 0x00, 0x00 }; // { 0x48, 0x89, 0xC8 }; - XED_DECODED_INST DecodedInst; - XedDecodedInstZeroSetMode(&DecodedInst, &XedGlobalMachineState); - //XedDecodedInstZero(&DecodedInst); - //XedDecodedInstSetMode(&DecodedInst, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b); - XED_ERROR_ENUM Err = XedDecode(&DecodedInst, TestCode, sizeof(TestCode)); - if (Err != XED_ERROR_NONE) + + UINT OutSize = 0; + PUCHAR Output = VmHandlerIRegLoadMem_BISO(VM_IREG_2, VM_OPSIZE_2, &OutSize); // VmHandlerPrologue(8, &OutSize); + if (Output && OutSize) { - printf("Failed to decode.\n"); - system("pause"); - return -1; + PrintByteArr(Output, OutSize); } - XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&DecodedInst); - printf("IClass: %s\n", XedIClassEnumToString(IClass)); + printf("\n"); - - - CONST xed_inst_t* Inst = XedDecodedInstInst(&DecodedInst); - ULONG OperandCount = XedDecodedInstNumOperands(&DecodedInst); - - for (ULONG i = 0; i < OperandCount; i++) + for (UINT i = 0; i < VM_IREG_COUNT; 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) - { - ULONG 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", xed_decoded_inst_get_scale(&DecodedInst, MemOpIndex)); - printf("Disp: %llu\n", xed_decoded_inst_get_memory_displacement(&DecodedInst, MemOpIndex)); - } + printf("IReg: %u, %s %s %s %s\n", i, XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_1)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_2)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_4)), XedRegEnumToString(VmIRegToXReg((VM_IREG_ENUM)i, VM_OPSIZE_8))); } + printf("Reg2: %s %s %s %s\n", XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_1)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_2)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_4)), XedRegEnumToString(VmGetRegOfSize(XED_REG_R15, VM_OPSIZE_8))); + //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); //printf("Operand Count %u\n", OperandCount); @@ -246,9 +261,9 @@ int main() //CvInit(); - ////ULONG Delta = (*((PULONG)((PUCHAR)TestShelcode + 1))) + 5; + ////UINT Delta = (*((PUINT)((PUCHAR)TestShelcode + 1))) + 5; ////printf("Delta: %X\n", Delta); - //PVOID ActualFunction = TestShelcode; // (PVOID)((ULONG64)TestShelcode + Delta); + //PVOID ActualFunction = TestShelcode; // (PVOID)((UINT64)TestShelcode + Delta); //printf("%llu %llu %llu %llu\n", TestShelcode(1, 2, 3, 4), TestShelcode(20, 20, 20, 4), TestShelcode(50, 50, 50, 0), Nextfunction(12)); //system("pause"); @@ -286,7 +301,7 @@ int main() //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); //printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock)); - //ULONG AsmSize; + //UINT AsmSize; //PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); //if (!Asm) //{ @@ -297,7 +312,7 @@ int main() //PutToFile(Asm, AsmSize); //system("pause"); - /*ULONG AsmSize; + /*UINT AsmSize; PVOID Asm = CvDriverFunctionObfuscate(MemeBlock, 110, &AsmSize, 5, 0.5); if (!Asm) { @@ -308,7 +323,7 @@ int main() PutToFile(Asm, AsmSize); - typedef ULONG64(*FnTestShelcode)(ULONG64, ULONG64, ULONG64, ULONG64); + typedef UINT64(*FnTestShelcode)(UINT64, UINT64, UINT64, UINT64); PVOID Exec = NULL; Exec = MakeExecutableBuffer(Asm, AsmSize); if (!Exec) @@ -321,7 +336,7 @@ int main() /*PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); - typedef ULONG64(*FnRetNum)(ULONG Num); + typedef UINT64(*FnRetNum)(UINT Num); printf("\n\nSize: %u Obfuscated: %llu Original: %llu\n\n", NcCountInstructions(&RetNumBlock), ((FnRetNum)Exec)(1776), ((FnRetNum)Exec)(1776)); NcDeleteBlock(&RetNumBlock); @@ -339,15 +354,15 @@ int main() ObfObfuscate(&Obf, &Block); NcDebugPrint(&Block); - ULONG ByteSize = NcCalcBlockSizeInBytes(&Block); - ULONG InstSize = NcCountInstructions(&Block); + UINT ByteSize = NcCalcBlockSizeInBytes(&Block); + UINT InstSize = NcCountInstructions(&Block); printf("Bytes: %u, Insts: %u, FlagsMeme: %u.\n", ByteSize, InstSize, Obf.Flags); - ULONG AsmSize; + UINT AsmSize; PVOID Asm = NcAssemble(&Block, &AsmSize); PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); - typedef ULONG(*FnGetFour)(); + typedef UINT(*FnGetFour)(); printf("numba is: %u size is %u\n\n", ((FnGetFour)Exec)(), AsmSize); PutToFile(Asm, AsmSize);*/ @@ -371,14 +386,14 @@ int main() ///*Pre->Start = Return1776; //Pre->End = Return1776;*/ - //for (ULONG i = 0; i < Return1776->RawDataSize; i++) + //for (UINT i = 0; i < Return1776->RawDataSize; i++) // Return1776->RawData[i] = (UCHAR)rand(); - //for (ULONG i = 0; i < RetInst->RawDataSize; i++) + //for (UINT i = 0; i < RetInst->RawDataSize; i++) // RetInst->RawData[i] = (UCHAR)rand(); - //ULONG AsmLen; + //UINT AsmLen; //PVOID Asm = NcAssemble(Pre1, &AsmLen); //PUCHAR Tb = (PUCHAR)Asm; //for (uint32_t i = 0; i < AsmLen; i++) @@ -388,7 +403,7 @@ int main() //system("pause"); - //typedef ULONG64(*FnGet1776)(); + //typedef UINT64(*FnGet1776)(); //FnGet1776 ExecBuffer = (FnGet1776)MakeExecutableBuffer(Asm, AsmLen); //if (ExecBuffer) //{ @@ -411,7 +426,7 @@ int main() PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme1, sizeof(meme1)); NcInsertLinkBefore(Block.End->Prev->Prev->Prev->Prev, NewLink); - ULONG AssembledSize; + UINT AssembledSize; PVOID AssembledBlock = NcAssemble(&Block, &AssembledSize); if (!AssembledBlock || !AssembledSize) { diff --git a/CodeVirtualizer/NativeCode.cpp b/CodeVirtualizer/NativeCode.cpp index a166341..e935306 100644 --- a/CodeVirtualizer/NativeCode.cpp +++ b/CodeVirtualizer/NativeCode.cpp @@ -3,8 +3,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK() { - XedDecodedInstZero(&XedInstruction); - XedDecodedInstSetMode(&XedInstruction, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b); + XedDecodedInstZeroSetMode(&XedInstruction, &XedGlobalMachineState); Flags = 0UL; Next = Prev = NULL; Block = NULL; @@ -14,7 +13,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK() AsmOperations.clear(); } -_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B) +_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(UINT LabelId, _NATIVE_CODE_BLOCK* B) : _NATIVE_CODE_LINK() { Block = B; @@ -22,7 +21,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B) Flags = CODE_FLAG_IS_LABEL; } -_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode) +_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(UINT F, PVOID Rd, UINT Rds, BOOL Decode) : _NATIVE_CODE_LINK() { Flags = F; @@ -129,9 +128,9 @@ VOID NcUnlink(PNATIVE_CODE_LINK Link) } } -ULONG NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne) +UINT NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne) { - ULONG InstructionCount = 0; + UINT InstructionCount = 0; for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) { if (T->Flags & CODE_FLAG_IS_LABEL) @@ -143,9 +142,9 @@ ULONG NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne) return InstructionCount; } -ULONG NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block) +UINT NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block) { - ULONG TotalSize = 0; + UINT TotalSize = 0; for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) { if (T->Flags & CODE_FLAG_IS_LABEL) @@ -155,16 +154,16 @@ ULONG NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block) return TotalSize; } -ULONG NcGenUnusedLabelId(PNATIVE_CODE_BLOCK Block) +UINT NcGenUnusedLabelId(PNATIVE_CODE_BLOCK Block) { - ULONG ReturnLabelId = rand(); + UINT ReturnLabelId = rand(); while (StdFind(Block->LabelIds.begin(), Block->LabelIds.end(), ReturnLabelId) != Block->LabelIds.end()) ReturnLabelId = rand(); Block->LabelIds.push_back(ReturnLabelId); return ReturnLabelId; } -VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block, ULONG Original, ULONG New) +VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block, UINT Original, UINT New) { for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) { @@ -256,7 +255,7 @@ BOOL NcInsertBlockStartToEnd(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNA BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) { - ULONG CurrentLabelId = 0; + UINT CurrentLabelId = 0; for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next) { if (!(T->Flags & CODE_FLAG_IS_INST)) @@ -266,7 +265,7 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) if (Category != XED_CATEGORY_COND_BR && Category != XED_CATEGORY_UNCOND_BR) continue; - ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); + UINT OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); if (OperandCount < 1) continue; @@ -382,7 +381,7 @@ BOOL NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNAT Block->LabelIds.clear(); Block->Start = Block->End = NULL; - for (ULONG L : Start->Block->LabelIds) + for (UINT L : Start->Block->LabelIds) Block->LabelIds.push_back(L); for (PNATIVE_CODE_LINK CurLink = Start; CurLink && CurLink != End->Next; CurLink = CurLink->Next) @@ -409,17 +408,14 @@ BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link) if (XedDecodedInstGetBranchDisplacementWidth(&Link->XedInstruction) == 32) return TRUE; - XED_STATE MachineState; - MachineState.mmode = XED_MACHINE_MODE_LONG_64; - MachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b; XED_ENCODER_INSTRUCTION EncoderInstruction; XED_ENCODER_REQUEST EncoderRequest; UCHAR EncodeBuffer[15]; UINT ReturnedSize; XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Link->XedInstruction); - XedInst1(&EncoderInstruction, MachineState, IClass, 32, XedRelBr(0, 32)); - XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); + XedInst1(&EncoderInstruction, XedGlobalMachineState, IClass, 32, XedRelBr(0, 32)); + XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState); if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) return FALSE; @@ -432,7 +428,7 @@ BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link) Link->RawData = new UCHAR[ReturnedSize]; RtlCopyMemory(Link->RawData, EncodeBuffer, ReturnedSize); - XedDecodedInstZeroSetMode(&Link->XedInstruction, &MachineState); + XedDecodedInstZeroSetMode(&Link->XedInstruction, &XedGlobalMachineState); if (XED_ERROR_NONE != XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize)) return FALSE; @@ -536,7 +532,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) if (!NcGetDeltaToLabel(T, &BranchDisp)) return FALSE; - ULONG DispWidth = XedDecodedInstGetBranchDisplacementWidthBits(&T->XedInstruction); + UINT DispWidth = XedDecodedInstGetBranchDisplacementWidthBits(&T->XedInstruction); if (log2(abs(BranchDisp)) + 1 > DispWidth) { //duh oh @@ -545,10 +541,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) DispWidth = 32; - //Encode new instruction - XED_STATE MachineState; - MachineState.mmode = XED_MACHINE_MODE_LONG_64; - MachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b; + //Encode new instruction XED_ENCODER_INSTRUCTION EncoderInstruction; XED_ENCODER_REQUEST EncoderRequest; UCHAR EncodeBuffer[15]; @@ -556,8 +549,8 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInstruction); //Do the encoding - XedInst1(&EncoderInstruction, MachineState, IClass, DispWidth, XedRelBr(0, DispWidth)); - XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); + XedInst1(&EncoderInstruction, XedGlobalMachineState, IClass, DispWidth, XedRelBr(0, DispWidth)); + XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState); if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) return FALSE; XED_ERROR_ENUM Err = XedEncode(&EncoderRequest, EncodeBuffer, 15, &ReturnedSize); @@ -571,7 +564,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) RtlCopyMemory(T->RawData, EncodeBuffer, ReturnedSize); //Decode instruction so its proper and all that - XedDecodedInstZeroSetMode(&T->XedInstruction, &MachineState); + XedDecodedInstZeroSetMode(&T->XedInstruction, &XedGlobalMachineState); if (XED_ERROR_NONE != XedDecode(&T->XedInstruction, T->RawData, T->RawDataSize)) return FALSE; @@ -604,7 +597,7 @@ BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block) if (T->Flags & CODE_FLAG_IS_LABEL) continue; - ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); + UINT OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); if (OperandCount == 0) continue; @@ -613,16 +606,16 @@ BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block) return FALSE; } -BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize) +BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, UINT BufferSize) { PUCHAR Buf = (PUCHAR)Buffer; - ULONG Offset = 0; + UINT Offset = 0; while (Offset < BufferSize) { PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; Link->Flags = CODE_FLAG_IS_INST; - ULONG PossibleSize = min(15, BufferSize - Offset); + UINT PossibleSize = min(15, BufferSize - Offset); XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInstruction, (Buf + Offset), PossibleSize); if (DecodeError != XED_ERROR_NONE) { @@ -645,7 +638,7 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize) return TRUE; } -PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize) +PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PUINT OutSize) { if (!NcFixRelJmps(Block)) return NULL; @@ -676,7 +669,7 @@ PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize) } //assumes all jmps already promoted to 32 bit branch displacement size -PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize) +PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PUINT OutSize) { for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) { @@ -686,7 +679,7 @@ PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize) if (!NcGetDeltaToRandomLabel(T, &BranchDisp)) return FALSE; - ULONG DispWidth = XedDecodedInstGetBranchDisplacementWidth(&T->XedInstruction); + UINT DispWidth = XedDecodedInstGetBranchDisplacementWidth(&T->XedInstruction); switch (DispWidth) { case 1: *(PINT8)&T->RawData[T->RawDataSize - DispWidth] = (INT8)BranchDisp; break; diff --git a/CodeVirtualizer/NativeCode.h b/CodeVirtualizer/NativeCode.h index bc2fc07..106fbd7 100644 --- a/CodeVirtualizer/NativeCode.h +++ b/CodeVirtualizer/NativeCode.h @@ -15,15 +15,15 @@ typedef struct _NATIVE_CODE_LINK _NATIVE_CODE_LINK* Next; _NATIVE_CODE_LINK* Prev; _NATIVE_CODE_BLOCK* Block; - ULONG Flags; - ULONG Label; + UINT Flags; + UINT Label; PUCHAR RawData; - ULONG RawDataSize; + UINT RawDataSize; XED_DECODED_INST XedInstruction; STDVECTOR> AsmOperations; _NATIVE_CODE_LINK(); - _NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); - _NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode = FALSE); + _NATIVE_CODE_LINK(UINT LabelId, _NATIVE_CODE_BLOCK* B); + _NATIVE_CODE_LINK(UINT F, PVOID Rd, UINT Rds, BOOL Decode = FALSE); ~_NATIVE_CODE_LINK(); }NATIVE_CODE_LINK, *PNATIVE_CODE_LINK; @@ -31,7 +31,7 @@ typedef struct _NATIVE_CODE_BLOCK { PNATIVE_CODE_LINK Start; PNATIVE_CODE_LINK End; - STDVECTOR LabelIds; + STDVECTOR LabelIds; _NATIVE_CODE_BLOCK(); }NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK; @@ -45,13 +45,13 @@ VOID NcInsertLinkBefore(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2); VOID NcUnlink(PNATIVE_CODE_LINK Link); -ULONG NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne = FALSE); +UINT NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne = FALSE); -ULONG NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block); +UINT NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block); -VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New); +VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, UINT Original, UINT New); -ULONG NcGenUnusedLabelId(PNATIVE_CODE_BLOCK Block); +UINT NcGenUnusedLabelId(PNATIVE_CODE_BLOCK Block); VOID NcFixLabelsForBlocks(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2); @@ -83,11 +83,11 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block); BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block); -BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize); +BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, UINT BufferSize); -PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize); +PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PUINT OutSize); -PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize); +PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PUINT OutSize); VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block); diff --git a/CodeVirtualizer/Obfuscator.cpp b/CodeVirtualizer/Obfuscator.cpp index 0c09ebe..897ee20 100644 --- a/CodeVirtualizer/Obfuscator.cpp +++ b/CodeVirtualizer/Obfuscator.cpp @@ -3,16 +3,16 @@ BOOL ObfiRandomizeInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PVOID Context) { - for (ULONG i = 0; i < Link->RawDataSize; i++) + for (UINT i = 0; i < Link->RawDataSize; i++) ToMutate[i] = RndGetRandomInt(0, 255); return TRUE; } VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage) { - ULONG BlockSize = NcCountInstructions(Block, TRUE); - ULONG BranchSize = (FLOAT)BlockSize * BranchSizePercentage; - ULONG BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize); + UINT BlockSize = NcCountInstructions(Block, TRUE); + UINT BranchSize = (FLOAT)BlockSize * BranchSizePercentage; + UINT BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize); PNATIVE_CODE_LINK BranchStart = BranchStartPos ? NULL : Block->Start; for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) { @@ -46,9 +46,9 @@ VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage) } } -ULONG ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, ULONG MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst) +UINT ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, UINT MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst) { - ULONG MutatedInstructions = 0; + UINT MutatedInstructions = 0; for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) { if ((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) || (T->Flags & CODE_FLAG_IS_REL_JMP)) diff --git a/CodeVirtualizer/Obfuscator.h b/CodeVirtualizer/Obfuscator.h index 169a95d..9673acb 100644 --- a/CodeVirtualizer/Obfuscator.h +++ b/CodeVirtualizer/Obfuscator.h @@ -27,22 +27,22 @@ PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0); VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage); -ULONG ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, ULONG MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst); +UINT ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, UINT MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst); XED_ICLASS_ENUM ObfGetRandomJccClass(); -PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementSize = 32); +PNATIVE_CODE_LINK ObfGenRandomJcc(UINT LabelId, UINT DisplacementSize = 32); -PNATIVE_CODE_LINK ObfGenJmpToLabel(ULONG LabelId, ULONG DisplacementSize = 32); +PNATIVE_CODE_LINK ObfGenJmpToLabel(UINT LabelId, UINT DisplacementSize = 32); BOOL ObfCreateOpaqueBranches(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken); //Combines the two branches into one block that can easily be patched into the code //Resulting block is put into NotTaken -BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, ULONG JccLabel, ULONG JmpLabel); +BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, UINT JccLabel, UINT JmpLabel); diff --git a/CodeVirtualizer/OpaqueBranching.cpp b/CodeVirtualizer/OpaqueBranching.cpp index 8d20dec..248b31d 100644 --- a/CodeVirtualizer/OpaqueBranching.cpp +++ b/CodeVirtualizer/OpaqueBranching.cpp @@ -22,19 +22,16 @@ XED_ICLASS_ENUM ObfGetRandomJccClass() return XED_ICLASS_JLE; } -PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementWidth) +PNATIVE_CODE_LINK ObfGenRandomJcc(UINT LabelId, UINT DisplacementWidth) { - XED_STATE MachineState; - MachineState.mmode = XED_MACHINE_MODE_LONG_64; - MachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b; XED_ENCODER_INSTRUCTION EncoderInstruction; XED_ENCODER_REQUEST EncoderRequest; UCHAR EncodeBuffer[15]; UINT ReturnedSize; - XedInst1(&EncoderInstruction, MachineState, ObfGetRandomJccClass(), DisplacementWidth, XedRelBr(0, DisplacementWidth)); + XedInst1(&EncoderInstruction, XedGlobalMachineState, ObfGetRandomJccClass(), DisplacementWidth, XedRelBr(0, DisplacementWidth)); - XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); + XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState); if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) return NULL; @@ -53,19 +50,16 @@ PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementWidth) return Link; } -PNATIVE_CODE_LINK ObfGenJmpToLabel(ULONG LabelId, ULONG DisplacementWidth) +PNATIVE_CODE_LINK ObfGenJmpToLabel(UINT LabelId, UINT DisplacementWidth) { - XED_STATE MachineState; - MachineState.mmode = XED_MACHINE_MODE_LONG_64; - MachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b; XED_ENCODER_INSTRUCTION EncoderInstruction; XED_ENCODER_REQUEST EncoderRequest; UCHAR EncodeBuffer[15]; UINT ReturnedSize; - XedInst1(&EncoderInstruction, MachineState, XED_ICLASS_JMP, DisplacementWidth, XedRelBr(0, DisplacementWidth)); + XedInst1(&EncoderInstruction, XedGlobalMachineState, XED_ICLASS_JMP, DisplacementWidth, XedRelBr(0, DisplacementWidth)); - XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); + XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState); if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) return NULL; @@ -89,7 +83,7 @@ BOOL ObfCreateOpaqueBranches(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNA return (NcDeepCopyPartialBlock(Start, End, Taken) && !NcDeepCopyPartialBlock(Start, End, NotTaken)); } -BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, ULONG JccLabel, ULONG JmpLabel) +BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, UINT JccLabel, UINT JmpLabel) { PNATIVE_CODE_LINK Jcc = ObfGenRandomJcc(JccLabel); if (!Jcc) diff --git a/CodeVirtualizer/PEFile.cpp b/CodeVirtualizer/PEFile.cpp index 961a838..773afc2 100644 --- a/CodeVirtualizer/PEFile.cpp +++ b/CodeVirtualizer/PEFile.cpp @@ -1,7 +1,7 @@ #include "PEFile.h" -//VOID FiLoadFile(PPE_FILE File, PVOID RawData, ULONG RawDataSize) +//VOID FiLoadFile(PPE_FILE File, PVOID RawData, UINT RawDataSize) //{ // File->RawData = RawData; // File->RawDataSize = RawDataSize; diff --git a/CodeVirtualizer/Random.cpp b/CodeVirtualizer/Random.cpp index 045572d..24987ee 100644 --- a/CodeVirtualizer/Random.cpp +++ b/CodeVirtualizer/Random.cpp @@ -5,7 +5,7 @@ INT RndGetRandomInt(INT min, INT max) { std::random_device rd; std::default_random_engine generator(rd()); - std::uniform_int_distribution distribution(min, max); + std::uniform_int_distribution distribution(min, max); return distribution(generator); } diff --git a/CodeVirtualizer/RipMovInst.cpp b/CodeVirtualizer/RipMovInst.cpp index 084e08b..cdfaf14 100644 --- a/CodeVirtualizer/RipMovInst.cpp +++ b/CodeVirtualizer/RipMovInst.cpp @@ -38,15 +38,15 @@ BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) { - ULONG FourByte = Link->RawDataSize / 4; - ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; - ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); + UINT FourByte = Link->RawDataSize / 4; + UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; + UINT OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; Block->Start = Block->End = new NATIVE_CODE_LINK; PUCHAR DataOffset = Link->RawData; - ULONG Count = FourByte; + UINT Count = FourByte; while (Count) { //Account for remaining MOVs @@ -103,15 +103,15 @@ PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) { - ULONG FourByte = Link->RawDataSize / 4; - ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; - ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); + UINT FourByte = Link->RawDataSize / 4; + UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; + UINT OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; Block->Start = Block->End = new NATIVE_CODE_LINK; - ULONG ZeroValue = 0; - ULONG Count = FourByte; + UINT ZeroValue = 0; + UINT Count = FourByte; while (Count) { INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4); diff --git a/CodeVirtualizer/VMAssembly.asm b/CodeVirtualizer/VMAssembly.asm index 79ac672..9554d24 100644 --- a/CodeVirtualizer/VMAssembly.asm +++ b/CodeVirtualizer/VMAssembly.asm @@ -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 \ No newline at end of file diff --git a/CodeVirtualizer/VMDefs.h b/CodeVirtualizer/VMDefs.h index b8904b6..e41bba9 100644 --- a/CodeVirtualizer/VMDefs.h +++ b/CodeVirtualizer/VMDefs.h @@ -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 \ No newline at end of file diff --git a/CodeVirtualizer/VirtualInstructionEmitter.cpp b/CodeVirtualizer/VirtualInstructionEmitter.cpp new file mode 100644 index 0000000..fcb4856 --- /dev/null +++ b/CodeVirtualizer/VirtualInstructionEmitter.cpp @@ -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) +{ + +} \ No newline at end of file diff --git a/CodeVirtualizer/VirtualInstructionEmitter.h b/CodeVirtualizer/VirtualInstructionEmitter.h new file mode 100644 index 0000000..195104f --- /dev/null +++ b/CodeVirtualizer/VirtualInstructionEmitter.h @@ -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 \ No newline at end of file diff --git a/CodeVirtualizer/VirtualMachine.cpp b/CodeVirtualizer/VirtualMachine.cpp index 4b8016d..d6c90a5 100644 --- a/CodeVirtualizer/VirtualMachine.cpp +++ b/CodeVirtualizer/VirtualMachine.cpp @@ -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; } -PUCHAR VmEmitVmExit(PULONG Size) + +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)); + } + 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) { - return NULL; + /* + * 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); } diff --git a/CodeVirtualizer/VirtualMachine.h b/CodeVirtualizer/VirtualMachine.h index 7dcf5f3..23c248f 100644 --- a/CodeVirtualizer/VirtualMachine.h +++ b/CodeVirtualizer/VirtualMachine.h @@ -4,29 +4,43 @@ #include "Windas.h" #include "XedWrap.h" #include "VMDefs.h" +#include "NativeCode.h" +#include "VmCode.h" -typedef struct _VM_DATA -{ - PVOID RegisterFile[32]; -}VM_DATA, *PVM_DATA; +#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)) -typedef struct _VM_EMITTER -{ - -}VM_EMITTER, *PVM_EMITTER; +#define VmOpSizeToBytes(OpSize) (pow(2, (UCHAR)OpSize)) +#define VmOpSizeToBits(OpSize) (VmOpSizeToBytes(OpSize) * 8) /* -* VmEnter: -* Move all x86 8 byte registers into storage inside of VM_DATA structure. -* Move address of VM_DATA structure into rcx -* Move virtual instruction pointer into rdx +* Vm Structure: +* RDI = VM_HEADER +* RSI = Handler Table +* RDX = Vm Instruction Pointer +* RBP = Vm Register file +* RAX = IREG0 +* RBX = IREG1 +* RCX = IREG2 +* +* R8 = Not ever saved. Uses ATM: HandlerJmp, */ -PUCHAR VmEmitVmEnter(PULONG Size); -PUCHAR VmEmitVmExit(PULONG Size); +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); -PUCHAR VmEmitMove(); -PUCHAR VmEmitSignExtend(PVM_EMITTER Emitter, UCHAR StartSize, UCHAR FinalSize, PULONG Size); -PUCHAR VmEmitZeroExtend(PVM_EMITTER Emitter, UCHAR StartSize, UCHAR FinalSize, PULONG Size); +#define VM_HANDLER_PROLOGUE_SIZE 15 +PUCHAR VmHandlerPrologue(UINT InstructionSize, PUINT OutSize, XED_REG_ENUM Vip = XED_REG_RDX, XED_REG_ENUM HandlerTableReg = XED_REG_RSI); +PUCHAR VmHandlerIRegLoadMem_B(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegLoadMem_BO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegLoadMem_BIS(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegLoadMem_BISO(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegLoadReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegStoreReg(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); +PUCHAR VmHandlerIRegLoadImm(VM_IREG_ENUM IReg, VM_OPERAND_SIZE_ENUM OperandSize, PUINT OutSize); #endif \ No newline at end of file diff --git a/CodeVirtualizer/Virtualizer.cpp b/CodeVirtualizer/Virtualizer.cpp index 648a8ab..d739b7d 100644 --- a/CodeVirtualizer/Virtualizer.cpp +++ b/CodeVirtualizer/Virtualizer.cpp @@ -2,29 +2,31 @@ BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link) { - switch (XedDecodedInstGetIClass(&Link->XedInstruction)) { case XED_ICLASS_MOV: return TRUE; } return FALSE; } -BOOL ViValidateNativeCodeBlock(PNATIVE_CODE_BLOCK Block) +BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block) { for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) { if (!ViCanHandleInst(T)) return FALSE; - } - return TRUE; -} -BOOL VmEmitEnter(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block) -{ - -} + //Cant handle RIP relative instructions. + CONST XED_INST* Inst = XedDecodedInstInst(&T->XedInstruction); + UINT OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); + for (UINT i = 0; i < OperandCount; i++) + { + XED_OPERAND_ENUM OperandName = XedOperandName(XedInstOperand(Inst, i)); -BOOL VmEmitExit(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block) -{ + if ((OperandName == XED_OPERAND_MEM0 || OperandName == XED_OPERAND_MEM1) + && XedDecodedInstGetBaseReg(&T->XedInstruction, OperandName - XED_OPERAND_MEM0) == XED_REG_RIP) + return FALSE; + } + } + return TRUE; } diff --git a/CodeVirtualizer/Virtualizer.h b/CodeVirtualizer/Virtualizer.h index 0f9b310..71600a3 100644 --- a/CodeVirtualizer/Virtualizer.h +++ b/CodeVirtualizer/Virtualizer.h @@ -4,7 +4,7 @@ #include "Code.h" #include "VmCode.h" #include "NativeCode.h" - +#include "VMDefs.h" /* * Structure: @@ -13,26 +13,17 @@ * - Two byte opcode * - * -* -* LOC register(Frame pointer): -* - A register for which all local variables are addressed from -* - Specific instructions for quick access of stuff around this ptr -* - Example Frame: -* - [Previous function variables -* - [Return Address -* - [Previous Functions LOC -* - LOC->[Empty Stack Space -* -* -* -VmEnter will essentially "call into" the vm and will be created using a function to rearrange and push arguments based on the arguments passed to said function. +* 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; +}VIRTUALIZER, *PVIRTUALIZER; BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link); -BOOL ViValidateNativeCodeBlock(PNATIVE_CODE_BLOCK Block); - -BOOL VmEmitEnter(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block); -BOOL VmEmitExit(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block); +BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block); #endif \ No newline at end of file diff --git a/CodeVirtualizer/VmCode.cpp b/CodeVirtualizer/VmCode.cpp index 3861638..92cb1dd 100644 --- a/CodeVirtualizer/VmCode.cpp +++ b/CodeVirtualizer/VmCode.cpp @@ -5,11 +5,13 @@ _VM_CODE_LINK::_VM_CODE_LINK() Flags = 0; Next = Prev = NULL; Label = 0; - RawData = NULL; - RawDataSize = 0UL; + InstData = NULL; + InstDataSize = 0UL; + PrologueData = NULL; + PrologueDataSize = 0UL; } -_VM_CODE_LINK::_VM_CODE_LINK(ULONG LabelId) +_VM_CODE_LINK::_VM_CODE_LINK(UINT LabelId) : _VM_CODE_LINK() { Label = LabelId; diff --git a/CodeVirtualizer/VmCode.h b/CodeVirtualizer/VmCode.h index e29f336..d473243 100644 --- a/CodeVirtualizer/VmCode.h +++ b/CodeVirtualizer/VmCode.h @@ -9,13 +9,17 @@ typedef struct _VM_CODE_LINK _VM_CODE_LINK* Next; _VM_CODE_LINK* Prev; - ULONG Flags; - ULONG Label; - PUCHAR RawData; - ULONG RawDataSize; + UINT Flags; + UINT Label; + + PUCHAR InstData; + UINT InstDataSize; + + PUCHAR PrologueData; + PUCHAR PrologueDataSize; _VM_CODE_LINK(); - _VM_CODE_LINK(ULONG LabelId); + _VM_CODE_LINK(UINT LabelId); }VM_CODE_LINK, *PVM_CODE_LINK; typedef struct _VM_CODE_BLOCK diff --git a/CodeVirtualizer/Windas.h b/CodeVirtualizer/Windas.h index 1200980..9bd06ee 100644 --- a/CodeVirtualizer/Windas.h +++ b/CodeVirtualizer/Windas.h @@ -8,6 +8,7 @@ #include #include #include +#include #define INLINE inline #define STDSTRING std::string diff --git a/CodeVirtualizer/XedWrap.cpp b/CodeVirtualizer/XedWrap.cpp index 212c848..90af4bd 100644 --- a/CodeVirtualizer/XedWrap.cpp +++ b/CodeVirtualizer/XedWrap.cpp @@ -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; } \ No newline at end of file diff --git a/CodeVirtualizer/XedWrap.h b/CodeVirtualizer/XedWrap.h index 3bc5c91..538f024 100644 --- a/CodeVirtualizer/XedWrap.h +++ b/CodeVirtualizer/XedWrap.h @@ -44,6 +44,8 @@ extern "C" #define XedDecodedInstGetSegReg xed_decoded_inst_get_seg_reg #define XedDecodedInstGetBaseReg xed_decoded_inst_get_base_reg #define XedDecodedInstGetIndexReg xed_decoded_inst_get_index_reg +#define XedDecodedInstGetScale xed_decoded_inst_get_scale +#define XedDecodedInstGetMemoryDisplacement xed_decoded_inst_get_memory_displacement #define XedInstOperand xed_inst_operand @@ -89,9 +91,15 @@ extern "C" #define XedRelBr xed_relbr #define XedReg xed_reg #define XedDisp xed_disp +#define XedMemB xed_mem_b +#define XedMemBD xed_mem_bd +#define XedMemBISD xed_mem_bisd +#define XedSimm0 xed_simm0 +#define XedImm0 xed_imm0 inline XED_STATE XedGlobalMachineState; -VOID XedInit(); +VOID XedGlobalInit(); +PUCHAR XedEncodeInstructions(XED_ENCODER_INSTRUCTION* InstList, UINT InstCount, PUINT OutSize); #endif \ No newline at end of file