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.

115 lines
3.4 KiB

#include "Obfuscator.h"
XED_ICLASS_ENUM ObfGetRandomJccClass()
{
switch (RndGetRandomInt(0, 14))
{
case 0: return XED_ICLASS_JL;
case 1: return XED_ICLASS_JLE;
case 2: return XED_ICLASS_JNB;
case 3: return XED_ICLASS_JNBE;
case 4: return XED_ICLASS_JNL;
case 5: return XED_ICLASS_JNLE;
case 6: return XED_ICLASS_JNO;
case 7: return XED_ICLASS_JNP;
case 8: return XED_ICLASS_JNS;
case 9: return XED_ICLASS_JNZ;
case 10: return XED_ICLASS_JO;
case 11: return XED_ICLASS_JP;
case 13: return XED_ICLASS_JS;
case 14: return XED_ICLASS_JZ;
}
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;
UCHAR EncodeBuffer[15];
UINT ReturnedSize;
XedInst1(&EncoderInstruction, MachineState, ObfGetRandomJccClass(), DisplacementWidth, XedRelBr(0, DisplacementWidth));
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;
Link->Flags = (CODE_FLAG_IS_INST | CODE_FLAG_IS_REL_JMP);
return Link;
}
PNATIVE_CODE_LINK ObfGenJmpToLabel(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;
UCHAR EncodeBuffer[15];
UINT ReturnedSize;
XedInst1(&EncoderInstruction, MachineState, XED_ICLASS_JMP, DisplacementWidth, XedRelBr(0, DisplacementWidth));
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;
Link->Flags = (CODE_FLAG_IS_INST | CODE_FLAG_IS_REL_JMP);
return Link;
}
BOOL ObfCreateOpaqueBranches(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken)
{
return (NcDeepCopyPartialBlock(Start, End, Taken) && !NcDeepCopyPartialBlock(Start, End, NotTaken));
}
BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, ULONG JccLabel, ULONG JmpLabel)
{
PNATIVE_CODE_LINK Jcc = ObfGenRandomJcc(JccLabel);
if (!Jcc)
return FALSE;
PNATIVE_CODE_LINK Jmp = ObfGenJmpToLabel(JmpLabel);
if (!Jmp)
{
delete Jcc;
return FALSE;
}
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);
NotTaken->End = Taken->End;
return TRUE;
}