opaque branches

main
James 3 years ago
parent 9ccd3a5eae
commit c1db74be04

@ -28,6 +28,47 @@ ULONG TestBufferSize = sizeof(TestBuffer);
int main() int main()
{ {
XedTablesInit();
xed_state_t state;
state.mmode = XED_MACHINE_MODE_LONG_64;
state.stack_addr_width = XED_ADDRESS_WIDTH_64b;
xed_encoder_instruction_t inst;
//xed_inst2(&inst, state, XED_ICLASS_ADD, 0, xed_reg(XED_REG_EAX),
// xed_mem_bd(XED_REG_EDX, xed_disp(0x11223344, 32), 32));
xed_inst1(&inst, state, XED_ICLASS_JLE, 32, xed_relbr(0x1776, 32));
xed_encoder_request_t request;
xed_encoder_request_zero_set_mode(&request, &state);
if (!xed_convert_to_encoder_request(&request, &inst))
{
printf("failed to convert instruction.\n");
system("pause");
return -1;
}
unsigned char storage[15];
unsigned int len;
xed_error_enum_t err = xed_encode(&request, storage, 15, &len);
if (err != XED_ERROR_NONE)
{
printf("XedEncode failed with error %s\n", XedErrorEnumToString(err));
system("pause");
return FALSE;
}
printf("len: %u\n", len);
for (int i = 0; i < len; i++)
{
std::cout << std::setw(2) << std::setfill('0') << std::hex << (INT)storage[i] << ' ';
}
std::cout << '\n';
return -1;
NATIVE_CODE_BLOCK Block; NATIVE_CODE_BLOCK Block;
XedTablesInit(); XedTablesInit();

@ -2,8 +2,8 @@
_NATIVE_CODE_LINK::_NATIVE_CODE_LINK() _NATIVE_CODE_LINK::_NATIVE_CODE_LINK()
{ {
XedDecodedInstZero(&XedInst); XedDecodedInstZero(&XedInstruction);
XedDecodedInstSetMode(&XedInst, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b); 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;
@ -39,7 +39,7 @@ _NATIVE_CODE_LINK::~_NATIVE_CODE_LINK()
_NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK() _NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK()
{ {
Start = End = NULL; Start = End = NULL;
HasRelativeJumps = FALSE; LabelIds.clear();
} }
VOID NcAppendToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link) VOID NcAppendToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link)
@ -117,17 +117,29 @@ VOID NcUnlink(PNATIVE_CODE_LINK Link)
} }
} }
ULONG NcGenUnusedLabelId(STDVECTOR<ULONG> CONST& LabelIds) ULONG NcCalcBlockSize(PNATIVE_CODE_BLOCK Block)
{
ULONG TotalSize = 0;
for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next)
{
if (T->Flags & CODE_FLAG_IS_LABEL)
continue;
TotalSize += T->RawDataSize;
}
return TotalSize;
}
ULONG NcGenUnusedLabelId(PNATIVE_CODE_BLOCK Block)
{ {
ULONG ReturnLabelId = rand(); ULONG ReturnLabelId = rand();
while (StdFind(LabelIds.begin(), LabelIds.end(), ReturnLabelId) != LabelIds.end()) while (StdFind(Block->LabelIds.begin(), Block->LabelIds.end(), ReturnLabelId) != Block->LabelIds.end())
ReturnLabelId = rand(); ReturnLabelId = rand();
return ReturnLabelId; return ReturnLabelId;
} }
VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New) VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block, ULONG Original, ULONG New)
{ {
for (PNATIVE_CODE_LINK T = Block1->Start; T; T = T->Next) for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next)
{ {
if (((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_IS_REL_JMP)) && T->Label == Original) if (((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_IS_REL_JMP)) && T->Label == Original)
T->Label = New; T->Label = New;
@ -136,26 +148,23 @@ VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New)
VOID NcFixLabelsForBlocks(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2) VOID NcFixLabelsForBlocks(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2)
{ {
STDVECTOR<ULONG> BlockOneLabels;
for (PNATIVE_CODE_LINK T = Block1->Start; T; T = T->Next)
{
if ((T->Flags & CODE_FLAG_IS_LABEL) && StdFind(BlockOneLabels.begin(), BlockOneLabels.end(), T->Label) != BlockOneLabels.end())
BlockOneLabels.push_back(T->Label);
}
for (PNATIVE_CODE_LINK T = Block2->Start; T; T = T->Next) for (PNATIVE_CODE_LINK T = Block2->Start; T; T = T->Next)
{ {
if ((T->Flags & CODE_FLAG_IS_LABEL) && StdFind(BlockOneLabels.begin(), BlockOneLabels.end(), T->Label) != BlockOneLabels.end()) if ((T->Flags & CODE_FLAG_IS_LABEL) && StdFind(Block1->LabelIds.begin(), Block1->LabelIds.end(), T->Label) != Block1->LabelIds.end())
NcChangeLabelId(Block2, T->Label, NcGenUnusedLabelId(BlockOneLabels)); {
ULONG Lid = NcGenUnusedLabelId(Block1);
NcChangeLabelId(Block2, T->Label, Lid);
Block1->LabelIds.push_back(Lid);
}
} }
} }
BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block) BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL FixLabels)
{ {
if (!Link || !Link->Block || !Block || !Block->Start || !Block->End || Link->Block == Block) if (!Link || !Link->Block || !Block || !Block->Start || !Block->End || Link->Block == Block)
return FALSE; return FALSE;
if (Block->HasRelativeJumps && Link->Block->HasRelativeJumps) if (FixLabels && Block->LabelIds.size() && Link->Block->LabelIds.size())
NcFixLabelsForBlocks(Link->Block, Block); NcFixLabelsForBlocks(Link->Block, Block);
if (Link->Next) if (Link->Next)
@ -170,12 +179,12 @@ BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block)
return TRUE; return TRUE;
} }
BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block) BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL FixLabels)
{ {
if (!Link || !Link->Block || !Block || !Block->Start || !Block->End) if (!Link || !Link->Block || !Block || !Block->Start || !Block->End)
return FALSE; return FALSE;
if (Block->HasRelativeJumps && Link->Block->HasRelativeJumps) if (FixLabels && Block->LabelIds.size() && Link->Block->LabelIds.size())
NcFixLabelsForBlocks(Link->Block, Block); NcFixLabelsForBlocks(Link->Block, Block);
if (Link->Prev) if (Link->Prev)
@ -198,15 +207,15 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
if (!(T->Flags & CODE_FLAG_IS_INST)) if (!(T->Flags & CODE_FLAG_IS_INST))
continue; continue;
XED_CATEGORY_ENUM Category = XedDecodedInstGetCategory(&T->XedInst); XED_CATEGORY_ENUM Category = XedDecodedInstGetCategory(&T->XedInstruction);
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->XedInst); ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction);
if (OperandCount < 1) if (OperandCount < 1)
continue; continue;
CONST XED_INST* Inst = XedDecodedInstInst(&T->XedInst); CONST XED_INST* Inst = XedDecodedInstInst(&T->XedInstruction);
if (!Inst) if (!Inst)
continue; continue;
@ -218,7 +227,7 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
if (OperandType != XED_OPERAND_TYPE_IMM && OperandType != XED_OPERAND_TYPE_IMM_CONST) if (OperandType != XED_OPERAND_TYPE_IMM && OperandType != XED_OPERAND_TYPE_IMM_CONST)
continue; continue;
INT32 BranchDisplacement = XedDecodedInstGetBranchDisplacement(&T->XedInst); INT32 BranchDisplacement = XedDecodedInstGetBranchDisplacement(&T->XedInstruction);
PNATIVE_CODE_LINK JmpPos = NcValidateJmp(T, BranchDisplacement); PNATIVE_CODE_LINK JmpPos = NcValidateJmp(T, BranchDisplacement);
if (!JmpPos) if (!JmpPos)
{ {
@ -233,10 +242,10 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
else else
{ {
NcInsertLinkBefore(JmpPos, new NATIVE_CODE_LINK(CurrentLabelId, Block)); NcInsertLinkBefore(JmpPos, new NATIVE_CODE_LINK(CurrentLabelId, Block));
Block->LabelIds.push_back(CurrentLabelId);
T->Label = CurrentLabelId; T->Label = CurrentLabelId;
++CurrentLabelId; ++CurrentLabelId;
} }
Block->HasRelativeJumps = TRUE;
T->Flags |= CODE_FLAG_IS_REL_JMP; T->Flags |= CODE_FLAG_IS_REL_JMP;
} }
return TRUE; return TRUE;
@ -252,7 +261,7 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
Delta -= XedDecodedInstGetLength(&T->XedInst); Delta -= XedDecodedInstGetLength(&T->XedInstruction);
T = T->Next; T = T->Next;
} }
if (Delta != 0 || !T) if (Delta != 0 || !T)
@ -268,7 +277,7 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
Delta += XedDecodedInstGetLength(&T->XedInst); Delta += XedDecodedInstGetLength(&T->XedInstruction);
if (Delta >= 0) if (Delta >= 0)
break; break;
T = T->Prev; T = T->Prev;
@ -282,53 +291,47 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
return Jmp; return Jmp;
} }
PNATIVE_CODE_LINK NcDeepCopy(PNATIVE_CODE_LINK Link) PNATIVE_CODE_LINK NcDeepCopyLink(PNATIVE_CODE_LINK Link)
{ {
if (Link->Flags & CODE_FLAG_IS_LABEL) if (Link->Flags & CODE_FLAG_IS_LABEL)
{ {
return new NATIVE_CODE_LINK(Link->Label, NULL); return new NATIVE_CODE_LINK(Link->Label, NULL);
} }
else else
{ { PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(Link->Flags, Link->RawData, Link->RawDataSize);
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Link->XedInst);
printf("Doing %s\n", XedIClassEnumToString(IClass));
PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(Link->Flags, Link->RawData, Link->RawDataSize);
NewLink->Label = Link->Label; NewLink->Label = Link->Label;
XED_ERROR_ENUM DecodeError = XedDecode(&NewLink->XedInst, Link->RawData, Link->RawDataSize); XED_ERROR_ENUM DecodeError = XedDecode(&NewLink->XedInstruction, Link->RawData, Link->RawDataSize);
if (DecodeError != XED_ERROR_NONE) if (DecodeError != XED_ERROR_NONE)
{ {
printf("XedDecode failed in NcDeepCopy: %s\n", XedErrorEnumToString(DecodeError)); printf("XedDecode failed in NcDeepCopyLink: %s\n", XedErrorEnumToString(DecodeError));
delete NewLink; delete NewLink;
return NULL; return NULL;
} }
printf("succeeded\n");
return NewLink; return NewLink;
} }
} }
PNATIVE_CODE_BLOCK NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End) PNATIVE_CODE_BLOCK NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End)
{ {
if (!Start || !End) if (!Start || !End || !Start->Block || Start->Block != End->Block)
return NULL; return NULL;
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
if (!Block) if (!Block)
return NULL; return NULL;
for (ULONG L : Start->Block->LabelIds)
Block->LabelIds.push_back(L);
for (PNATIVE_CODE_LINK CurLink = Start; CurLink != End->Next; CurLink = CurLink->Next) for (PNATIVE_CODE_LINK CurLink = Start; CurLink != End->Next; CurLink = CurLink->Next)
{ {
PNATIVE_CODE_LINK Temp = NcDeepCopy(CurLink); PNATIVE_CODE_LINK Temp = NcDeepCopyLink(CurLink);
if (!Temp) if (!Temp)
{ {
NcDeleteBlock(Block); NcDeleteBlock(Block);
delete Block; delete Block;
return NULL; return NULL;
} }
if (Temp->Flags & CODE_FLAG_IS_REL_JMP)
Block->HasRelativeJumps = TRUE;
NcAppendToBlock(Block, Temp); NcAppendToBlock(Block, Temp);
} }
@ -350,7 +353,7 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG 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); ULONG PossibleSize = min(15, BufferSize - Offset);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, (Buf + Offset), PossibleSize); XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInstruction, (Buf + Offset), PossibleSize);
if (DecodeError != XED_ERROR_NONE) if (DecodeError != XED_ERROR_NONE)
{ {
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError)); printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
@ -358,7 +361,7 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
delete Link; delete Link;
return FALSE; return FALSE;
} }
Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst); Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInstruction);
Link->RawData = new UCHAR[Link->RawDataSize]; Link->RawData = new UCHAR[Link->RawDataSize];
memcpy(Link->RawData, (Buf + Offset), Link->RawDataSize); memcpy(Link->RawData, (Buf + Offset), Link->RawDataSize);
@ -374,6 +377,7 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
PVOID NcAssemble(PNATIVE_CODE_BLOCK Block) PVOID NcAssemble(PNATIVE_CODE_BLOCK Block)
{ {
//TODO: handle post assembly editing for Jit obfuscation types(maybe a vector of post assembly processing traits inside of NATIVE_CODE_LINK)
return NULL; return NULL;
} }
@ -402,7 +406,7 @@ VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block)
} }
else else
{ {
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInst); XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInstruction);
if (T->Flags & CODE_FLAG_IS_REL_JMP) if (T->Flags & CODE_FLAG_IS_REL_JMP)
{ {
SetConsoleTextAttribute(ConsoleHandle, FOREGROUND_GREEN | FOREGROUND_RED); SetConsoleTextAttribute(ConsoleHandle, FOREGROUND_GREEN | FOREGROUND_RED);

@ -16,7 +16,7 @@ typedef struct _NATIVE_CODE_LINK
ULONG Label; ULONG Label;
PUCHAR RawData; PUCHAR RawData;
ULONG RawDataSize; ULONG RawDataSize;
XED_DECODED_INST XedInst; XED_DECODED_INST XedInstruction;
_NATIVE_CODE_LINK(); _NATIVE_CODE_LINK();
_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); _NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B);
_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds); _NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds);
@ -27,7 +27,7 @@ typedef struct _NATIVE_CODE_BLOCK
{ {
PNATIVE_CODE_LINK Start; PNATIVE_CODE_LINK Start;
PNATIVE_CODE_LINK End; PNATIVE_CODE_LINK End;
BOOL HasRelativeJumps; STDVECTOR<ULONG> LabelIds;
_NATIVE_CODE_BLOCK(); _NATIVE_CODE_BLOCK();
}NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK; }NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK;
@ -41,21 +41,23 @@ VOID NcInsertLinkBefore(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2);
VOID NcUnlink(PNATIVE_CODE_LINK Link); VOID NcUnlink(PNATIVE_CODE_LINK Link);
ULONG NcCalcBlockSize(PNATIVE_CODE_BLOCK Block);
VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New); VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New);
ULONG NcGenUnusedLabelId(STDVECTOR<ULONG> CONST& LabelIds); ULONG 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);
BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block); BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL FixLabels = TRUE);
BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block); BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL FixLabels = TRUE);
BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block); BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block);
PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Link, INT32 Delta); PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Link, INT32 Delta);
PNATIVE_CODE_LINK NcDeepCopy(PNATIVE_CODE_LINK Link); PNATIVE_CODE_LINK NcDeepCopyLink(PNATIVE_CODE_LINK Link);
PNATIVE_CODE_BLOCK NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End); PNATIVE_CODE_BLOCK NcDeepCopyPartialBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End);

