main
James 2 years ago
parent ff37bc98d5
commit c610fd02d8

@ -6,7 +6,7 @@
__declspec(dllexport) VOID CvInit(); __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); __declspec(dllexport) VOID CvDeleteCode(PVOID Code);

@ -172,6 +172,7 @@
<ClCompile Include="Virtualizer.cpp" /> <ClCompile Include="Virtualizer.cpp" />
<ClCompile Include="VirtualMachine.cpp" /> <ClCompile Include="VirtualMachine.cpp" />
<ClCompile Include="VmCode.cpp" /> <ClCompile Include="VmCode.cpp" />
<ClCompile Include="VirtualInstructionEmitter.cpp" />
<ClCompile Include="XedWrap.cpp" /> <ClCompile Include="XedWrap.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -187,6 +188,7 @@
<ClInclude Include="VirtualMachine.h" /> <ClInclude Include="VirtualMachine.h" />
<ClInclude Include="VmCode.h" /> <ClInclude Include="VmCode.h" />
<ClInclude Include="VMDefs.h" /> <ClInclude Include="VMDefs.h" />
<ClInclude Include="VirtualInstructionEmitter.h" />
<ClInclude Include="Windas.h" /> <ClInclude Include="Windas.h" />
<ClInclude Include="XedWrap.h" /> <ClInclude Include="XedWrap.h" />
</ItemGroup> </ItemGroup>

@ -39,6 +39,9 @@
<ClInclude Include="Symbos.h"> <ClInclude Include="Symbos.h">
<Filter>File\Symbols</Filter> <Filter>File\Symbols</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="VirtualInstructionEmitter.h">
<Filter>Virtualizer\VM</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
@ -87,6 +90,9 @@
<ClCompile Include="Pattern.cpp"> <ClCompile Include="Pattern.cpp">
<Filter>Obfuscator</Filter> <Filter>Obfuscator</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="VirtualInstructionEmitter.cpp">
<Filter>Virtualizer\VM</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Xed"> <Filter Include="Xed">

