#include #include #include #include "Windas.h" #include "XedWrap.h" #include "NativeCode.h" #include "Obfuscator.h" #include "Random.h" #include "VirtualMachine.h" #include "Virtualizer.h" __declspec(dllexport) VOID CvInit() { XedTablesInit(); srand(time(NULL)); } __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) { //printf("%X", ((PUCHAR)Code)[CodeSize - 1]); --CodeSize; } NATIVE_CODE_BLOCK CodeBlock; if (!NcDisassemble(&CodeBlock, Code, CodeSize)) { return NULL; } //printf("Dissasembled.\n"); if (!NcPromoteAllRelJmpTo32(&CodeBlock)) { return NULL; } //printf("Jmps Fixed.\n"); /*OPBR_SETS Obf; Obf.Flags = 0; Obf.ParentBlock = &CodeBlock; Obf.MinBranchLength = InstructionCount / 5 ; Obf.BranchLengthChangeAmount = 4; Obf.SpaceBetweenBranches = 10; Obf.BranchLengthChangeAmount = 4; Obf.BranchImmediately = FALSE; Obf.RandomizeBranchChangeAmount = TRUE; Obf.RandomizeSpaceBetweenBranches = TRUE; Obf.BranchRemainingInstructions = TRUE; Obf.BranchChance = 75; UINT BranchesMade = */ while (BranchCount) { ObfGenOpaqueBranch(&CodeBlock, RndGetRandomFloat(0.F, MaxBranchSizePercentage)); BranchCount--; } //if (MutSettings) // ObfMutateInstructions(MutSettings, &CodeBlock); return NcAssembleEx(&CodeBlock, OutSize); } __declspec(dllexport) VOID CvDeleteCode(PVOID Code) { if (Code) delete[] Code; } VOID PrintByteArr(PVOID Buff, UINT BufSize) { for (uint32_t i = 0; i < BufSize; i++) { std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)((PUCHAR)Buff)[i] << ' '; } } PVOID MakeExecutableBuffer(PVOID Buffer, UINT BufferSize) { PVOID ExecBuffer = VirtualAlloc(nullptr, BufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!ExecBuffer) { printf("allocate failed.\n"); return NULL; } RtlCopyMemory(ExecBuffer, Buffer, BufferSize); return ExecBuffer; } VOID PutToFile(PVOID Buffer, UINT BufferSize) { std::ofstream fout; // //fout.open("C:\\Users\\James\\Desktop\\fantern\\Test.m", std::ios::binary | std::ios::out); fout.open("C:\\Users\\Iizerd\\Desktop\\Leeg Hake\\Test.m", std::ios::binary | std::ios::out); fout.write((PCHAR)Buffer, BufferSize); fout.close(); } UINT64 TestShelcode(UINT64 v1, UINT64 v2, UINT64 v3, UINT64 v4) { if (v4 == 0) v4 = 2; UINT64 Value = 1; for (int i = 1; i <= v1; i++) { Value *= i; Value += v3; Value /= v4; for (int i = 1; i <= v4; i++) Value += v2 = i; } return Value; } UINT64 Nextfunction(UINT64 v1) { return v1 + 1; } UCHAR TestBuffer[] = { 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, //0xEB, 0x0E, 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, //0x7E, 0x06, 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0, //0xEB, 0xF8, 0x50, 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x48, 0x87, 0x04, 0x24, 0xC3, }; UINT TestBufferSize = sizeof(TestBuffer); UCHAR meme1[] = { 0x31, 0xc0, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0x83, 0xc0, 0x01, 0xc3, }; UCHAR RetNumCode[] = { 0x33, 0xC0 , 0x48, 0x83, 0xC0, 0x01 , 0x48, 0x83, 0xE9, 0x01 , 0x48, 0x83, 0xC1, 0x01 , 0x48, 0x83, 0xC0, 0x02 , 0x48, 0x83, 0xE8, 0x02 , 0x48, 0x83, 0xE9, 0x01 , 0x75, 0xE6 , 0xC3 }; UCHAR IsEvenCode[]{ 0xF6, 0xC1, 0x01, 0x75, 0x05, 0x66, 0xB8, 0x01, 0x00, 0xC3, 0x33, 0xC0, 0xC3, }; //EXTERN_C UINT64 RetNum(UINT64 Num); //EXTERN_C BOOL IsEven(UINT64 Num); int main() { XedGlobalInit(); srand(time(NULL)); //UINT OutSize = 0; //PUCHAR Output = VmHandlerIRegMem_BISD(VM_IREG_3, VM_OPSIZE_16, FALSE, &OutSize); // VmHandlerPrologue(8, &OutSize); ////PUCHAR Output = VmHandlerEncode2(XED_ICLASS_MOVZX, VM_OPSIZE_32, VM_OPSIZE_16, &OutSize); ////PUCHAR Output = VmHandlerPrologue(10, &OutSize); //if (Output && OutSize) //{ // 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) { 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"); } /*XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&DecodedInst); printf("IClass: %s\n", XedIClassEnumToString(IClass)); CONST xed_inst_t* Inst = XedDecodedInstInst(&DecodedInst); UINT OperandCount = XedDecodedInstNumOperands(&DecodedInst); for (UINT i = 0; i < OperandCount; i++) { CONST xed_operand_t* Operand = XedInstOperand(Inst, i); xed_operand_enum_t OperandName = XedOperandName(Operand); printf("Operand Name: %s\n", XedOperandEnumToString(OperandName)); printf("Operand Written: %i\n", XedOperandWritten(Operand)); printf("Operand Read: %i\n", XedOperandRead(Operand)); printf("Operand R/R: %i\n", XedOperandReadAndWritten(Operand)); if (XedOperandIsRegister(OperandName)) { xed_reg_enum_t RegEnum = XedDecodedInstGetReg(&DecodedInst, OperandName); printf("Reg: %s\n", XedRegEnumToString(RegEnum)); } if (OperandName == XED_OPERAND_MEM0 || OperandName == XED_OPERAND_MEM1) { UINT MemOpIndex = OperandName - XED_OPERAND_MEM0; printf("MemOpIdx: %u\n", MemOpIndex); printf("Base Reg: %s\n", XedRegEnumToString(XedDecodedInstGetBaseReg(&DecodedInst, MemOpIndex))); printf("Index Reg: %s\n", XedRegEnumToString(XedDecodedInstGetIndexReg(&DecodedInst, MemOpIndex))); printf("Scale: %u\n", XedDecodedInstGetScale(&DecodedInst, MemOpIndex)); printf("Disp: %llu\n", XedDecodedInstGetMemoryDisplacement(&DecodedInst, MemOpIndex)); printf("OpLength: %u\n", XedDecodedInstOperandLength(&DecodedInst, i)); } }*/ //xed_operand_values_t* Operands = xed_decoded_inst_operands(&DecodedInst); //printf("Operand Count %u\n", OperandCount); //printf("%s\n", xed_reg_enum_t2str(xed_operand_values_get_base_reg(Operands, 0))); ////printf("%s\n", xed_reg_enum_t2str(xed_operand_values_get_base_reg(Operands, 1))); //printf("%u is length.\n", xed_operand_values_get_memory_displacement_length(Operands)); //printf("%u memop count\n", xed_operand_values_number_of_memory_operands(Operands)); //printf(""); system("pause"); } //CvInit(); ////UINT Delta = (*((PUINT)((PUCHAR)TestShelcode + 1))) + 5; ////printf("Delta: %X\n", 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"); //PUCHAR MemeBlock = new UCHAR[110]; //memcpy(MemeBlock, ActualFunction, 110); //PrintByteArr(MemeBlock, 110); //system("pause"); //NATIVE_CODE_BLOCK RetNumBlock; ////NcDisassemble(&RetNumBlock, RetNumCode, sizeof(RetNumCode)); //NcDisassemble(&RetNumBlock, MemeBlock, 110); //if (!NcPromoteAllRelJmpTo32(&RetNumBlock)) //{ // printf("failed to promote all jmps.\n"); //} //OPBR_SETS Obf; //Obf.Flags = 0; //Obf.ParentBlock = &RetNumBlock; //Obf.Divisor = 1.7F; //Obf.MaxDepth = 10; //Obf.MinBranchSize = 5; //Obf.ChanceForBranch = 80; //Obf.MinDepthForBranch = 0; //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); //INSTMUT_SETS Obf2; //Obf2.MutateChance = 100; ////ObfMutateInstructions(&Obf2, &RetNumBlock); //Obf.MinBranchSize = 40; //printf("Size = %u\n", NcCountInstructions(&RetNumBlock, TRUE)); //Obf.ChanceForBranch = 100; //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); //printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock)); //UINT AsmSize; //PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); //if (!Asm) //{ // printf("failed to assemble\n"); // system("pause"); // return 1; //} //PutToFile(Asm, AsmSize); //system("pause"); /*UINT AsmSize; PVOID Asm = CvDriverFunctionObfuscate(MemeBlock, 110, &AsmSize, 5, 0.5); if (!Asm) { printf("failed to obfuscate ngiga\n"); system("pause"); return 2; } PutToFile(Asm, AsmSize); typedef UINT64(*FnTestShelcode)(UINT64, UINT64, UINT64, UINT64); PVOID Exec = NULL; Exec = MakeExecutableBuffer(Asm, AsmSize); if (!Exec) { printf("Failed to make buffer\n"); return 1; } printf("%llu %llu %llu %llu\n", ((FnTestShelcode)Exec)(1, 2, 3, 4), ((FnTestShelcode)Exec)(20, 20, 20, 4), ((FnTestShelcode)Exec)(50, 50, 50, 0), Nextfunction(12));*/ /*PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); 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); system("pause");*/ /*NATIVE_CODE_BLOCK Block; NcDisassemble(&Block, meme1, sizeof(meme1)); OBFUSCATOR Obf; Obf.Flags = 0; Obf.MinSizeForOpaqueBranch = 12; Obf.GlobalBlock = &Block; ObfObfuscate(&Obf, &Block); Obf.MinSizeForOpaqueBranch = 4; ObfObfuscate(&Obf, &Block); NcDebugPrint(&Block); UINT ByteSize = NcCalcBlockSizeInBytes(&Block); UINT InstSize = NcCountInstructions(&Block); printf("Bytes: %u, Insts: %u, FlagsMeme: %u.\n", ByteSize, InstSize, Obf.Flags); UINT AsmSize; PVOID Asm = NcAssemble(&Block, &AsmSize); PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); typedef UINT(*FnGetFour)(); printf("numba is: %u size is %u\n\n", ((FnGetFour)Exec)(), AsmSize); PutToFile(Asm, AsmSize);*/ //PNATIVE_CODE_LINK Return1776 = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme1, sizeof(meme1)); //PNATIVE_CODE_LINK RetInst = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme2, sizeof(meme2)); //PNATIVE_CODE_BLOCK Pre1 = JitEmitPreRipMov(Return1776); //PNATIVE_CODE_BLOCK Post1 = JitEmitPostRipMov(Return1776); //PNATIVE_CODE_BLOCK Pre2 = JitEmitPreRipMov(RetInst); //PNATIVE_CODE_BLOCK Post2 = JitEmitPostRipMov(RetInst); //NcAppendToBlock(Pre1, Return1776); //NcInsertBlockAfter(Pre1->End, Post1, 0); //Pre1->End = Post1->End; //NcInsertBlockAfter(Pre1->End, Pre2, 0); //Pre1->End = Pre2->End; //NcAppendToBlock(Pre1, RetInst); //NcInsertBlockAfter(Pre1->End, Post2, 0); //Pre1->End = Post2->End; ///*Pre->Start = Return1776; //Pre->End = Return1776;*/ //for (UINT i = 0; i < Return1776->RawDataSize; i++) // Return1776->RawData[i] = (UCHAR)rand(); //for (UINT i = 0; i < RetInst->RawDataSize; i++) // RetInst->RawData[i] = (UCHAR)rand(); //UINT AsmLen; //PVOID Asm = NcAssemble(Pre1, &AsmLen); //PUCHAR Tb = (PUCHAR)Asm; //for (uint32_t i = 0; i < AsmLen; i++) //{ // std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)Tb[i] << ' '; //} //system("pause"); //typedef UINT64(*FnGet1776)(); //FnGet1776 ExecBuffer = (FnGet1776)MakeExecutableBuffer(Asm, AsmLen); //if (ExecBuffer) //{ // printf("The numba was: %X\n", ExecBuffer()); // printf("The numba was: %X\n", ExecBuffer()); // printf("The numba was: %X\n", ExecBuffer()); // printf("The numba was: %X\n", ExecBuffer()); //} //NcDebugPrint(Post); /*NATIVE_CODE_BLOCK Block; NcDisassemble(&Block, TestBuffer, TestBufferSize); PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme1, sizeof(meme1)); NcInsertLinkBefore(Block.End->Prev->Prev->Prev->Prev, NewLink); UINT AssembledSize; PVOID AssembledBlock = NcAssemble(&Block, &AssembledSize); if (!AssembledBlock || !AssembledSize) { printf("Something failed nicka.\n"); system("pause"); return -1; } PUCHAR Tb = (PUCHAR)AssembledBlock; for (uint32_t i = 0; i < AssembledSize; i++) { std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)Tb[i] << ' '; } */ //PNATIVE_CODE_BLOCK OpaqueBranch = ObfGenOpaqueBranch(Block.Start, Block.End); //NcDebugPrint(OpaqueBranch); /*NATIVE_CODE_LINK T; T.RawDataSize = 10; T.RawData = new UCHAR[10]; memset(T.RawData, 0xAA, 10); JIT_BITWISE_DATA Data; RtlSecureZeroMemory(&Data, sizeof(JIT_BITWISE_DATA)); PNATIVE_CODE_BLOCK NewBlock = JitEmitPreRipMov(&T); if (NewBlock) { printf("\n"); NcDebugPrint(NewBlock); printf("\n"); NcPrintBlockCode(NewBlock); } system("pause");*/