diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj b/CodeVirtualizer/CodeVirtualizer.vcxproj index 7307d50..2891904 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj @@ -151,7 +151,8 @@ - + + @@ -160,7 +161,8 @@ - + + diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters index 10fbd2c..abd0b5e 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters @@ -20,8 +20,11 @@ VirtualMachine - - Obfuscator\XorInstructions + + Obfuscator\RipXorInst + + + Obfuscator\RipMovInst @@ -41,8 +44,11 @@ VirtualMachine - - Obfuscator\XorInstructions + + Obfuscator\RipXorInst + + + Obfuscator\RipMovInst @@ -55,16 +61,16 @@ {f74192e7-2064-44d2-983c-fac92f468c0a} - - {65f3fdd3-b851-4e50-8a48-d1ecb4af2f91} - {d784ddc8-2452-41ff-bc20-582ec03b3eb5} {cc5b78db-cdf7-4b83-9652-2722cbdec89e} - + + {7040cc27-0179-47d5-9908-962d224b8c6e} + + {51b7ca69-a7e9-4634-9eb2-d70f211fe2d2} diff --git a/CodeVirtualizer/Main.cpp b/CodeVirtualizer/Main.cpp index 03ad7fb..a9cc183 100644 --- a/CodeVirtualizer/Main.cpp +++ b/CodeVirtualizer/Main.cpp @@ -4,7 +4,7 @@ #include "NativeCode.h" -#include "XorInstructions.h" +#include "RipXorInst.h" UCHAR TestBuffer[]{ 0x48, 0x33, 0xC0, @@ -34,10 +34,10 @@ int main() NcDebugPrint(&Block); NATIVE_CODE_LINK T; - T.RawDataSize = 7; + T.RawDataSize = 10; XOR_INST_DATA Data; RtlSecureZeroMemory(&Data, sizeof(XOR_INST_DATA)); - PNATIVE_CODE_BLOCK NewBlock = ObfEmitPostXorForInst(&T, &Data, TRUE); + PNATIVE_CODE_BLOCK NewBlock = ObfEmitPreXorForInst(&T, &Data, TRUE); if (NewBlock) { printf("\n"); diff --git a/CodeVirtualizer/NativeCode.cpp b/CodeVirtualizer/NativeCode.cpp index 435c94a..a72673b 100644 --- a/CodeVirtualizer/NativeCode.cpp +++ b/CodeVirtualizer/NativeCode.cpp @@ -96,10 +96,14 @@ BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block) Block->End->Next = Link; Link->Prev = Block->End; - return TRUE; } - return FALSE; + for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next) + { + T->Block = Link->Block; + } + + return TRUE; } BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) diff --git a/CodeVirtualizer/RipMovInst.cpp b/CodeVirtualizer/RipMovInst.cpp new file mode 100644 index 0000000..89f2dbc --- /dev/null +++ b/CodeVirtualizer/RipMovInst.cpp @@ -0,0 +1,209 @@ +#include "RipMovInst.h" + + +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); + + *(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; + 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); + + *(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; + 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); + + *(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; + return TRUE; +} + +PNATIVE_CODE_BLOCK ObfEmitPreMovForInst(PNATIVE_CODE_LINK Link) +{ + ULONG FourByte = Link->RawDataSize / 4; + ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; + ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); + + PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; + + Block->Start = Block->End = new NATIVE_CODE_LINK; + PUCHAR DataOffset = Link->RawData; + ULONG Count = FourByte; + while (Count) + { + //Account for remaining MOVs + INT32 RipDelta = (((Count - 1) * DWORD_MOV_INST_LENGTH) + (TwoByte * WORD_MOV_INST_LENGTH) + (OneByte * BYTE_MOV_INST_LENGTH)); + //Account for already MOVd instructions + RipDelta += ((FourByte - Count) * 4); + //Add the actual instruction + if (!ObfEmitRipRelativeMovD(Block, RipDelta, DataOffset)) + { + NcDelete(Block); + delete Block; + return NULL; + } + DataOffset += 4; + --Count; + } + + if (TwoByte) + { + INT32 RipDelta = (OneByte * BYTE_MOV_INST_LENGTH); + RipDelta += (FourByte * 4); + if (!ObfEmitRipRelativeMovW(Block, RipDelta, DataOffset)) + { + NcDelete(Block); + delete Block; + return NULL; + } + DataOffset += 2; + } + + if (OneByte) + { + INT32 RipDelta = 0; + RipDelta += (FourByte * 4) + (TwoByte * 2); + if (!ObfEmitRipRelativeMovB(Block, RipDelta, DataOffset)) + { + NcDelete(Block); + delete Block; + return NULL; + } + } + + PNATIVE_CODE_LINK StartLink = Block->Start; + Block->Start = Block->Start->Next; + if (Block->Start) + Block->Start->Prev = NULL; + delete StartLink; + + return Block; +} + +PNATIVE_CODE_BLOCK ObfEmitPostMovForInst(PNATIVE_CODE_LINK Link) +{ + ULONG FourByte = Link->RawDataSize / 4; + ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; + ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); + + PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK; + + Block->Start = Block->End = new NATIVE_CODE_LINK; + ULONG ZeroValue = 0; + ULONG Count = FourByte; + while (Count) + { + INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4); + RipDelta += (FourByte - (Count - 1)) * DWORD_MOV_INST_LENGTH; + RipDelta *= (-1); + if (!ObfEmitRipRelativeMovD(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDelete(Block); + delete Block; + return NULL; + } + --Count; + } + + if (TwoByte) + { + INT32 RipDelta = Link->RawDataSize - (FourByte * 4); + RipDelta += (FourByte * DWORD_MOV_INST_LENGTH); + RipDelta += WORD_MOV_INST_LENGTH; + RipDelta *= (-1); + + if (!ObfEmitRipRelativeMovW(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDelete(Block); + delete Block; + return NULL; + } + } + + if (OneByte) + { + INT32 RipDelta = Link->RawDataSize - (FourByte * 4) - (TwoByte * 2); + RipDelta += (FourByte * DWORD_MOV_INST_LENGTH); + RipDelta += WORD_MOV_INST_LENGTH; + RipDelta += BYTE_MOV_INST_LENGTH; + RipDelta *= (-1); + if (!ObfEmitRipRelativeMovB(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDelete(Block); + delete Block; + return NULL; + } + } + + PNATIVE_CODE_LINK StartLink = Block->Start; + Block->Start = Block->Start->Next; + if (Block->Start) + Block->Start->Prev = NULL; + delete StartLink; + + return Block; +} \ No newline at end of file diff --git a/CodeVirtualizer/RipMovInst.h b/CodeVirtualizer/RipMovInst.h new file mode 100644 index 0000000..eb7bb2c --- /dev/null +++ b/CodeVirtualizer/RipMovInst.h @@ -0,0 +1,32 @@ +#ifndef __RIP_MOV_INST_H +#define __RIP_MOV_INST_H + +#include "Windas.h" +#include "XedWrap.h" +#include "NativeCode.h" + +#define DWORD_MOV_INST_LENGTH 10 +#define DWORD_MOV_INST_RIP_OFFSET 2 +#define DWORD_MOV_INST_MOV_OFFSET 6 + +#define WORD_MOV_INST_LENGTH 9 +#define WORD_MOV_INST_RIP_OFFSET 3 +#define WORD_MOV_INST_MOV_OFFSET 7 + +#define BYTE_MOV_INST_LENGTH 7 +#define BYTE_MOV_INST_RIP_OFFSET 2 +#define BYTE_MOV_INST_MOV_OFFSET 6 + +BOOL ObfEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); + +BOOL ObfEmitRipRelativeMovW(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); + +PNATIVE_CODE_BLOCK ObfEmitPostMovForInst(PNATIVE_CODE_LINK Link); + + + +#endif diff --git a/CodeVirtualizer/XorInstructions.cpp b/CodeVirtualizer/RipXorInst.cpp similarity index 93% rename from CodeVirtualizer/XorInstructions.cpp rename to CodeVirtualizer/RipXorInst.cpp index 2fe26da..6a9f360 100644 --- a/CodeVirtualizer/XorInstructions.cpp +++ b/CodeVirtualizer/RipXorInst.cpp @@ -1,4 +1,4 @@ -#include "XorInstructions.h" +#include "RipXorInst.h" BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block) @@ -63,6 +63,7 @@ BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu delete Link; return FALSE; } + Link->Block = Block; Link->Prev = Block->End; Block->End->Next = Link; @@ -124,6 +125,31 @@ BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Valu return TRUE; } +VOID ObfXorInstBytes(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData) +{ + ULONG FourByte = Link->RawDataSize / 4; + ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; + ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); + + PUCHAR Buffer = Link->RawData; + while (FourByte) + { + *(PULONG)Buffer ^= XorData->Data[2 - FourByte]; + Buffer += 4; + FourByte--; + } + + if (TwoByte) + { + *(PUSHORT)Buffer ^= (USHORT)XorData->Data[3]; + Buffer += 2; + } + + if (OneByte) + *(PUCHAR)Buffer ^= (UCHAR)XorData->Data[3]; + +} + PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags) { ULONG FourByte = Link->RawDataSize / 4; @@ -225,22 +251,17 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA ULONG Count = FourByte; while (Count) { - INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4); if (SaveFlags) RipDelta += 1; - RipDelta += (FourByte - (Count - 1)) * DWORD_XOR_INST_LENGTH; - RipDelta *= (-1); - if (!ObfEmitRipRelativeXorD(Block, RipDelta, XorData->Data[FourByte - Count])) { NcDelete(Block); delete Block; return NULL; } - --Count; } @@ -249,11 +270,8 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA INT32 RipDelta = Link->RawDataSize - (FourByte * 4); if (SaveFlags) RipDelta += 1; - RipDelta += (FourByte * DWORD_XOR_INST_LENGTH); - RipDelta += WORD_XOR_INST_LENGTH; - RipDelta *= (-1); if (!ObfEmitRipRelativeXorW(Block, RipDelta, XorData->Data[3])) @@ -269,15 +287,10 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA INT32 RipDelta = Link->RawDataSize - (FourByte * 4) - (TwoByte * 2); if (SaveFlags) RipDelta += 1; - RipDelta += (FourByte * DWORD_XOR_INST_LENGTH); - RipDelta += WORD_XOR_INST_LENGTH; - RipDelta += BYTE_XOR_INST_LENGTH; - RipDelta *= (-1); - if (!ObfEmitRipRelativeXorB(Block, RipDelta, XorData->Data[4])) { NcDelete(Block); @@ -300,4 +313,4 @@ PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA delete StartLink; return Block; -} \ No newline at end of file +} diff --git a/CodeVirtualizer/XorInstructions.h b/CodeVirtualizer/RipXorInst.h similarity index 88% rename from CodeVirtualizer/XorInstructions.h rename to CodeVirtualizer/RipXorInst.h index ab3476a..dbc72ff 100644 --- a/CodeVirtualizer/XorInstructions.h +++ b/CodeVirtualizer/RipXorInst.h @@ -1,5 +1,5 @@ -#ifndef __CRYPTED_CODE_H -#define __CRYPTED_CODE_H +#ifndef __RIP_XOR_INST_H +#define __RIP_XOR_INST_H #include "Windas.h" #include "XedWrap.h" @@ -24,11 +24,21 @@ typedef struct _XOR_INST_DATA }XOR_INST_DATA, *PXOR_INST_DATA; BOOL ObfEmitPushfqInst(PNATIVE_CODE_BLOCK Block); + BOOL ObfEmitPopfqInst(PNATIVE_CODE_BLOCK Block); + BOOL ObfEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); + BOOL ObfEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); + BOOL ObfEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); + +VOID ObfXorInstBytes(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData); + PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags); + PNATIVE_CODE_BLOCK ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags); + + #endif diff --git a/x64/Debug/CodeVirtualizer.ilk b/x64/Debug/CodeVirtualizer.ilk index 3a5073e..8ed8b6b 100644 Binary files a/x64/Debug/CodeVirtualizer.ilk and b/x64/Debug/CodeVirtualizer.ilk differ