@ -9,13 +9,15 @@
#include "Obfuscator.h" #include "Obfuscator.h"
#include "Random.h" #include "Random.h"
#include "VirtualMachine.h"
__declspec(dllexport) VOID CvInit() __declspec(dllexport) VOID CvInit()
{ {
XedTablesInit(); XedTablesInit();
srand(time(NULL)); 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 //trip 0xCC alignment at end of code
while (((PUCHAR)Code)[CodeSize - 1] == 0xCC) while (((PUCHAR)Code)[CodeSize - 1] == 0xCC)
@ -49,7 +51,7 @@ __declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize
Obf.RandomizeSpaceBetweenBranches = TRUE; Obf.RandomizeSpaceBetweenBranches = TRUE;
Obf.BranchRemainingInstructions = TRUE; Obf.BranchRemainingInstructions = TRUE;
Obf.BranchChance = 75; Obf.BranchChance = 75;
ULONG BranchesMade = */ UINT BranchesMade = */
while (BranchCount) 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++) 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); PVOID ExecBuffer = VirtualAlloc(nullptr, BufferSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!ExecBuffer) if (!ExecBuffer)
@ -90,7 +92,7 @@ PVOID MakeExecutableBuffer(PVOID Buffer, ULONG BufferSize)
return ExecBuffer; return ExecBuffer;
} }
VOID PutToFile(PVOID Buffer, ULONG BufferSize) VOID PutToFile(PVOID Buffer, UINT BufferSize)
{ {
std::ofstream fout; std::ofstream fout;
// //
@ -100,12 +102,12 @@ VOID PutToFile(PVOID Buffer, ULONG BufferSize)
fout.close(); 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) if (v4 == 0)
v4 = 2; v4 = 2;
ULONG64 Value = 1; UINT64 Value = 1;
for (int i = 1; i <= v1; i++) for (int i = 1; i <= v1; i++)
{ {
Value *= i; Value *= i;
@ -117,7 +119,7 @@ ULONG64 TestShelcode(ULONG64 v1, ULONG64 v2, ULONG64 v3, ULONG64 v4)
return Value; return Value;
} }
ULONG64 Nextfunction(ULONG64 v1) UINT64 Nextfunction(UINT64 v1)
{ {
return v1 + 1; return v1 + 1;
} }
@ -139,7 +141,7 @@ UCHAR TestBuffer[] = {
0x48, 0x87, 0x04, 0x24, 0x48, 0x87, 0x04, 0x24,
0xC3, 0xC3,
}; };
ULONG TestBufferSize = sizeof(TestBuffer); UINT TestBufferSize = sizeof(TestBuffer);
UCHAR meme1[] = { UCHAR meme1[] = {
0x31, 0xc0, 0x31, 0xc0,
@ -182,56 +184,69 @@ UCHAR IsEvenCode[]{
0xC3, 0xC3,
}; };
//EXTERN_C ULONG64 RetNum(ULONG64 Num); //EXTERN_C UINT64 RetNum(UINT64 Num);
//EXTERN_C BOOL IsEven(ULONG64 Num); //EXTERN_C BOOL IsEven(UINT64 Num);
int main() int main()
{ {
XedGlobalInit(); XedGlobalInit();
srand(time(NULL)); srand(time(NULL));
UCHAR TestCode[] = { 0x48, 0x8B, 0x84, 0xD1, 0xF0, 0x06, 0x00, 0x00 }; // { 0x48, 0x89, 0xC8 };
XED_DECODED_INST DecodedInst; UINT OutSize = 0;
XedDecodedInstZeroSetMode(&DecodedInst, &XedGlobalMachineState); PUCHAR Output = VmHandlerIRegLoadMem_BISO(VM_IREG_2, VM_OPSIZE_2, &OutSize); // VmHandlerPrologue(8, &OutSize);
//XedDecodedInstZero(&DecodedInst); if (Output && OutSize)
//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)
{ {
printf("Failed to decode.\n"); PrintByteArr(Output, OutSize);
system("pause");
return -1;
} }
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&DecodedInst); printf("\n");
printf("IClass: %s\n", XedIClassEnumToString(IClass));
for (UINT i = 0; i < VM_IREG_COUNT; i++)
CONST xed_inst_t* Inst = XedDecodedInstInst(&DecodedInst);
ULONG OperandCount = XedDecodedInstNumOperands(&DecodedInst);
for (ULONG i = 0; i < OperandCount; i++)
{ {
CONST xed_operand_t* Operand = XedInstOperand(Inst, i); 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)));
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("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); //xed_operand_values_t* Operands = xed_decoded_inst_operands(&DecodedInst);
//printf("Operand Count %u\n", OperandCount); //printf("Operand Count %u\n", OperandCount);
@ -246,9 +261,9 @@ int main()
//CvInit(); //CvInit();
////ULONG Delta = (*((PULONG)((PUCHAR)TestShelcode + 1))) + 5; ////UINT Delta = (*((PUINT)((PUCHAR)TestShelcode + 1))) + 5;
////printf("Delta: %X\n", Delta); ////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)); //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"); //system("pause");
@ -286,7 +301,7 @@ int main()
//ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock);
//printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock)); //printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock));
//ULONG AsmSize; //UINT AsmSize;
//PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); //PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize);
//if (!Asm) //if (!Asm)
//{ //{
@ -297,7 +312,7 @@ int main()
//PutToFile(Asm, AsmSize); //PutToFile(Asm, AsmSize);
//system("pause"); //system("pause");
/*ULONG AsmSize; /*UINT AsmSize;
PVOID Asm = CvDriverFunctionObfuscate(MemeBlock, 110, &AsmSize, 5, 0.5); PVOID Asm = CvDriverFunctionObfuscate(MemeBlock, 110, &AsmSize, 5, 0.5);
if (!Asm) if (!Asm)
{ {
@ -308,7 +323,7 @@ int main()
PutToFile(Asm, AsmSize); PutToFile(Asm, AsmSize);
typedef ULONG64(*FnTestShelcode)(ULONG64, ULONG64, ULONG64, ULONG64); typedef UINT64(*FnTestShelcode)(UINT64, UINT64, UINT64, UINT64);
PVOID Exec = NULL; PVOID Exec = NULL;
Exec = MakeExecutableBuffer(Asm, AsmSize); Exec = MakeExecutableBuffer(Asm, AsmSize);
if (!Exec) if (!Exec)
@ -321,7 +336,7 @@ int main()
/*PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); /*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)); printf("\n\nSize: %u Obfuscated: %llu Original: %llu\n\n", NcCountInstructions(&RetNumBlock), ((FnRetNum)Exec)(1776), ((FnRetNum)Exec)(1776));
NcDeleteBlock(&RetNumBlock); NcDeleteBlock(&RetNumBlock);
@ -339,15 +354,15 @@ int main()
ObfObfuscate(&Obf, &Block); ObfObfuscate(&Obf, &Block);
NcDebugPrint(&Block); NcDebugPrint(&Block);
ULONG ByteSize = NcCalcBlockSizeInBytes(&Block); UINT ByteSize = NcCalcBlockSizeInBytes(&Block);
ULONG InstSize = NcCountInstructions(&Block); UINT InstSize = NcCountInstructions(&Block);
printf("Bytes: %u, Insts: %u, FlagsMeme: %u.\n", ByteSize, InstSize, Obf.Flags); printf("Bytes: %u, Insts: %u, FlagsMeme: %u.\n", ByteSize, InstSize, Obf.Flags);
ULONG AsmSize; UINT AsmSize;
PVOID Asm = NcAssemble(&Block, &AsmSize); PVOID Asm = NcAssemble(&Block, &AsmSize);
PVOID Exec = MakeExecutableBuffer(Asm, AsmSize); PVOID Exec = MakeExecutableBuffer(Asm, AsmSize);
typedef ULONG(*FnGetFour)(); typedef UINT(*FnGetFour)();
printf("numba is: %u size is %u\n\n", ((FnGetFour)Exec)(), AsmSize); printf("numba is: %u size is %u\n\n", ((FnGetFour)Exec)(), AsmSize);
PutToFile(Asm, AsmSize);*/ PutToFile(Asm, AsmSize);*/
@ -371,14 +386,14 @@ int main()
///*Pre->Start = Return1776; ///*Pre->Start = Return1776;
//Pre->End = 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(); // 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(); // RetInst->RawData[i] = (UCHAR)rand();
//ULONG AsmLen; //UINT AsmLen;
//PVOID Asm = NcAssemble(Pre1, &AsmLen); //PVOID Asm = NcAssemble(Pre1, &AsmLen);
//PUCHAR Tb = (PUCHAR)Asm; //PUCHAR Tb = (PUCHAR)Asm;
//for (uint32_t i = 0; i < AsmLen; i++) //for (uint32_t i = 0; i < AsmLen; i++)
@ -388,7 +403,7 @@ int main()
//system("pause"); //system("pause");
//typedef ULONG64(*FnGet1776)(); //typedef UINT64(*FnGet1776)();
//FnGet1776 ExecBuffer = (FnGet1776)MakeExecutableBuffer(Asm, AsmLen); //FnGet1776 ExecBuffer = (FnGet1776)MakeExecutableBuffer(Asm, AsmLen);
//if (ExecBuffer) //if (ExecBuffer)
//{ //{
@ -411,7 +426,7 @@ int main()
PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme1, sizeof(meme1)); PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, meme1, sizeof(meme1));
NcInsertLinkBefore(Block.End->Prev->Prev->Prev->Prev, NewLink); NcInsertLinkBefore(Block.End->Prev->Prev->Prev->Prev, NewLink);
ULONG AssembledSize; UINT AssembledSize;
PVOID AssembledBlock = NcAssemble(&Block, &AssembledSize); PVOID AssembledBlock = NcAssemble(&Block, &AssembledSize);
if (!AssembledBlock || !AssembledSize) if (!AssembledBlock || !AssembledSize)
{ {

@ -3,8 +3,7 @@
_NATIVE_CODE_LINK::_NATIVE_CODE_LINK() _NATIVE_CODE_LINK::_NATIVE_CODE_LINK()
{ {
XedDecodedInstZero(&XedInstruction); XedDecodedInstZeroSetMode(&XedInstruction, &XedGlobalMachineState);
XedDecodedInstSetMode(&XedInstruction, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b);
Flags = 0UL; Flags = 0UL;
Next = Prev = NULL; Next = Prev = NULL;
Block = NULL; Block = NULL;
@ -14,7 +13,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK()
AsmOperations.clear(); 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() : _NATIVE_CODE_LINK()
{ {
Block = B; Block = B;
@ -22,7 +21,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B)
Flags = CODE_FLAG_IS_LABEL; 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() : _NATIVE_CODE_LINK()
{ {
Flags = F; 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) for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
@ -143,9 +142,9 @@ ULONG NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne)
return InstructionCount; 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) for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
@ -155,16 +154,16 @@ ULONG NcCalcBlockSizeInBytes(PNATIVE_CODE_BLOCK Block)
return TotalSize; 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()) while (StdFind(Block->LabelIds.begin(), Block->LabelIds.end(), ReturnLabelId) != Block->LabelIds.end())
ReturnLabelId = rand(); ReturnLabelId = rand();
Block->LabelIds.push_back(ReturnLabelId); Block->LabelIds.push_back(ReturnLabelId);
return 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) 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) BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
{ {
ULONG CurrentLabelId = 0; UINT CurrentLabelId = 0;
for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next) for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next)
{ {
if (!(T->Flags & CODE_FLAG_IS_INST)) 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) if (Category != XED_CATEGORY_COND_BR && Category != XED_CATEGORY_UNCOND_BR)
continue; continue;
ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); UINT OperandCount = XedDecodedInstNumOperands(&T->XedInstruction);
if (OperandCount < 1) if (OperandCount < 1)
continue; continue;
@ -382,7 +381,7 @@ BOOL NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNAT
Block->LabelIds.clear(); Block->LabelIds.clear();
Block->Start = Block->End = NULL; Block->Start = Block->End = NULL;
for (ULONG L : Start->Block->LabelIds) for (UINT L : Start->Block->LabelIds)
Block->LabelIds.push_back(L); Block->LabelIds.push_back(L);
for (PNATIVE_CODE_LINK CurLink = Start; CurLink && CurLink != End->Next; CurLink = CurLink->Next) 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) if (XedDecodedInstGetBranchDisplacementWidth(&Link->XedInstruction) == 32)
return TRUE; 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_INSTRUCTION EncoderInstruction;
XED_ENCODER_REQUEST EncoderRequest; XED_ENCODER_REQUEST EncoderRequest;
UCHAR EncodeBuffer[15]; UCHAR EncodeBuffer[15];
UINT ReturnedSize; UINT ReturnedSize;
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Link->XedInstruction); XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Link->XedInstruction);
XedInst1(&EncoderInstruction, MachineState, IClass, 32, XedRelBr(0, 32)); XedInst1(&EncoderInstruction, XedGlobalMachineState, IClass, 32, XedRelBr(0, 32));
XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState);
if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction))
return FALSE; return FALSE;
@ -432,7 +428,7 @@ BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link)
Link->RawData = new UCHAR[ReturnedSize]; Link->RawData = new UCHAR[ReturnedSize];
RtlCopyMemory(Link->RawData, EncodeBuffer, 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)) if (XED_ERROR_NONE != XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize))
return FALSE; return FALSE;
@ -536,7 +532,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block)
if (!NcGetDeltaToLabel(T, &BranchDisp)) if (!NcGetDeltaToLabel(T, &BranchDisp))
return FALSE; return FALSE;
ULONG DispWidth = XedDecodedInstGetBranchDisplacementWidthBits(&T->XedInstruction); UINT DispWidth = XedDecodedInstGetBranchDisplacementWidthBits(&T->XedInstruction);
if (log2(abs(BranchDisp)) + 1 > DispWidth) if (log2(abs(BranchDisp)) + 1 > DispWidth)
{ {
//duh oh //duh oh
@ -545,10 +541,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block)
DispWidth = 32; DispWidth = 32;
//Encode new instruction //Encode new instruction
XED_STATE MachineState;
MachineState.mmode = XED_MACHINE_MODE_LONG_64;
MachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b;
XED_ENCODER_INSTRUCTION EncoderInstruction; XED_ENCODER_INSTRUCTION EncoderInstruction;
XED_ENCODER_REQUEST EncoderRequest; XED_ENCODER_REQUEST EncoderRequest;
UCHAR EncodeBuffer[15]; UCHAR EncodeBuffer[15];
@ -556,8 +549,8 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block)
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInstruction); XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInstruction);
//Do the encoding //Do the encoding
XedInst1(&EncoderInstruction, MachineState, IClass, DispWidth, XedRelBr(0, DispWidth)); XedInst1(&EncoderInstruction, XedGlobalMachineState, IClass, DispWidth, XedRelBr(0, DispWidth));
XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); XedEncoderRequestZeroSetMode(&EncoderRequest, &XedGlobalMachineState);
if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction))
return FALSE; return FALSE;
XED_ERROR_ENUM Err = XedEncode(&EncoderRequest, EncodeBuffer, 15, &ReturnedSize); XED_ERROR_ENUM Err = XedEncode(&EncoderRequest, EncodeBuffer, 15, &ReturnedSize);
@ -571,7 +564,7 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block)
RtlCopyMemory(T->RawData, EncodeBuffer, ReturnedSize); RtlCopyMemory(T->RawData, EncodeBuffer, ReturnedSize);
//Decode instruction so its proper and all that //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)) if (XED_ERROR_NONE != XedDecode(&T->XedInstruction, T->RawData, T->RawDataSize))
return FALSE; return FALSE;
@ -604,7 +597,7 @@ BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block)
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); UINT OperandCount = XedDecodedInstNumOperands(&T->XedInstruction);
if (OperandCount == 0) if (OperandCount == 0)
continue; continue;
@ -613,16 +606,16 @@ BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block)
return FALSE; 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; PUCHAR Buf = (PUCHAR)Buffer;
ULONG Offset = 0; UINT Offset = 0;
while (Offset < BufferSize) while (Offset < BufferSize)
{ {
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST; 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); XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInstruction, (Buf + Offset), PossibleSize);
if (DecodeError != XED_ERROR_NONE) if (DecodeError != XED_ERROR_NONE)
{ {
@ -645,7 +638,7 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
return TRUE; return TRUE;
} }
PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize) PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PUINT OutSize)
{ {
if (!NcFixRelJmps(Block)) if (!NcFixRelJmps(Block))
return NULL; 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 //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;) 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)) if (!NcGetDeltaToRandomLabel(T, &BranchDisp))
return FALSE; return FALSE;
ULONG DispWidth = XedDecodedInstGetBranchDisplacementWidth(&T->XedInstruction); UINT DispWidth = XedDecodedInstGetBranchDisplacementWidth(&T->XedInstruction);
switch (DispWidth) switch (DispWidth)
{ {
case 1: *(PINT8)&T->RawData[T->RawDataSize - DispWidth] = (INT8)BranchDisp; break; case 1: *(PINT8)&T->RawData[T->RawDataSize - DispWidth] = (INT8)BranchDisp; break;

@ -15,15 +15,15 @@ typedef struct _NATIVE_CODE_LINK
_NATIVE_CODE_LINK* Next; _NATIVE_CODE_LINK* Next;
_NATIVE_CODE_LINK* Prev; _NATIVE_CODE_LINK* Prev;
_NATIVE_CODE_BLOCK* Block; _NATIVE_CODE_BLOCK* Block;
ULONG Flags; UINT Flags;
ULONG Label; UINT Label;
PUCHAR RawData; PUCHAR RawData;
ULONG RawDataSize; UINT RawDataSize;
XED_DECODED_INST XedInstruction; XED_DECODED_INST XedInstruction;
STDVECTOR<STDPAIR<FN_INST_ASM_OP, PVOID>> AsmOperations; STDVECTOR<STDPAIR<FN_INST_ASM_OP, PVOID>> AsmOperations;
_NATIVE_CODE_LINK(); _NATIVE_CODE_LINK();
_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); _NATIVE_CODE_LINK(UINT LabelId, _NATIVE_CODE_BLOCK* B);
_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode = FALSE); _NATIVE_CODE_LINK(UINT F, PVOID Rd, UINT Rds, BOOL Decode = FALSE);
~_NATIVE_CODE_LINK(); ~_NATIVE_CODE_LINK();
}NATIVE_CODE_LINK, *PNATIVE_CODE_LINK; }NATIVE_CODE_LINK, *PNATIVE_CODE_LINK;
@ -31,7 +31,7 @@ typedef struct _NATIVE_CODE_BLOCK
{ {
PNATIVE_CODE_LINK Start; PNATIVE_CODE_LINK Start;
PNATIVE_CODE_LINK End; PNATIVE_CODE_LINK End;
STDVECTOR<ULONG> LabelIds; STDVECTOR<UINT> LabelIds;
_NATIVE_CODE_BLOCK(); _NATIVE_CODE_BLOCK();
}NATIVE_CODE_BLOCK, *PNATIVE_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); 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); 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 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); VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block);