@ -4,7 +4,7 @@ PNATIVE_CODE_LINK NcEmitNop()
{ {
UCHAR RawData[] = { 0x90 }; UCHAR RawData[] = { 0x90 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInst, Link->RawData, 1); XedDecode(&Link->XedInstruction, Link->RawData, 1);
return Link; return Link;
} }

@ -1 +1,102 @@
#include "OpaqueBranching.h" #include "OpaqueBranching.h"
XED_ICLASS_ENUM ObfGetRandomJccClass()
{
switch (rand() % 15)
{
default:
return XED_ICLASS_JLE;
}
}
PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG 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;
ULONG DispWidth = ((rand() % 2) ? 16 : 32);
UCHAR EncodeBuffer[15];
UINT ReturnedSize;
XedInst1(&EncoderInstruction, MachineState, ObfGetRandomJccClass(), DispWidth, XedRelBr(0, DispWidth));
XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState);
if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction))
return NULL;
if (XED_ERROR_NONE != XedEncode(&EncoderRequest, EncodeBuffer, 15, &ReturnedSize))
return NULL;
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, EncodeBuffer, ReturnedSize);
if (XED_ERROR_NONE != XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize))
{
delete Link;
return NULL;
}
Link->Label = LabelId;
return Link;
}
PNATIVE_CODE_LINK ObfGenJmpForOpaqueBranch(ULONG LabelId, ULONG DisplacementWidth)
{
return NULL;
}
PNATIVE_CODE_BLOCK ObfGenerateOpaqueBranch(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End)
{
if (!Start || !End || !Start->Block || Start->Block != End->Block)
return NULL;
PNATIVE_CODE_BLOCK NotTaken = NcDeepCopyPartialBlock(Start, End);
if (!NotTaken)
{
return NULL;
}
PNATIVE_CODE_BLOCK Taken = NcDeepCopyPartialBlock(Start, End);
if (!Taken)
{
NcDeleteBlock(NotTaken);
delete NotTaken;
return NULL;
}
ULONG JccLabel = NcGenUnusedLabelId(Start->Block);
ULONG JmpLabel = NcGenUnusedLabelId(Start->Block);
Start->Block->LabelIds.push_back(JccLabel);
Start->Block->LabelIds.push_back(JmpLabel);
PNATIVE_CODE_LINK Jcc = ObfGenRandomJcc(JccLabel);
if (!Jcc)
{
NcDeleteBlock(Taken);
delete Taken;
NcDeleteBlock(NotTaken);
delete NotTaken;
return NULL;
}
PNATIVE_CODE_LINK Jmp = ObfGenJmpForOpaqueBranch(JmpLabel);
if (!Jmp)
{
delete Jcc;
NcDeleteBlock(Taken);
delete Taken;
NcDeleteBlock(NotTaken);
delete NotTaken;
return NULL;
}
NcPrependToBlock(NotTaken, Jcc);
NcAppendToBlock(NotTaken, Jmp);
NcPrependToBlock(Taken, new NATIVE_CODE_LINK(JccLabel, Taken));
NcAppendToBlock(Taken, new NATIVE_CODE_LINK(JmpLabel, Taken));
NcInsertBlockAfter(NotTaken->End, Taken, FALSE);
delete Taken;
return NotTaken;
}

