|
|
|
@ -2,8 +2,8 @@
|
|
|
|
|
|
|
|
|
|
_NATIVE_CODE_LINK::_NATIVE_CODE_LINK()
|
|
|
|
|
{
|
|
|
|
|
XedDecodedInstZero(&XedInst);
|
|
|
|
|
XedDecodedInstSetMode(&XedInst, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b);
|
|
|
|
|
XedDecodedInstZero(&XedInstruction);
|
|
|
|
|
XedDecodedInstSetMode(&XedInstruction, XED_MACHINE_MODE_LONG_64, XED_ADDRESS_WIDTH_64b);
|
|
|
|
|
Flags = 0UL;
|
|
|
|
|
Next = Prev = NULL;
|
|
|
|
|
Block = NULL;
|
|
|
|
@ -39,7 +39,7 @@ _NATIVE_CODE_LINK::~_NATIVE_CODE_LINK()
|
|
|
|
|
_NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK()
|
|
|
|
|
{
|
|
|
|
|
Start = End = NULL;
|
|
|
|
|
HasRelativeJumps = FALSE;
|
|
|
|
|
LabelIds.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
while (StdFind(LabelIds.begin(), LabelIds.end(), ReturnLabelId) != LabelIds.end())
|
|
|
|
|
while (StdFind(Block->LabelIds.begin(), Block->LabelIds.end(), ReturnLabelId) != Block->LabelIds.end())
|
|
|
|
|
ReturnLabelId = rand();
|
|
|
|
|
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)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
if ((T->Flags & CODE_FLAG_IS_LABEL) && StdFind(BlockOneLabels.begin(), BlockOneLabels.end(), T->Label) != BlockOneLabels.end())
|
|
|
|
|
NcChangeLabelId(Block2, T->Label, NcGenUnusedLabelId(BlockOneLabels));
|
|
|
|
|
if ((T->Flags & CODE_FLAG_IS_LABEL) && StdFind(Block1->LabelIds.begin(), Block1->LabelIds.end(), T->Label) != Block1->LabelIds.end())
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (Block->HasRelativeJumps && Link->Block->HasRelativeJumps)
|
|
|
|
|
if (FixLabels && Block->LabelIds.size() && Link->Block->LabelIds.size())
|
|
|
|
|
NcFixLabelsForBlocks(Link->Block, Block);
|
|
|
|
|
|
|
|
|
|
if (Link->Next)
|
|
|
|
@ -170,12 +179,12 @@ BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block)
|
|
|
|
|
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)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (Block->HasRelativeJumps && Link->Block->HasRelativeJumps)
|
|
|
|
|
if (FixLabels && Block->LabelIds.size() && Link->Block->LabelIds.size())
|
|
|
|
|
NcFixLabelsForBlocks(Link->Block, Block);
|
|
|
|
|
|
|
|
|
|
if (Link->Prev)
|
|
|
|
@ -198,15 +207,15 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
|
|
|
|
|
if (!(T->Flags & CODE_FLAG_IS_INST))
|
|
|
|
|
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)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInst);
|
|
|
|
|
ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction);
|
|
|
|
|
if (OperandCount < 1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
CONST XED_INST* Inst = XedDecodedInstInst(&T->XedInst);
|
|
|
|
|
CONST XED_INST* Inst = XedDecodedInstInst(&T->XedInstruction);
|
|
|
|
|
if (!Inst)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
@ -218,7 +227,7 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
|
|
|
|
|
if (OperandType != XED_OPERAND_TYPE_IMM && OperandType != XED_OPERAND_TYPE_IMM_CONST)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
INT32 BranchDisplacement = XedDecodedInstGetBranchDisplacement(&T->XedInst);
|
|
|
|
|
INT32 BranchDisplacement = XedDecodedInstGetBranchDisplacement(&T->XedInstruction);
|
|
|
|
|
PNATIVE_CODE_LINK JmpPos = NcValidateJmp(T, BranchDisplacement);
|
|
|
|
|
if (!JmpPos)
|
|
|
|
|
{
|
|
|
|
@ -233,10 +242,10 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NcInsertLinkBefore(JmpPos, new NATIVE_CODE_LINK(CurrentLabelId, Block));
|
|
|
|
|
Block->LabelIds.push_back(CurrentLabelId);
|
|
|
|
|
T->Label = CurrentLabelId;
|
|
|
|
|
++CurrentLabelId;
|
|
|
|
|
}
|
|
|
|
|
Block->HasRelativeJumps = TRUE;
|
|
|
|
|
T->Flags |= CODE_FLAG_IS_REL_JMP;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
|
|
|
@ -252,7 +261,7 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
|
|
|
|
|
{
|
|
|
|
|
if (T->Flags & CODE_FLAG_IS_LABEL)
|
|
|
|
|
continue;
|
|
|
|
|
Delta -= XedDecodedInstGetLength(&T->XedInst);
|
|
|
|
|
Delta -= XedDecodedInstGetLength(&T->XedInstruction);
|
|
|
|
|
T = T->Next;
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
continue;
|
|
|
|
|
Delta += XedDecodedInstGetLength(&T->XedInst);
|
|
|
|
|
Delta += XedDecodedInstGetLength(&T->XedInstruction);
|
|
|
|
|
if (Delta >= 0)
|
|
|
|
|
break;
|
|
|
|
|
T = T->Prev;
|
|
|
|
@ -282,53 +291,47 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
return new NATIVE_CODE_LINK(Link->Label, NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
{ PNATIVE_CODE_LINK NewLink = new NATIVE_CODE_LINK(Link->Flags, Link->RawData, Link->RawDataSize);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
printf("XedDecode failed in NcDeepCopy: %s\n", XedErrorEnumToString(DecodeError));
|
|
|
|
|
printf("XedDecode failed in NcDeepCopyLink: %s\n", XedErrorEnumToString(DecodeError));
|
|
|
|
|
delete NewLink;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
printf("succeeded\n");
|
|
|
|
|
return NewLink;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
|
|
|
|
|
if (!Block)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
PNATIVE_CODE_LINK Temp = NcDeepCopy(CurLink);
|
|
|
|
|
PNATIVE_CODE_LINK Temp = NcDeepCopyLink(CurLink);
|
|
|
|
|
if (!Temp)
|
|
|
|
|
{
|
|
|
|
|
NcDeleteBlock(Block);
|
|
|
|
|
delete Block;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Temp->Flags & CODE_FLAG_IS_REL_JMP)
|
|
|
|
|
Block->HasRelativeJumps = TRUE;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
Link->Flags = CODE_FLAG_IS_INST;
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst);
|
|
|
|
|
Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInstruction);
|
|
|
|
|
Link->RawData = new UCHAR[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)
|
|
|
|
|
{
|
|
|
|
|
//TODO: handle post assembly editing for Jit obfuscation types(maybe a vector of post assembly processing traits inside of NATIVE_CODE_LINK)
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -402,7 +406,7 @@ VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInst);
|
|
|
|
|
XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&T->XedInstruction);
|
|
|
|
|
if (T->Flags & CODE_FLAG_IS_REL_JMP)
|
|
|
|
|
{
|
|
|
|
|
SetConsoleTextAttribute(ConsoleHandle, FOREGROUND_GREEN | FOREGROUND_RED);
|
|
|
|
|