@ -3,16 +3,16 @@
BOOL ObfiRandomizeInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PVOID Context) 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); ToMutate[i] = RndGetRandomInt(0, 255);
return TRUE; return TRUE;
} }
VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage) VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage)
{ {
ULONG BlockSize = NcCountInstructions(Block, TRUE); UINT BlockSize = NcCountInstructions(Block, TRUE);
ULONG BranchSize = (FLOAT)BlockSize * BranchSizePercentage; UINT BranchSize = (FLOAT)BlockSize * BranchSizePercentage;
ULONG BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize); UINT BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize);
PNATIVE_CODE_LINK BranchStart = BranchStartPos ? NULL : Block->Start; PNATIVE_CODE_LINK BranchStart = BranchStartPos ? NULL : Block->Start;
for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) 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;) 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)) if ((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) || (T->Flags & CODE_FLAG_IS_REL_JMP))

@ -27,22 +27,22 @@ PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0);
VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage); 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(); 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); 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 //Combines the two branches into one block that can easily be patched into the code
//Resulting block is put into NotTaken //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);

@ -22,19 +22,16 @@ XED_ICLASS_ENUM ObfGetRandomJccClass()
return XED_ICLASS_JLE; 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_INSTRUCTION EncoderInstruction;
XED_ENCODER_REQUEST EncoderRequest; XED_ENCODER_REQUEST EncoderRequest;
UCHAR EncodeBuffer[15]; UCHAR EncodeBuffer[15];
UINT ReturnedSize; 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)) if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction))
return NULL; return NULL;
@ -53,19 +50,16 @@ PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementWidth)
return Link; 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_INSTRUCTION EncoderInstruction;
XED_ENCODER_REQUEST EncoderRequest; XED_ENCODER_REQUEST EncoderRequest;
UCHAR EncodeBuffer[15]; UCHAR EncodeBuffer[15];
UINT ReturnedSize; 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)) if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction))
return NULL; 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)); 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); PNATIVE_CODE_LINK Jcc = ObfGenRandomJcc(JccLabel);
if (!Jcc) if (!Jcc)