@ -5,7 +5,14 @@
#include "XedWrap.h" #include "XedWrap.h"
#include "NativeCode.h" #include "NativeCode.h"
XED_ICLASS_ENUM ObfGetRandomJccClass();
PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementSize = 4);
PNATIVE_CODE_LINK ObfGenJmpForOpaqueBranch(ULONG LabelId, ULONG DisplacementSize = 4);
PNATIVE_CODE_BLOCK ObfGenerateOpaqueBranch(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End);
VOID ObfGenerateOpaqueBranch(PNATIVE_CODE_LINK Start, ULONG Length);
#endif #endif

@ -9,7 +9,7 @@ BOOL ObfEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat
*(PINT32)&Link->RawData[DWORD_MOV_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[DWORD_MOV_INST_RIP_OFFSET] = RipDelta;
memcpy(&Link->RawData[DWORD_MOV_INST_MOV_OFFSET], Data, 4); memcpy(&Link->RawData[DWORD_MOV_INST_MOV_OFFSET], Data, 4);
printf("%p memes\n", Link); printf("%p memes\n", Link);
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -21,7 +21,7 @@ BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(PINT32)&Link->RawData[WORD_MOV_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[WORD_MOV_INST_RIP_OFFSET] = RipDelta;
memcpy(&Link->RawData[WORD_MOV_INST_MOV_OFFSET], Data, 2); memcpy(&Link->RawData[WORD_MOV_INST_MOV_OFFSET], Data, 2);
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -33,7 +33,7 @@ BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(PINT32)&Link->RawData[BYTE_MOV_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[BYTE_MOV_INST_RIP_OFFSET] = RipDelta;
Link->RawData[BYTE_MOV_INST_MOV_OFFSET] = *Data; Link->RawData[BYTE_MOV_INST_MOV_OFFSET] = *Data;
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }

@ -5,7 +5,7 @@ BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block)
{ {
UCHAR RawData[] = { 0x9C }; UCHAR RawData[] = { 0x9C };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInst, Link->RawData, 1); XedDecode(&Link->XedInstruction, Link->RawData, 1);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -14,7 +14,7 @@ BOOL ObfEmitPopfqInst(PNATIVE_CODE_BLOCK Block)
{ {
UCHAR RawData[] = { 0x9D }; UCHAR RawData[] = { 0x9D };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInst, Link->RawData, 1); XedDecode(&Link->XedInstruction, Link->RawData, 1);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -26,7 +26,7 @@ BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(PINT32)&Link->RawData[DWORD_XOR_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[DWORD_XOR_INST_RIP_OFFSET] = RipDelta;
*(PULONG)&Link->RawData[DWORD_XOR_INST_XOR_OFFSET] = Value; *(PULONG)&Link->RawData[DWORD_XOR_INST_XOR_OFFSET] = Value;
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -38,7 +38,7 @@ BOOL ObfEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(PINT32)&Link->RawData[WORD_XOR_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[WORD_XOR_INST_RIP_OFFSET] = RipDelta;
*(PUSHORT)&Link->RawData[WORD_XOR_INST_XOR_OFFSET] = (USHORT)Value; *(PUSHORT)&Link->RawData[WORD_XOR_INST_XOR_OFFSET] = (USHORT)Value;
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -50,7 +50,7 @@ BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(PINT32)&Link->RawData[BYTE_XOR_INST_RIP_OFFSET] = RipDelta; *(PINT32)&Link->RawData[BYTE_XOR_INST_RIP_OFFSET] = RipDelta;
*(PUCHAR)&Link->RawData[BYTE_XOR_INST_XOR_OFFSET] = (UCHAR)Value; *(PUCHAR)&Link->RawData[BYTE_XOR_INST_XOR_OFFSET] = (UCHAR)Value;
XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
NcAppendToBlock(Block, Link); NcAppendToBlock(Block, Link);
return TRUE; return TRUE;
} }
@ -109,7 +109,7 @@ VOID ObfiUpdateXorLedger(CONST XED_FLAG_SET* FlagsWritten, XED_FLAG_SET* Ledger)
BOOL ObfDoesInstWriteToAllXorFlags(PNATIVE_CODE_LINK Link) BOOL ObfDoesInstWriteToAllXorFlags(PNATIVE_CODE_LINK Link)
{ {
CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&Link->XedInst); CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&Link->XedInstruction);
CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags); CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);
CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(SimpleFlags); CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(SimpleFlags);
@ -137,7 +137,7 @@ BOOL ObfAreXorFlagsClobberedBeforeUse(PNATIVE_CODE_LINK Link)
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&T->XedInst); CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&T->XedInstruction);
CONST XED_FLAG_SET* FlagsRead = XedSimpleFlagGetReadFlagSet(SimpleFlags); CONST XED_FLAG_SET* FlagsRead = XedSimpleFlagGetReadFlagSet(SimpleFlags);
CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags); CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);

