deal with flags for xoring instructions

basically decide if we need to save and restore flags before xoring prior two and after the instruction executes.
main
James 3 years ago
parent a88fbcbde1
commit feaed17402

@ -151,6 +151,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="NativeCode.cpp" /> <ClCompile Include="NativeCode.cpp" />
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
<ClCompile Include="Nop.cpp" />
<ClCompile Include="Obfuscator.cpp" /> <ClCompile Include="Obfuscator.cpp" />
<ClCompile Include="RipMovInst.cpp" /> <ClCompile Include="RipMovInst.cpp" />
<ClCompile Include="RipXorInst.cpp" /> <ClCompile Include="RipXorInst.cpp" />
@ -162,6 +163,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="Code.h" /> <ClInclude Include="Code.h" />
<ClInclude Include="NativeCode.h" /> <ClInclude Include="NativeCode.h" />
<ClInclude Include="Nop.h" />
<ClInclude Include="Obfuscator.h" /> <ClInclude Include="Obfuscator.h" />
<ClInclude Include="RipMovInst.h" /> <ClInclude Include="RipMovInst.h" />
<ClInclude Include="RipXorInst.h" /> <ClInclude Include="RipXorInst.h" />

@ -29,6 +29,9 @@
<ClInclude Include="Obfuscator.h"> <ClInclude Include="Obfuscator.h">
<Filter>Obfuscator</Filter> <Filter>Obfuscator</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Nop.h">
<Filter>Obfuscator\Nop</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
@ -56,6 +59,9 @@
<ClCompile Include="Obfuscator.cpp"> <ClCompile Include="Obfuscator.cpp">
<Filter>Obfuscator</Filter> <Filter>Obfuscator</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Nop.cpp">
<Filter>Obfuscator\Nop</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Xed"> <Filter Include="Xed">
@ -79,5 +85,8 @@
<Filter Include="Obfuscator\RipXorInst"> <Filter Include="Obfuscator\RipXorInst">
<UniqueIdentifier>{51b7ca69-a7e9-4634-9eb2-d70f211fe2d2}</UniqueIdentifier> <UniqueIdentifier>{51b7ca69-a7e9-4634-9eb2-d70f211fe2d2}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Obfuscator\Nop">
<UniqueIdentifier>{4b1bac75-b456-46a5-ad8b-453ffef9eef9}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -5,6 +5,7 @@
#include "NativeCode.h" #include "NativeCode.h"
#include "RipXorInst.h" #include "RipXorInst.h"
#include "RipMovInst.h"
UCHAR TestBuffer[]{ UCHAR TestBuffer[]{
0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0,
@ -30,14 +31,16 @@ int main()
NATIVE_CODE_BLOCK Block; NATIVE_CODE_BLOCK Block;
XedTablesInit(); XedTablesInit();
NcFromBuffer(&Block, TestBuffer, TestBufferSize); NcDisassemble(&Block, TestBuffer, TestBufferSize);
NcDebugPrint(&Block); NcDebugPrint(&Block);
NATIVE_CODE_LINK T; NATIVE_CODE_LINK T;
T.RawDataSize = 10; T.RawDataSize = 10;
T.RawData = new UCHAR[10];
memset(T.RawData, 0xAA, 10);
XOR_INST_DATA Data; XOR_INST_DATA Data;
RtlSecureZeroMemory(&Data, sizeof(XOR_INST_DATA)); RtlSecureZeroMemory(&Data, sizeof(XOR_INST_DATA));
PNATIVE_CODE_BLOCK NewBlock = ObfEmitPreXorForInst(&T, &Data, TRUE); PNATIVE_CODE_BLOCK NewBlock = ObfEmitPreMovForInst(&T);
if (NewBlock) if (NewBlock)
{ {
printf("\n"); printf("\n");

@ -20,6 +20,16 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B)
Flags = CODE_FLAG_IS_LABEL; Flags = CODE_FLAG_IS_LABEL;
} }
_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds)
: _NATIVE_CODE_LINK()
{
Flags = F;
RawDataSize = Rds;
RawData = new UCHAR[Rds];
if (Rd)
memcpy(RawData, Rd, Rds);
}
_NATIVE_CODE_LINK::~_NATIVE_CODE_LINK() _NATIVE_CODE_LINK::~_NATIVE_CODE_LINK()
{ {
if (RawData) if (RawData)
@ -32,6 +42,46 @@ _NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK()
HasRelativeJumps = FALSE; HasRelativeJumps = FALSE;
} }
VOID NcAppendToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link)
{
if (!Link)
return;
Link->Block = Block;
Link->Prev = Block->End;
Link->Next = NULL;
if (!Block->End || !Block->Start)
{
Block->Start = Block->End = Link;
}
else
{
Block->End->Next = Link;
Block->End = Link;
}
}
VOID NcPrependToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link)
{
if (!Link)
return;
Link->Block = Block;
Link->Next = Block->Start;
Link->Prev = NULL;
if (!Block->End || !Block->Start)
{
Block->Start = Block->End = Link;
}
else
{
Block->Start->Prev = Link;
Block->Start = Link;
}
}
VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2) VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2)
{ {
if (Link1) if (Link1)
@ -67,12 +117,6 @@ VOID NcUnlink(PNATIVE_CODE_LINK Link)
} }
} }
VOID NcConcat(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2)
{
//Cant simply concatinate blocks here, need to go through the second block and
//update the label names so that there are no conflicts between the two blocks
}
ULONG NcGenUnusedLabelId(STDVECTOR<ULONG> CONST& LabelIds) ULONG NcGenUnusedLabelId(STDVECTOR<ULONG> CONST& LabelIds)
{ {
ULONG ReturnLabelId = rand(); ULONG ReturnLabelId = rand();
@ -85,7 +129,7 @@ VOID NcChangeLabelId(PNATIVE_CODE_BLOCK Block1, ULONG Original, ULONG New)
{ {
for (PNATIVE_CODE_LINK T = Block1->Start; T; T = T->Next) for (PNATIVE_CODE_LINK T = Block1->Start; T; T = T->Next)
{ {
if ((T->Flags & CODE_FLAG_IS_LABEL) && 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;
} }
} }
@ -238,11 +282,8 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta)
return Jmp; return Jmp;
} }
BOOL NcFromBuffer(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize) BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
{ {
Block->Start = new NATIVE_CODE_LINK;
Block->End = Block->Start;
PUCHAR Buf = (PUCHAR)Buffer; PUCHAR Buf = (PUCHAR)Buffer;
ULONG Offset = 0; ULONG Offset = 0;
@ -262,25 +303,21 @@ BOOL NcFromBuffer(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst); Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst);
Link->RawData = new UCHAR[Link->RawDataSize]; Link->RawData = new UCHAR[Link->RawDataSize];
Link->Block = Block; NcAppendToBlock(Block, Link);
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
Offset += Link->RawDataSize; Offset += Link->RawDataSize;
} }
PNATIVE_CODE_LINK StartLink = Block->Start;
Block->Start = Block->Start->Next;
if (Block->Start)
Block->Start->Prev = NULL;
delete StartLink;
NcCreateLabels(Block); NcCreateLabels(Block);
return TRUE; return TRUE;
} }
PVOID NcAssemble(PNATIVE_CODE_BLOCK Block)
{
}
VOID NcDelete(PNATIVE_CODE_BLOCK Block) VOID NcDelete(PNATIVE_CODE_BLOCK Block)
{ {
for (PNATIVE_CODE_LINK T = Block->Start; T;) for (PNATIVE_CODE_LINK T = Block->Start; T;)

@ -19,6 +19,7 @@ typedef struct _NATIVE_CODE_LINK
XED_DECODED_INST XedInst; XED_DECODED_INST XedInst;
_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(); ~_NATIVE_CODE_LINK();
}NATIVE_CODE_LINK, *PNATIVE_CODE_LINK; }NATIVE_CODE_LINK, *PNATIVE_CODE_LINK;
@ -30,14 +31,16 @@ typedef struct _NATIVE_CODE_BLOCK
_NATIVE_CODE_BLOCK(); _NATIVE_CODE_BLOCK();
}NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK; }NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK;
VOID NcAppendToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link);
VOID NcPrependToBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_LINK Link);
VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2); VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2);
VOID NcInsertLinkBefore(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2); VOID NcInsertLinkBefore(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2);
VOID NcUnlink(PNATIVE_CODE_LINK Link); VOID NcUnlink(PNATIVE_CODE_LINK Link);
VOID NcConcat(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2);
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(STDVECTOR<ULONG> CONST& LabelIds);
@ -52,7 +55,9 @@ 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);
BOOL NcFromBuffer(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize); BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize);
PVOID NcAssemble(PNATIVE_CODE_BLOCK Block);
VOID NcDelete(PNATIVE_CODE_BLOCK Block); VOID NcDelete(PNATIVE_CODE_BLOCK Block);