@ -1,7 +1,7 @@
#include "PEFile.h" #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->RawData = RawData;
// File->RawDataSize = RawDataSize; // File->RawDataSize = RawDataSize;

@ -5,7 +5,7 @@ INT RndGetRandomInt(INT min, INT max)
{ {
std::random_device rd; std::random_device rd;
std::default_random_engine generator(rd()); std::default_random_engine generator(rd());
std::uniform_int_distribution<ULONG> distribution(min, max); std::uniform_int_distribution<UINT> distribution(min, max);
return distribution(generator); return distribution(generator);
} }

@ -38,15 +38,15 @@ BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat
PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta)
{ {
ULONG FourByte = Link->RawDataSize / 4; UINT FourByte = Link->RawDataSize / 4;
ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2;
ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); UINT OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2));
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
Block->Start = Block->End = new NATIVE_CODE_LINK; Block->Start = Block->End = new NATIVE_CODE_LINK;
PUCHAR DataOffset = Link->RawData; PUCHAR DataOffset = Link->RawData;
ULONG Count = FourByte; UINT Count = FourByte;
while (Count) while (Count)
{ {
//Account for remaining MOVs //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) PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta)
{ {
ULONG FourByte = Link->RawDataSize / 4; UINT FourByte = Link->RawDataSize / 4;
ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2;
ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); UINT OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2));
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
Block->Start = Block->End = new NATIVE_CODE_LINK; Block->Start = Block->End = new NATIVE_CODE_LINK;
ULONG ZeroValue = 0; UINT ZeroValue = 0;
ULONG Count = FourByte; UINT Count = FourByte;
while (Count) while (Count)
{ {
INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4); INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4);

@ -1,22 +1,13 @@
.CODE .CODE
;Machine structure
;REGISTER = Register file(32 8 byte registers)
;REGISTER = Instruction Pointer
;REGISTER = Handler Table
;
ViEnter PROC ViEnter PROC
MOV [RSP+8h],RCX mov [rsp+8h],rdi
MOV [RSP+10h],RDX mov rdi,0FFFFFFFFFFFFFFFFh
MOV [RSP+18h],R8
MOV [RSP+20h],R9
PUSH RAX ;store registers now
MOV RAX,0FFFFFFFFFFFFFFFFh
;RAX NOW POINTER TO VMDATA STRUCT
ret
ViEnter ENDP ViEnter ENDP
END END

@ -1,18 +1,125 @@
#ifndef __VMDEFS_H #ifndef __VMDEFS_H
#define __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_ENTER,
VM_ICLASS_EXIT, VM_ICLASS_EXIT,
VM_ICLASS_MOV,
VM_ICLASS_SX, //Loading from memory into internal registers
VM_ICLASS_ZX, //Need to support 3 modes: [BASE], [BASE+OFFSET], [BASE+INDEX*SCALE+OFFSET]
VM_ICLASS_ADD, //for 4 possible sizes(1,2,4,8)
VM_ICLASS_SUB, //for 3 possible register spots(rax,rbx,rcx
VM_ICLASS_MUL, //3 * 4 * 3 = 72
VM_ICLASS_DIV, 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 #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" #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);
} }