@ -13,6 +13,9 @@ extern "C"
#define XED_OPERAND xed_operand_t #define XED_OPERAND xed_operand_t
#define XED_SIMPLE_FLAG xed_simple_flag_t #define XED_SIMPLE_FLAG xed_simple_flag_t
#define XED_FLAG_SET xed_flag_set_t #define XED_FLAG_SET xed_flag_set_t
#define XED_STATE xed_state_t
#define XED_ENCODER_INSTRUCTION xed_encoder_instruction_t
#define XED_ENCODER_REQUEST xed_encoder_request_t
#define XED_OPERAND_TYPE_ENUM xed_operand_type_enum_t #define XED_OPERAND_TYPE_ENUM xed_operand_type_enum_t
#define XED_ERROR_ENUM xed_error_enum_t #define XED_ERROR_ENUM xed_error_enum_t
@ -45,4 +48,20 @@ extern "C"
#define XedSimpleFlagGetWrittenFlagSet xed_simple_flag_get_written_flag_set #define XedSimpleFlagGetWrittenFlagSet xed_simple_flag_get_written_flag_set
#define XedSimpleFlagGetUndefinedFlagSet xed_simple_flag_get_undefined_flag_set #define XedSimpleFlagGetUndefinedFlagSet xed_simple_flag_get_undefined_flag_set
#define XedEncoderRequestZeroSetMode xed_encoder_request_zero_set_mode
#define XedConvertToEncoderRequest xed_convert_to_encoder_request
#define XedEncode xed_encode
#define XedInst xed_inst
#define XedInst0 xed_inst0
#define XedInst1 xed_inst1
#define XedInst2 xed_inst2
#define XedInst3 xed_inst3
#define XedInst4 xed_inst4
#define XedInst5 xed_inst5
#define XedRelBr xed_relbr
#define XedReg xed_reg
#define XedDisp xed_disp
#endif #endif

Binary file not shown.
Loading…
Cancel
Save