@ -0,0 +1,27 @@
#include "Nop.h"
PNATIVE_CODE_LINK NcEmitNop()
{
UCHAR RawData[] = { 0x90 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInst, Link->RawData, 1);
return Link;
}
PNATIVE_CODE_BLOCK NcEmitNopGroup(ULONG Count)
{
if (Count < 1)
return NULL;
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
if (!Block)
return NULL;
while (Count)
{
NcAppendToBlock(Block, NcEmitNop());
Count--;
}
return Block;
}

@ -0,0 +1,12 @@
#ifndef __NOP_H
#define __NOP_H
#include "Windas.h"
#include "XedWrap.h"
#include "NativeCode.h"
PNATIVE_CODE_LINK NcEmitNop();
PNATIVE_CODE_BLOCK NcEmitNopGroup(ULONG Count);
#endif

@ -3,82 +3,38 @@
BOOL ObfEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) BOOL ObfEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
{ {
UCHAR Bytes[] = { 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[DWORD_MOV_INST_LENGTH];
Link->RawDataSize = DWORD_MOV_INST_LENGTH;
memcpy(Link->RawData, Bytes, DWORD_MOV_INST_LENGTH);
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData));
*(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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize);
if (DecodeError != XED_ERROR_NONE) NcAppendToBlock(Block, Link);
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
{ {
UCHAR Bytes[] = { 0x66, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0x66, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[WORD_MOV_INST_LENGTH];
Link->RawDataSize = WORD_MOV_INST_LENGTH;
memcpy(Link->RawData, Bytes, WORD_MOV_INST_LENGTH);
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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); NcAppendToBlock(Block, Link);
if (DecodeError != XED_ERROR_NONE)
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
{ {
UCHAR Bytes[] = { 0xC6, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0xC6, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[BYTE_MOV_INST_LENGTH];
Link->RawDataSize = BYTE_MOV_INST_LENGTH;
memcpy(Link->RawData, Bytes, BYTE_MOV_INST_LENGTH);
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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); NcAppendToBlock(Block, Link);
if (DecodeError != XED_ERROR_NONE)
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
@ -101,6 +57,8 @@ PNATIVE_CODE_BLOCK ObfEmitPreMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToIns
RipDelta += ((FourByte - Count) * 4); RipDelta += ((FourByte - Count) * 4);
RipDelta += DeltaToInst; RipDelta += DeltaToInst;
//Add the actual instruction //Add the actual instruction
printf("%p IS THE DATAOFFSET\n", DataOffset);
system("pause");
if (!ObfEmitRipRelativeMovD(Block, RipDelta, DataOffset)) if (!ObfEmitRipRelativeMovD(Block, RipDelta, DataOffset))
{ {
NcDelete(Block); NcDelete(Block);

@ -23,9 +23,9 @@ BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat
BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data);
PNATIVE_CODE_BLOCK ObfEmitPreMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToInst); PNATIVE_CODE_BLOCK ObfEmitPreMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToInst = 0);
PNATIVE_CODE_BLOCK ObfEmitPostMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToInst); PNATIVE_CODE_BLOCK ObfEmitPostMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToInst = 0);

@ -3,125 +3,55 @@
BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block) BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block)
{ {
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; UCHAR RawData[] = { 0x9C };
Link->Flags = CODE_FLAG_IS_INST; PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
Link->RawData = new UCHAR[1]; XedDecode(&Link->XedInst, Link->RawData, 1);
*(PUCHAR)(Link->RawData) = 0x9C; NcAppendToBlock(Block, Link);
Link->RawDataSize = 1;
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, 1);
if (DecodeError != XED_ERROR_NONE)
{
printf("Pushfq decode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitPopfqInst(PNATIVE_CODE_BLOCK Block) BOOL ObfEmitPopfqInst(PNATIVE_CODE_BLOCK Block)
{ {
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; UCHAR RawData[] = { 0x9D };
Link->Flags = CODE_FLAG_IS_INST; PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
Link->RawData = new UCHAR[1]; XedDecode(&Link->XedInst, Link->RawData, 1);
*(PUCHAR)(Link->RawData) = 0x9D; NcAppendToBlock(Block, Link);
Link->RawDataSize = 1;
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, 1);
if (DecodeError != XED_ERROR_NONE)
{
printf("Popfq decode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value)
{ {
UCHAR Bytes[] = { 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[DWORD_XOR_INST_LENGTH];
Link->RawDataSize = DWORD_XOR_INST_LENGTH;
memcpy(Link->RawData, Bytes, DWORD_XOR_INST_LENGTH);
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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); NcAppendToBlock(Block, Link);
if (DecodeError != XED_ERROR_NONE)
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) BOOL ObfEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value)
{ {
UCHAR Bytes[] = { 0x66, 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0x66, 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[WORD_XOR_INST_LENGTH];
Link->RawDataSize = WORD_XOR_INST_LENGTH;
memcpy(Link->RawData, Bytes, WORD_XOR_INST_LENGTH);
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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); NcAppendToBlock(Block, Link);
if (DecodeError != XED_ERROR_NONE)
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value)
{ {
UCHAR Bytes[] = { 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00 }; UCHAR RawData[] = { 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00 };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK;
Link->Flags = CODE_FLAG_IS_INST;
Link->RawData = new UCHAR[BYTE_XOR_INST_LENGTH];
Link->RawDataSize = BYTE_XOR_INST_LENGTH;
memcpy(Link->RawData, Bytes, BYTE_XOR_INST_LENGTH);
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);
XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); NcAppendToBlock(Block, Link);
if (DecodeError != XED_ERROR_NONE)
{
printf("XedDecode failed with error %s\n", XedErrorEnumToString(DecodeError));
delete Link;
return FALSE;
}
Link->Block = Block;
Link->Prev = Block->End;
Block->End->Next = Link;
Block->End = Link;
return TRUE; return TRUE;
} }
@ -150,6 +80,78 @@ VOID ObfXorInstBytes(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData)
} }
BOOL ObfiCheckXorFlagCollisions(CONST XED_FLAG_SET* FlagsRead, XED_FLAG_SET Ledger)
{
return ((FlagsRead->s.zf && FlagsRead->s.zf == Ledger.s.zf) ||
(FlagsRead->s.sf && FlagsRead->s.sf == Ledger.s.sf) ||
(FlagsRead->s.pf && FlagsRead->s.pf == Ledger.s.pf) ||
(FlagsRead->s.of && FlagsRead->s.of == Ledger.s.of) ||
(FlagsRead->s.cf && FlagsRead->s.cf == Ledger.s.cf) ||
(FlagsRead->s.af && FlagsRead->s.af == Ledger.s.af)
);
}
VOID ObfiUpdateXorLedger(CONST XED_FLAG_SET* FlagsWritten, XED_FLAG_SET* Ledger)
{
if (FlagsWritten->s.zf)
Ledger->s.zf = FALSE;
if (FlagsWritten->s.sf)
Ledger->s.sf = FALSE;
if (FlagsWritten->s.pf)
Ledger->s.pf = FALSE;
if (FlagsWritten->s.of)
Ledger->s.of = FALSE;
if (FlagsWritten->s.cf)
Ledger->s.cf = FALSE;
if (FlagsWritten->s.af)
Ledger->s.af = FALSE;
}
BOOL ObfDoesInstWriteToAllXorFlags(PNATIVE_CODE_LINK Link)
{
CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&Link->XedInst);
CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);
CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(SimpleFlags);
return (FlagsWritten->s.zf &&
FlagsWritten->s.sf &&
FlagsWritten->s.pf &&
FlagsWritten->s.of &&
FlagsWritten->s.cf &&
FlagsUndefined->s.af
);
}
BOOL ObfAreXorFlagsClobberedBeforeUse(PNATIVE_CODE_LINK Link)
{
XED_FLAG_SET Ledger;
Ledger.s.zf = TRUE;
Ledger.s.sf = TRUE;
Ledger.s.pf = TRUE;
Ledger.s.of = TRUE;
Ledger.s.cf = TRUE;
Ledger.s.af = TRUE;
for (PNATIVE_CODE_LINK T = Link->Next; T; T = T->Next)
{
if (T->Flags & CODE_FLAG_IS_LABEL)
continue;
CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&T->XedInst);
CONST XED_FLAG_SET* FlagsRead = XedSimpleFlagGetReadFlagSet(SimpleFlags);
CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);
if (ObfiCheckXorFlagCollisions(FlagsRead, Ledger))
return FALSE;
ObfiUpdateXorLedger(FlagsWritten, &Ledger);
if (Ledger.flat == 0)
return TRUE;
}
return FALSE;
}
PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst) PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst)
{ {
ULONG FourByte = Link->RawDataSize / 4; ULONG FourByte = Link->RawDataSize / 4;
@ -157,8 +159,8 @@ PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA X
ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2));
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
if (!Block)
Block->Start = Block->End = new NATIVE_CODE_LINK; return NULL;
if (SaveFlags && !ObfEmitPushfqInst(Block)) if (SaveFlags && !ObfEmitPushfqInst(Block))
{ {
@ -225,12 +227,6 @@ PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA X
return NULL; return NULL;
} }
PNATIVE_CODE_LINK StartLink = Block->Start;
Block->Start = Block->Start->Next;
if (Block->Start)
Block->Start->Prev = NULL;
delete StartLink;
return Block; return Block;
} }
@ -241,8 +237,8 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA
ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2));
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
if (!Block)
Block->Start = Block->End = new NATIVE_CODE_LINK; return NULL;
if (SaveFlags && !ObfEmitPushfqInst(Block)) if (SaveFlags && !ObfEmitPushfqInst(Block))
{ {
@ -311,11 +307,5 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA
return NULL; return NULL;
} }
PNATIVE_CODE_LINK StartLink = Block->Start;
Block->Start = Block->Start->Next;
if (Block->Start)
Block->Start->Prev = NULL;
delete StartLink;
return Block; return Block;
} }