@ -4,29 +4,43 @@
#include "Windas.h" #include "Windas.h"
#include "XedWrap.h" #include "XedWrap.h"
#include "VMDefs.h" #include "VMDefs.h"
#include "NativeCode.h"
#include "VmCode.h"
typedef struct _VM_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))
PVOID RegisterFile[32]; #define VmIRegLoadRegDefaultCode(IReg, OpSize) (VM_ICLASS_LD_IREG_REG_START + (VM_OPSIZE_COUNT * (IReg)) + (OpSize))
}VM_DATA, *PVM_DATA; #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 #define VmOpSizeToBytes(OpSize) (pow(2, (UCHAR)OpSize))
{ #define VmOpSizeToBits(OpSize) (VmOpSizeToBytes(OpSize) * 8)
}VM_EMITTER, *PVM_EMITTER;
/* /*
* VmEnter: * Vm Structure:
* Move all x86 8 byte registers into storage inside of VM_DATA structure. * RDI = VM_HEADER
* Move address of VM_DATA structure into rcx * RSI = Handler Table
* Move virtual instruction pointer into rdx * 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); XED_REG_ENUM VmOperandSizeToRegEnumBase(VM_OPERAND_SIZE_ENUM OperandSize);
PUCHAR VmEmitVmExit(PULONG Size); 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); #define VM_HANDLER_PROLOGUE_SIZE 15
PUCHAR VmEmitZeroExtend(PVM_EMITTER Emitter, UCHAR StartSize, UCHAR FinalSize, PULONG Size); 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 #endif

@ -2,29 +2,31 @@
BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link) BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link)
{ {
switch (XedDecodedInstGetIClass(&Link->XedInstruction)) switch (XedDecodedInstGetIClass(&Link->XedInstruction))
{ {
case XED_ICLASS_MOV: return TRUE; case XED_ICLASS_MOV: return TRUE;
} }
return FALSE; 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) for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next)
{ {
if (!ViCanHandleInst(T)) if (!ViCanHandleInst(T))
return FALSE; 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;
} }

@ -4,7 +4,7 @@
#include "Code.h" #include "Code.h"
#include "VmCode.h" #include "VmCode.h"
#include "NativeCode.h" #include "NativeCode.h"
#include "VMDefs.h"
/* /*
* Structure: * Structure:
@ -13,26 +13,17 @@
* - Two byte opcode * - Two byte opcode
* - * -
* *
* * Replace the code of the original code with random bytes and somewhere within it put the entry into the vm
* LOC register(Frame pointer): * Put the address of the virtual function code into rax, then jmp to vmenter.
* - 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.
*/ */
typedef struct _VIRTUALIZER
{
UCHAR DefaultInstructions[VM_ICLASS_COUNT];
PNATIVE_CODE_BLOCK Block;
}VIRTUALIZER, *PVIRTUALIZER;
BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link); BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link);
BOOL ViValidateNativeCodeBlock(PNATIVE_CODE_BLOCK Block); BOOL ViValidateNativeCodeBlock(PVIRTUALIZER Vm, PNATIVE_CODE_BLOCK Block);
BOOL VmEmitEnter(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block);
BOOL VmEmitExit(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block);
#endif #endif

