You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
12 KiB
451 lines
12 KiB
|
|
#include <Windows.h>
|
|
#include <stdio.h>
|
|
#include <fstream>
|
|
|
|
#include "Windas.h"
|
|
#include "XedWrap.h"
|
|
#include "NativeCode.h"
|
|
#include "Obfuscator.h"
|
|
#include "Random.h"
|
|
|
|
__declspec(dllexport) VOID CvInit()
|
|
{
|
|
XedTablesInit();
|
|
srand(time(NULL));
|
|
}
|
|
|
|
__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize, PULONG OutSize, ULONG 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;
|
|
ULONG 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, ULONG 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, ULONG 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, ULONG 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();
|
|
}
|
|
|
|
ULONG64 TestShelcode(ULONG64 v1, ULONG64 v2, ULONG64 v3, ULONG64 v4)
|
|
{
|
|
if (v4 == 0)
|
|
v4 = 2;
|
|
|
|
ULONG64 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;
|
|
}
|
|
|
|
ULONG64 Nextfunction(ULONG64 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,
|
|
};
|
|
ULONG 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 ULONG64 RetNum(ULONG64 Num);
|
|
//EXTERN_C BOOL IsEven(ULONG64 Num);
|
|
|
|
int main()
|
|
{
|
|
XedTablesInit();
|
|
srand(time(NULL));
|
|
UCHAR TestCode[] = { 0x48, 0x8B, 0x84, 0xD1, 0xF0, 0x06, 0x00, 0x00 }; // { 0x48, 0x89, 0xC8 };
|
|
XED_DECODED_INST DecodedInst;
|
|
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)
|
|
{
|
|
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);
|
|
ULONG OperandCount = XedDecodedInstNumOperands(&DecodedInst);
|
|
|
|
for (ULONG 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)
|
|
{
|
|
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));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//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();
|
|
|
|
////ULONG Delta = (*((PULONG)((PUCHAR)TestShelcode + 1))) + 5;
|
|
////printf("Delta: %X\n", Delta);
|
|
//PVOID ActualFunction = TestShelcode; // (PVOID)((ULONG64)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));
|
|
//ULONG AsmSize;
|
|
//PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize);
|
|
//if (!Asm)
|
|
//{
|
|
// printf("failed to assemble\n");
|
|
// system("pause");
|
|
// return 1;
|
|
//}
|
|
//PutToFile(Asm, AsmSize);
|
|
//system("pause");
|
|
|
|
/*ULONG 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 ULONG64(*FnTestShelcode)(ULONG64, ULONG64, ULONG64, ULONG64);
|
|
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 ULONG64(*FnRetNum)(ULONG 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);
|
|
|
|
ULONG ByteSize = NcCalcBlockSizeInBytes(&Block);
|
|
ULONG InstSize = NcCountInstructions(&Block);
|
|
|
|
printf("Bytes: %u, Insts: %u, FlagsMeme: %u.\n", ByteSize, InstSize, Obf.Flags);
|
|
|
|
ULONG AsmSize;
|
|
PVOID Asm = NcAssemble(&Block, &AsmSize);
|
|
PVOID Exec = MakeExecutableBuffer(Asm, AsmSize);
|
|
typedef ULONG(*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 (ULONG i = 0; i < Return1776->RawDataSize; i++)
|
|
// Return1776->RawData[i] = (UCHAR)rand();
|
|
//for (ULONG i = 0; i < RetInst->RawDataSize; i++)
|
|
// RetInst->RawData[i] = (UCHAR)rand();
|
|
|
|
|
|
|
|
//ULONG 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 ULONG64(*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);
|
|
ULONG 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");*/
|
|
|
|
|