@ -35,6 +35,12 @@ BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu
VOID ObfXorInstBytes(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData); VOID ObfXorInstBytes(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData);
//Used to see if the PreXor needs to save the flags.
//If all flags are written to by the XORs are also written to by the target inst theres no point in saving flags
BOOL ObfDoesInstWriteToAllXorFlags(PNATIVE_CODE_LINK Link);
BOOL ObfAreXorFlagsClobberedBeforeUse(PNATIVE_CODE_LINK Link);
PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst = 0); PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst = 0);
PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst = 0); PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst = 0);

@ -12,5 +12,15 @@
#define STDVECTOR std::vector #define STDVECTOR std::vector
#define StdFind std::find #define StdFind std::find
/*
* Prefixes:
* Nc -> Native Code function
* Vc -> Virtual Code function
* Obf -> Obfuscator function
* Obfi -> Internal obfuscator function
* Xed -> Xed macro wrapper
* Vm -> Virtual Machine function
*/
#endif #endif

@ -11,6 +11,8 @@ extern "C"
#define XED_DECODED_INST xed_decoded_inst_t #define XED_DECODED_INST xed_decoded_inst_t
#define XED_INST xed_inst_t #define XED_INST xed_inst_t
#define XED_OPERAND xed_operand_t #define XED_OPERAND xed_operand_t
#define XED_SIMPLE_FLAG xed_simple_flag_t
#define XED_FLAG_SET xed_flag_set_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
@ -29,6 +31,7 @@ extern "C"
#define XedDecodedInstInst xed_decoded_inst_inst #define XedDecodedInstInst xed_decoded_inst_inst
#define XedDecodedInstNumOperands xed_decoded_inst_noperands #define XedDecodedInstNumOperands xed_decoded_inst_noperands
#define XedDecodedInstGetIClass xed_decoded_inst_get_iclass #define XedDecodedInstGetIClass xed_decoded_inst_get_iclass
#define XedDecodedInstGetRflagsInfo xed_decoded_inst_get_rflags_info
#define XedInstOperand xed_inst_operand #define XedInstOperand xed_inst_operand
@ -38,4 +41,8 @@ extern "C"
#define XedErrorEnumToString xed_error_enum_t2str #define XedErrorEnumToString xed_error_enum_t2str
#define XedCategoryEnumToString xed_category_enum_t2str #define XedCategoryEnumToString xed_category_enum_t2str
#define XedSimpleFlagGetReadFlagSet xed_simple_flag_get_read_flag_set
#define XedSimpleFlagGetWrittenFlagSet xed_simple_flag_get_written_flag_set
#define XedSimpleFlagGetUndefinedFlagSet xed_simple_flag_get_undefined_flag_set
#endif #endif

Binary file not shown.
Loading…
Cancel
Save