@ -5,11 +5,13 @@ _VM_CODE_LINK::_VM_CODE_LINK()
Flags = 0; Flags = 0;
Next = Prev = NULL; Next = Prev = NULL;
Label = 0; Label = 0;
RawData = NULL; InstData = NULL;
RawDataSize = 0UL; 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() : _VM_CODE_LINK()
{ {
Label = LabelId; Label = LabelId;

@ -9,13 +9,17 @@ typedef struct _VM_CODE_LINK
_VM_CODE_LINK* Next; _VM_CODE_LINK* Next;
_VM_CODE_LINK* Prev; _VM_CODE_LINK* Prev;
ULONG Flags; UINT Flags;
ULONG Label; UINT Label;
PUCHAR RawData;
ULONG RawDataSize; PUCHAR InstData;
UINT InstDataSize;
PUCHAR PrologueData;
PUCHAR PrologueDataSize;
_VM_CODE_LINK(); _VM_CODE_LINK();
_VM_CODE_LINK(ULONG LabelId); _VM_CODE_LINK(UINT LabelId);
}VM_CODE_LINK, *PVM_CODE_LINK; }VM_CODE_LINK, *PVM_CODE_LINK;
typedef struct _VM_CODE_BLOCK typedef struct _VM_CODE_BLOCK

