diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj b/CodeVirtualizer/CodeVirtualizer.vcxproj index da9ec6a..a02c7fc 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj @@ -151,6 +151,7 @@ + @@ -162,6 +163,7 @@ + diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters index 9ffa026..aedcfd9 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters @@ -29,6 +29,9 @@ Obfuscator + + Obfuscator\Nop + @@ -56,6 +59,9 @@ Obfuscator + + Obfuscator\Nop + @@ -79,5 +85,8 @@ {51b7ca69-a7e9-4634-9eb2-d70f211fe2d2} + + {4b1bac75-b456-46a5-ad8b-453ffef9eef9} + \ No newline at end of file diff --git a/CodeVirtualizer/Main.cpp b/CodeVirtualizer/Main.cpp index a9cc183..8836a2c 100644 --- a/CodeVirtualizer/Main.cpp +++ b/CodeVirtualizer/Main.cpp @@ -5,6 +5,7 @@ #include "NativeCode.h" #include "RipXorInst.h" +#include "RipMovInst.h" UCHAR TestBuffer[]{ 0x48, 0x33, 0xC0, @@ -30,14 +31,16 @@ int main() NATIVE_CODE_BLOCK Block; XedTablesInit(); - NcFromBuffer(&Block, TestBuffer, TestBufferSize); + NcDisassemble(&Block, TestBuffer, TestBufferSize); NcDebugPrint(&Block); NATIVE_CODE_LINK T; T.RawDataSize = 10; + T.RawData = new UCHAR[10]; + memset(T.RawData, 0xAA, 10); XOR_INST_DATA Data; RtlSecureZeroMemory(&Data, sizeof(XOR_INST_DATA)); - PNATIVE_CODE_BLOCK NewBlock = ObfEmitPreXorForInst(&T, &Data, TRUE); + PNATIVE_CODE_BLOCK NewBlock = ObfEmitPreMovForInst(&T); if (NewBlock) { printf("\n"); diff --git a/CodeVirtualizer/NativeCode.cpp b/CodeVirtualizer/NativeCode.cpp index 3d4f0f9..bd884a2 100644 --- a/CodeVirtualizer/NativeCode.cpp +++ b/CodeVirtualizer/NativeCode.cpp @@ -20,6 +20,16 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B) 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() { if (RawData) @@ -32,6 +42,46 @@ _NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK() 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) { 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 CONST& LabelIds) { 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) { - 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; } } @@ -238,11 +282,8 @@ PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta) 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; ULONG Offset = 0; @@ -262,25 +303,21 @@ BOOL NcFromBuffer(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize) Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst); Link->RawData = new UCHAR[Link->RawDataSize]; - Link->Block = Block; - Link->Prev = Block->End; - Block->End->Next = Link; - Block->End = Link; + NcAppendToBlock(Block, Link); 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); return TRUE; } +PVOID NcAssemble(PNATIVE_CODE_BLOCK Block) +{ + +} + VOID NcDelete(PNATIVE_CODE_BLOCK Block) { for (PNATIVE_CODE_LINK T = Block->Start; T;) diff --git a/CodeVirtualizer/NativeCode.h b/CodeVirtualizer/NativeCode.h index d521cb1..b0ad6a4 100644 --- a/CodeVirtualizer/NativeCode.h +++ b/CodeVirtualizer/NativeCode.h @@ -19,6 +19,7 @@ typedef struct _NATIVE_CODE_LINK XED_DECODED_INST XedInst; _NATIVE_CODE_LINK(); _NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); + _NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds); ~_NATIVE_CODE_LINK(); }NATIVE_CODE_LINK, *PNATIVE_CODE_LINK; @@ -30,14 +31,16 @@ typedef struct _NATIVE_CODE_BLOCK _NATIVE_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 NcInsertLinkBefore(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2); 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); ULONG NcGenUnusedLabelId(STDVECTOR CONST& LabelIds); @@ -52,7 +55,9 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block); 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); diff --git a/CodeVirtualizer/Nop.cpp b/CodeVirtualizer/Nop.cpp new file mode 100644 index 0000000..2801673 --- /dev/null +++ b/CodeVirtualizer/Nop.cpp @@ -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; +} \ No newline at end of file diff --git a/CodeVirtualizer/Nop.h b/CodeVirtualizer/Nop.h new file mode 100644 index 0000000..929471b --- /dev/null +++ b/CodeVirtualizer/Nop.h @@ -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 \ No newline at end of file diff --git a/CodeVirtualizer/RipMovInst.cpp b/CodeVirtualizer/RipMovInst.cpp index 7e7e439..f8402cd 100644 --- a/CodeVirtualizer/RipMovInst.cpp +++ b/CodeVirtualizer/RipMovInst.cpp @@ -3,82 +3,38 @@ BOOL ObfEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[DWORD_MOV_INST_RIP_OFFSET] = RipDelta; memcpy(&Link->RawData[DWORD_MOV_INST_MOV_OFFSET], Data, 4); - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + printf("%p memes\n", Link); + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0x66, 0xC7, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[WORD_MOV_INST_RIP_OFFSET] = RipDelta; memcpy(&Link->RawData[WORD_MOV_INST_MOV_OFFSET], Data, 2); - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0xC6, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[BYTE_MOV_INST_RIP_OFFSET] = RipDelta; Link->RawData[BYTE_MOV_INST_MOV_OFFSET] = *Data; - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); return TRUE; } @@ -101,6 +57,8 @@ PNATIVE_CODE_BLOCK ObfEmitPreMovForInst(PNATIVE_CODE_LINK Link, INT32 DeltaToIns RipDelta += ((FourByte - Count) * 4); RipDelta += DeltaToInst; //Add the actual instruction + printf("%p IS THE DATAOFFSET\n", DataOffset); + system("pause"); if (!ObfEmitRipRelativeMovD(Block, RipDelta, DataOffset)) { NcDelete(Block); diff --git a/CodeVirtualizer/RipMovInst.h b/CodeVirtualizer/RipMovInst.h index 12c1bc8..0c133a2 100644 --- a/CodeVirtualizer/RipMovInst.h +++ b/CodeVirtualizer/RipMovInst.h @@ -23,9 +23,9 @@ BOOL ObfEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat 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); diff --git a/CodeVirtualizer/RipXorInst.cpp b/CodeVirtualizer/RipXorInst.cpp index 0a0ef5a..b27b74a 100644 --- a/CodeVirtualizer/RipXorInst.cpp +++ b/CodeVirtualizer/RipXorInst.cpp @@ -3,125 +3,55 @@ BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block) { - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; - Link->Flags = CODE_FLAG_IS_INST; - Link->RawData = new UCHAR[1]; - *(PUCHAR)(Link->RawData) = 0x9C; - 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; + UCHAR RawData[] = { 0x9C }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1); + XedDecode(&Link->XedInst, Link->RawData, 1); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitPopfqInst(PNATIVE_CODE_BLOCK Block) { - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK; - Link->Flags = CODE_FLAG_IS_INST; - Link->RawData = new UCHAR[1]; - *(PUCHAR)(Link->RawData) = 0x9D; - 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; + UCHAR RawData[] = { 0x9D }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1); + XedDecode(&Link->XedInst, Link->RawData, 1); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[DWORD_XOR_INST_RIP_OFFSET] = RipDelta; *(PULONG)&Link->RawData[DWORD_XOR_INST_XOR_OFFSET] = Value; - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0x66, 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[WORD_XOR_INST_RIP_OFFSET] = RipDelta; *(PUSHORT)&Link->RawData[WORD_XOR_INST_XOR_OFFSET] = (USHORT)Value; - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); return TRUE; } BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) { - UCHAR Bytes[] = { 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); + UCHAR RawData[] = { 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00 }; + PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, sizeof(RawData)); *(PINT32)&Link->RawData[BYTE_XOR_INST_RIP_OFFSET] = RipDelta; *(PUCHAR)&Link->RawData[BYTE_XOR_INST_XOR_OFFSET] = (UCHAR)Value; - - XED_ERROR_ENUM DecodeError = XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); - 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; + XedDecode(&Link->XedInst, Link->RawData, Link->RawDataSize); + NcAppendToBlock(Block, Link); 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) { 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)); PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; - - Block->Start = Block->End = new NATIVE_CODE_LINK; + if (!Block) + return NULL; if (SaveFlags && !ObfEmitPushfqInst(Block)) { @@ -225,12 +227,6 @@ PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA X return NULL; } - PNATIVE_CODE_LINK StartLink = Block->Start; - Block->Start = Block->Start->Next; - if (Block->Start) - Block->Start->Prev = NULL; - delete StartLink; - 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)); PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; - - Block->Start = Block->End = new NATIVE_CODE_LINK; + if (!Block) + return NULL; if (SaveFlags && !ObfEmitPushfqInst(Block)) { @@ -311,11 +307,5 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA return NULL; } - PNATIVE_CODE_LINK StartLink = Block->Start; - Block->Start = Block->Start->Next; - if (Block->Start) - Block->Start->Prev = NULL; - delete StartLink; - return Block; } diff --git a/CodeVirtualizer/RipXorInst.h b/CodeVirtualizer/RipXorInst.h index 346752c..9d1dd40 100644 --- a/CodeVirtualizer/RipXorInst.h +++ b/CodeVirtualizer/RipXorInst.h @@ -35,6 +35,12 @@ BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu 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 ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags, INT32 DeltaToInst = 0); diff --git a/CodeVirtualizer/Windas.h b/CodeVirtualizer/Windas.h index 14af02e..d34980f 100644 --- a/CodeVirtualizer/Windas.h +++ b/CodeVirtualizer/Windas.h @@ -12,5 +12,15 @@ #define STDVECTOR std::vector #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 \ No newline at end of file diff --git a/CodeVirtualizer/XedWrap.h b/CodeVirtualizer/XedWrap.h index 9009e94..90a3e30 100644 --- a/CodeVirtualizer/XedWrap.h +++ b/CodeVirtualizer/XedWrap.h @@ -11,6 +11,8 @@ extern "C" #define XED_DECODED_INST xed_decoded_inst_t #define XED_INST xed_inst_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_ERROR_ENUM xed_error_enum_t @@ -29,6 +31,7 @@ extern "C" #define XedDecodedInstInst xed_decoded_inst_inst #define XedDecodedInstNumOperands xed_decoded_inst_noperands #define XedDecodedInstGetIClass xed_decoded_inst_get_iclass +#define XedDecodedInstGetRflagsInfo xed_decoded_inst_get_rflags_info #define XedInstOperand xed_inst_operand @@ -38,4 +41,8 @@ extern "C" #define XedErrorEnumToString xed_error_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 \ No newline at end of file diff --git a/x64/Debug/CodeVirtualizer.ilk b/x64/Debug/CodeVirtualizer.ilk index 8ed8b6b..da2fac0 100644 Binary files a/x64/Debug/CodeVirtualizer.ilk and b/x64/Debug/CodeVirtualizer.ilk differ