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.

102 lines
2.5 KiB

#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;
}