@ -8,6 +8,7 @@
#include <iomanip> #include <iomanip>
#include <algorithm> #include <algorithm>
#include <random> #include <random>
#include <cmath>
#define INLINE inline #define INLINE inline
#define STDSTRING std::string #define STDSTRING std::string

@ -1,9 +1,44 @@
#include "XedWrap.h" #include "XedWrap.h"
VOID XedInit() VOID XedGlobalInit()
{ {
XedTablesInit(); XedTablesInit();
XedGlobalMachineState; XedGlobalMachineState;
XedGlobalMachineState.mmode = XED_MACHINE_MODE_LONG_64; XedGlobalMachineState.mmode = XED_MACHINE_MODE_LONG_64;
XedGlobalMachineState.stack_addr_width = XED_ADDRESS_WIDTH_64b; 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;
} }

@ -44,6 +44,8 @@ extern "C"
#define XedDecodedInstGetSegReg xed_decoded_inst_get_seg_reg #define XedDecodedInstGetSegReg xed_decoded_inst_get_seg_reg
#define XedDecodedInstGetBaseReg xed_decoded_inst_get_base_reg #define XedDecodedInstGetBaseReg xed_decoded_inst_get_base_reg
#define XedDecodedInstGetIndexReg xed_decoded_inst_get_index_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 #define XedInstOperand xed_inst_operand
@ -89,9 +91,15 @@ extern "C"
#define XedRelBr xed_relbr #define XedRelBr xed_relbr
#define XedReg xed_reg #define XedReg xed_reg
#define XedDisp xed_disp #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; inline XED_STATE XedGlobalMachineState;
VOID XedInit(); VOID XedGlobalInit();
PUCHAR XedEncodeInstructions(XED_ENCODER_INSTRUCTION* InstList, UINT InstCount, PUINT OutSize);
#endif #endif
Loading…
Cancel
Save