From 5d46bc31dd0ad7e8342f1854cf20fb5bd9a6028c Mon Sep 17 00:00:00 2001 From: Iizerd Date: Sat, 11 Dec 2021 10:50:30 -0800 Subject: [PATCH] update --- CodeVirtualizer.sln | 10 + CodeVirtualizer/Assembly.asm | 15 +- CodeVirtualizer/CodeBlocks.cpp | 5 + CodeVirtualizer/CodeVirtualizer.h | 13 + CodeVirtualizer/CodeVirtualizer.vcxproj | 25 +- .../CodeVirtualizer.vcxproj.filters | 122 ++---- CodeVirtualizer/DataLog.cpp | 1 - CodeVirtualizer/DataLog.h | 7 - CodeVirtualizer/Flags.cpp | 2 +- CodeVirtualizer/Flags.h | 2 - CodeVirtualizer/Jit.cpp | 358 ------------------ CodeVirtualizer/Jit.h | 39 -- CodeVirtualizer/Jit2.cpp | 50 --- CodeVirtualizer/Jit2.h | 28 -- CodeVirtualizer/Junk.cpp | 1 - CodeVirtualizer/Junk.h | 9 - CodeVirtualizer/Main.cpp | 139 +++++-- CodeVirtualizer/NativeCode.cpp | 141 ++++++- CodeVirtualizer/NativeCode.h | 8 +- CodeVirtualizer/Nop.cpp | 21 - CodeVirtualizer/Nop.h | 12 - CodeVirtualizer/ObfMisc.cpp | 1 + CodeVirtualizer/Obfuscator.cpp | 104 ++--- CodeVirtualizer/Obfuscator.h | 69 ++-- CodeVirtualizer/OpaqueBranching.cpp | 34 +- CodeVirtualizer/OpaqueBranching.h | 14 - CodeVirtualizer/PEFile.cpp | 40 ++ CodeVirtualizer/PEFile.h | 36 ++ CodeVirtualizer/Random.cpp | 18 + CodeVirtualizer/Random.h | 12 + CodeVirtualizer/RipAndInst.cpp | 38 -- CodeVirtualizer/RipAndInst.h | 16 - CodeVirtualizer/RipMovInst.cpp | 136 ++++++- CodeVirtualizer/RipMovInst.h | 15 - CodeVirtualizer/RipOrInst.cpp | 38 -- CodeVirtualizer/RipOrInst.h | 16 - CodeVirtualizer/RipXorInst.cpp | 38 -- CodeVirtualizer/RipXorInst.h | 16 - CodeVirtualizer/Virtualizer.cpp | 12 +- CodeVirtualizer/Virtualizer.h | 20 + CodeVirtualizer/Windas.h | 2 + README.md | 26 +- TestProject/Main.cpp | 7 + TestProject/TestProject.vcxproj | 150 ++++++++ TestProject/TestProject.vcxproj.filters | 6 + TestProject/TestProject.vcxproj.user | 4 + 46 files changed, 853 insertions(+), 1023 deletions(-) create mode 100644 CodeVirtualizer/CodeBlocks.cpp create mode 100644 CodeVirtualizer/CodeVirtualizer.h delete mode 100644 CodeVirtualizer/DataLog.cpp delete mode 100644 CodeVirtualizer/DataLog.h delete mode 100644 CodeVirtualizer/Jit.cpp delete mode 100644 CodeVirtualizer/Jit.h delete mode 100644 CodeVirtualizer/Jit2.cpp delete mode 100644 CodeVirtualizer/Jit2.h delete mode 100644 CodeVirtualizer/Junk.cpp delete mode 100644 CodeVirtualizer/Junk.h delete mode 100644 CodeVirtualizer/Nop.cpp delete mode 100644 CodeVirtualizer/Nop.h create mode 100644 CodeVirtualizer/ObfMisc.cpp create mode 100644 CodeVirtualizer/PEFile.cpp create mode 100644 CodeVirtualizer/PEFile.h create mode 100644 CodeVirtualizer/Random.cpp create mode 100644 CodeVirtualizer/Random.h delete mode 100644 CodeVirtualizer/RipAndInst.cpp delete mode 100644 CodeVirtualizer/RipAndInst.h delete mode 100644 CodeVirtualizer/RipMovInst.h delete mode 100644 CodeVirtualizer/RipOrInst.cpp delete mode 100644 CodeVirtualizer/RipOrInst.h delete mode 100644 CodeVirtualizer/RipXorInst.cpp delete mode 100644 CodeVirtualizer/RipXorInst.h create mode 100644 TestProject/Main.cpp create mode 100644 TestProject/TestProject.vcxproj create mode 100644 TestProject/TestProject.vcxproj.filters create mode 100644 TestProject/TestProject.vcxproj.user diff --git a/CodeVirtualizer.sln b/CodeVirtualizer.sln index 8075d6f..5a5b222 100644 --- a/CodeVirtualizer.sln +++ b/CodeVirtualizer.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30413.136 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodeVirtualizer", "CodeVirtualizer\CodeVirtualizer.vcxproj", "{BC5C8C97-FCB6-41A5-BFA0-56CB98491CA9}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestProject", "TestProject\TestProject.vcxproj", "{0949E81D-FAC5-471E-B533-CB0D9B53B346}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -21,6 +23,14 @@ Global {BC5C8C97-FCB6-41A5-BFA0-56CB98491CA9}.Release|x64.Build.0 = Release|x64 {BC5C8C97-FCB6-41A5-BFA0-56CB98491CA9}.Release|x86.ActiveCfg = Release|Win32 {BC5C8C97-FCB6-41A5-BFA0-56CB98491CA9}.Release|x86.Build.0 = Release|Win32 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Debug|x64.ActiveCfg = Debug|x64 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Debug|x64.Build.0 = Debug|x64 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Debug|x86.ActiveCfg = Debug|Win32 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Debug|x86.Build.0 = Debug|Win32 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Release|x64.ActiveCfg = Release|x64 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Release|x64.Build.0 = Release|x64 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Release|x86.ActiveCfg = Release|Win32 + {0949E81D-FAC5-471E-B533-CB0D9B53B346}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CodeVirtualizer/Assembly.asm b/CodeVirtualizer/Assembly.asm index 71656cf..79ac672 100644 --- a/CodeVirtualizer/Assembly.asm +++ b/CodeVirtualizer/Assembly.asm @@ -7,13 +7,16 @@ ; -ViSx0 proc +ViEnter PROC + MOV [RSP+8h],RCX + MOV [RSP+10h],RDX + MOV [RSP+18h],R8 + MOV [RSP+20h],R9 -ViSx0 endp + PUSH RAX + MOV RAX,0FFFFFFFFFFFFFFFFh + ;RAX NOW POINTER TO VMDATA STRUCT - -ViZx0 proc - -ViZx0 endp +ViEnter ENDP END \ No newline at end of file diff --git a/CodeVirtualizer/CodeBlocks.cpp b/CodeVirtualizer/CodeBlocks.cpp new file mode 100644 index 0000000..c7a723b --- /dev/null +++ b/CodeVirtualizer/CodeBlocks.cpp @@ -0,0 +1,5 @@ +#include "Obfuscator.h" + +//Requires either being in the process address space, or relocations + + diff --git a/CodeVirtualizer/CodeVirtualizer.h b/CodeVirtualizer/CodeVirtualizer.h new file mode 100644 index 0000000..6a170c6 --- /dev/null +++ b/CodeVirtualizer/CodeVirtualizer.h @@ -0,0 +1,13 @@ +#ifndef __CODE_VIRTUALIZER_H +#define __CODE_VIRTUALIZER_H + +#include +#include "Obfuscator.h" + +__declspec(dllexport) VOID CvInit(); + +__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize, PULONG OutSize, ULONG BranchCount, FLOAT MaxBranchSizePercentage); + +__declspec(dllexport) VOID CvDeleteCode(PVOID Code); + +#endif \ No newline at end of file diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj b/CodeVirtualizer/CodeVirtualizer.vcxproj index e79c987..ec742ec 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj @@ -157,20 +157,16 @@ - + - - - - + - + + - - @@ -178,19 +174,12 @@ - + - - - - - - - - - + + diff --git a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters index bf20acb..cf67991 100644 --- a/CodeVirtualizer/CodeVirtualizer.vcxproj.filters +++ b/CodeVirtualizer/CodeVirtualizer.vcxproj.filters @@ -17,47 +17,24 @@ Virtualizer - - Obfuscator\Jit\RipXorInst - - - Obfuscator\Jit\RipMovInst - Obfuscator - - Obfuscator\Nop - - - Obfuscator\Branching\Junk - - - Obfuscator\Branching\OpaqueBranching - - - Obfuscator\Jit - - - Obfuscator\Jit\RipAndInst - - - Obfuscator\Jit\RipOrInst - - - DataLog - - - Obfuscator\Flags - Virtualizer\VM Virtualizer\VM - - Obfuscator\Jit + + Random + + + + Code + + + File @@ -74,44 +51,32 @@ Virtualizer - - Obfuscator\Jit\RipXorInst - - - Obfuscator\Jit\RipMovInst - Obfuscator - - Obfuscator\Nop - - - Obfuscator\Branching\Junk - - - Obfuscator\Branching\OpaqueBranching + + Virtualizer\VM - - Obfuscator\Jit + + Random - - Obfuscator\Jit\RipAndInst + + Obfuscator - - Obfuscator\Jit\RipOrInst + + Obfuscator - - DataLog + + Obfuscator - Obfuscator\Flags + Code - - Virtualizer\VM + + File - - Obfuscator\Jit + + Obfuscator @@ -127,42 +92,15 @@ {cc5b78db-cdf7-4b83-9652-2722cbdec89e} - - {4b1bac75-b456-46a5-ad8b-453ffef9eef9} - - - {3e2b0e35-a45c-42c4-9a63-df17442bd6eb} - - - {53f6966d-c6e0-422a-9e72-e94a5bab8958} - - - {a15ab2ae-ba21-4f72-b110-ed3012cfefde} - - - {aa4e6b0f-dd50-41e7-bc46-5dc8a6b44a62} - - - {7040cc27-0179-47d5-9908-962d224b8c6e} - - - {51b7ca69-a7e9-4634-9eb2-d70f211fe2d2} - - - {a280c509-ba7e-4660-93fb-459ffe274a17} - - - {9b60f523-bf84-4740-9ee6-b8f34a317078} - - - {b4404de7-66a7-4dac-b993-58db5b5b2989} - - - {296c0b55-edbb-45ab-b946-ec83e5441678} - {28de0895-3bf5-45ef-8293-92032c466572} + + {5e10e90f-db2d-4a93-b2c4-70dbe085cdf9} + + + {86aae053-7113-4aef-b35f-ec023f771992} + diff --git a/CodeVirtualizer/DataLog.cpp b/CodeVirtualizer/DataLog.cpp deleted file mode 100644 index 6db9109..0000000 --- a/CodeVirtualizer/DataLog.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "DataLog.h" \ No newline at end of file diff --git a/CodeVirtualizer/DataLog.h b/CodeVirtualizer/DataLog.h deleted file mode 100644 index 5331146..0000000 --- a/CodeVirtualizer/DataLog.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __DATALOG_H -#define __DATALOG_H - - - - -#endif \ No newline at end of file diff --git a/CodeVirtualizer/Flags.cpp b/CodeVirtualizer/Flags.cpp index 5b54539..a5ff0bf 100644 --- a/CodeVirtualizer/Flags.cpp +++ b/CodeVirtualizer/Flags.cpp @@ -45,7 +45,7 @@ BOOL FlgAreFlagsClobbered(PNATIVE_CODE_LINK Inst, PNATIVE_CODE_LINK Stop) CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(InstFlags); CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(InstFlags); - Ledger.flat &= ~(Ledger.flat & (FlagsWritten->flat | FlagsUndefined->flat)); + Ledger.flat &= ~(FlagsWritten->flat | FlagsUndefined->flat); } return TRUE; } \ No newline at end of file diff --git a/CodeVirtualizer/Flags.h b/CodeVirtualizer/Flags.h index e81cb6e..f344fd3 100644 --- a/CodeVirtualizer/Flags.h +++ b/CodeVirtualizer/Flags.h @@ -1,8 +1,6 @@ #ifndef __FLAGS_H #define __FLAGS_H -#include "Windas.h" -#include "XedWrap.h" #include "NativeCode.h" PNATIVE_CODE_LINK FlgEmitPushfqInst(); diff --git a/CodeVirtualizer/Jit.cpp b/CodeVirtualizer/Jit.cpp deleted file mode 100644 index e6fc19f..0000000 --- a/CodeVirtualizer/Jit.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include "Jit.h" -#include "Flags.h" -#include "RipXorInst.h" -#include "RipAndInst.h" -#include "RipOrInst.h" -#include "RipMovInst.h" - - -BOOL JitMutateInstForXor(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PJIT_BITWISE_DATA JitData) -{ - ULONG FourByte = Link->RawDataSize / 4; - ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; - ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); - - while (FourByte) - { - *(PULONG)ToMutate ^= JitData->Data[2 - FourByte]; - ToMutate += 4; - FourByte--; - } - - if (TwoByte) - { - *(PUSHORT)ToMutate ^= (USHORT)JitData->Data[3]; - ToMutate += 2; - } - - if (OneByte) - *(PUCHAR)ToMutate ^= (UCHAR)JitData->Data[3]; - - return TRUE; -} - -VOID JitMutateInstForOr(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData) -{ - -} - -VOID JitMutateInstForAnd(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData) -{ - -} - -PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) -{ - 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); - RipDelta += Delta; - //Add the actual instruction - if (!JitEmitRipRelativeMovD(Block, RipDelta, DataOffset)) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - DataOffset += 4; - --Count; - } - - if (TwoByte) - { - INT32 RipDelta = (OneByte * BYTE_MOV_INST_LENGTH); - RipDelta += (FourByte * 4); - RipDelta += Delta; - if (!JitEmitRipRelativeMovW(Block, RipDelta, DataOffset)) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - DataOffset += 2; - } - - if (OneByte) - { - INT32 RipDelta = 0; - RipDelta += (FourByte * 4) + (TwoByte * 2); - RipDelta += Delta; - if (!JitEmitRipRelativeMovB(Block, RipDelta, DataOffset)) - { - NcDeleteBlock(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 JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) -{ - 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); - RipDelta += Delta; - ZeroValue = rand(); - if (!JitEmitRipRelativeMovD(Block, RipDelta, (PUCHAR)&ZeroValue)) - { - NcDeleteBlock(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); - RipDelta += Delta; - ZeroValue = rand(); - if (!JitEmitRipRelativeMovW(Block, RipDelta, (PUCHAR)&ZeroValue)) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - } - - if (OneByte) - { - INT32 RipDelta = Link->RawDataSize - (FourByte * 4) - (TwoByte * 2); - RipDelta += (FourByte * DWORD_MOV_INST_LENGTH); - RipDelta += (TwoByte * WORD_MOV_INST_LENGTH); - RipDelta += BYTE_MOV_INST_LENGTH; - RipDelta *= (-1); - RipDelta += Delta; - ZeroValue = rand(); - if (!JitEmitRipRelativeMovB(Block, RipDelta, (PUCHAR)&ZeroValue)) - { - NcDeleteBlock(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; -} - -INLINE BOOL JitiEmitWrapperD(ULONG OpType, PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - switch (OpType) - { - case JIT_BITWISE_XOR: return JitEmitRipRelativeXorD(Block, RipDelta, Value); - case JIT_BITWISE_AND: return JitEmitRipRelativeAndD(Block, RipDelta, Value); - case JIT_BITWISE_OR: return JitEmitRipRelativeOrD(Block, RipDelta, Value); - } -} -INLINE BOOL JitiEmitWrapperW(ULONG OpType, PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - switch (OpType) - { - case JIT_BITWISE_XOR: return JitEmitRipRelativeXorW(Block, RipDelta, Value); - case JIT_BITWISE_AND: return JitEmitRipRelativeAndW(Block, RipDelta, Value); - case JIT_BITWISE_OR: return JitEmitRipRelativeOrW(Block, RipDelta, Value); - } -} -INLINE BOOL JitiEmitWrapperB(ULONG OpType, PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - switch (OpType) - { - case JIT_BITWISE_XOR: return JitEmitRipRelativeXorB(Block, RipDelta, Value); - case JIT_BITWISE_AND: return JitEmitRipRelativeAndB(Block, RipDelta, Value); - case JIT_BITWISE_OR: return JitEmitRipRelativeOrB(Block, RipDelta, Value); - } -} - -PNATIVE_CODE_BLOCK JitEmitPreRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData, ULONG OpType, BOOL SaveFlags, INT32 Delta) -{ - 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; - if (!Block) - return NULL; - - if (SaveFlags) - { - PNATIVE_CODE_LINK PushF = FlgEmitPushfqInst(); - PushF->Flags |= CODE_FLAG_DO_NOT_DIVIDE; - NcAppendToBlock(Block, PushF); - } - - ULONG Count = FourByte; - while (Count) - { - INT32 RipDelta = (((Count - 1) * DWORD_RIP_INST_LENGTH) + (TwoByte * WORD_RIP_INST_LENGTH) + (OneByte * BYTE_RIP_INST_LENGTH)); - if (SaveFlags) - RipDelta += 1; - RipDelta += ((FourByte - Count) * 4); - RipDelta += Delta; - if (!JitiEmitWrapperD(OpType, Block, RipDelta, JitData->Data[FourByte - Count])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - --Count; - } - - if (TwoByte) - { - INT32 RipDelta = (OneByte * BYTE_RIP_INST_LENGTH); - if (SaveFlags) - RipDelta += 1; - RipDelta += (FourByte * 4); - RipDelta += Delta; - if (!JitiEmitWrapperW(OpType, Block, RipDelta, JitData->Data[3])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - } - - if (OneByte) - { - INT32 RipDelta = 0; - if (SaveFlags) - RipDelta += 1; - RipDelta += (FourByte * 4) + (TwoByte * 2); - RipDelta += Delta; - if (!JitiEmitWrapperB(OpType, Block, RipDelta, JitData->Data[4])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - } - - if (SaveFlags) - { - PNATIVE_CODE_LINK PopF = FlgEmitPopfqInst(); - PopF->Flags |= CODE_FLAG_DO_NOT_DIVIDE; - NcAppendToBlock(Block, PopF); - } - - return Block; -} - -PNATIVE_CODE_BLOCK JitEmitPostRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData, ULONG OpType, BOOL SaveFlags, INT32 Delta) -{ - 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; - if (!Block) - return NULL; - - if (SaveFlags) - { - PNATIVE_CODE_LINK PushF = FlgEmitPushfqInst(); - PushF->Flags |= CODE_FLAG_DO_NOT_DIVIDE; - NcAppendToBlock(Block, PushF); - } - - ULONG Count = FourByte; - while (Count) - { - INT32 RipDelta = Link->RawDataSize - ((FourByte - Count) * 4); - if (SaveFlags) - RipDelta += 1; - RipDelta += (FourByte - (Count - 1)) * DWORD_RIP_INST_LENGTH; - RipDelta *= (-1); - RipDelta += Delta; - if (!JitiEmitWrapperD(OpType, Block, RipDelta, JitData->Data[FourByte - Count])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - --Count; - } - - if (TwoByte) - { - INT32 RipDelta = Link->RawDataSize - (FourByte * 4); - if (SaveFlags) - RipDelta += 1; - RipDelta += (FourByte * DWORD_RIP_INST_LENGTH); - RipDelta += WORD_RIP_INST_LENGTH; - RipDelta *= (-1); - RipDelta += Delta; - if (!JitiEmitWrapperW(OpType, Block, RipDelta, JitData->Data[3])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - } - - if (OneByte) - { - INT32 RipDelta = Link->RawDataSize - (FourByte * 4) - (TwoByte * 2); - if (SaveFlags) - RipDelta += 1; - RipDelta += (FourByte * DWORD_RIP_INST_LENGTH); - RipDelta += WORD_RIP_INST_LENGTH; - RipDelta += BYTE_RIP_INST_LENGTH; - RipDelta *= (-1); - RipDelta += Delta; - if (!JitiEmitWrapperB(OpType, Block, RipDelta, JitData->Data[4])) - { - NcDeleteBlock(Block); - delete Block; - return NULL; - } - } - - if (SaveFlags) - { - PNATIVE_CODE_LINK PopF = FlgEmitPopfqInst(); - PopF->Flags |= CODE_FLAG_DO_NOT_DIVIDE; - NcAppendToBlock(Block, PopF); - } - - return Block; -} diff --git a/CodeVirtualizer/Jit.h b/CodeVirtualizer/Jit.h deleted file mode 100644 index 14f22a2..0000000 --- a/CodeVirtualizer/Jit.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __JIT_H -#define __JIT_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -#define DWORD_RIP_INST_LENGTH 10 -#define WORD_RIP_INST_LENGTH 9 -#define BYTE_RIP_INST_LENGTH 7 - -#define DWORD_MOV_INST_LENGTH 10 -#define WORD_MOV_INST_LENGTH 9 -#define BYTE_MOV_INST_LENGTH 7 - -#define JIT_BITWISE_XOR 0 -#define JIT_BITWISE_AND 1 -#define JIT_BITWISE_OR 2 - -typedef struct _JIT_BITWISE_DATA -{ - ULONG Data[5]; -}JIT_BITWISE_DATA, *PJIT_BITWISE_DATA; - -BOOL JitMutateInstForXor(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PJIT_BITWISE_DATA JitData); - -VOID JitMutateInstForOr(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData); - -VOID JitMutateInstForAnd(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData); - -PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0); - -PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0); - -PNATIVE_CODE_BLOCK JitEmitPreRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData, ULONG OpType, BOOL SaveFlags = TRUE, INT32 Delta = 0); - -PNATIVE_CODE_BLOCK JitEmitPostRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_DATA JitData, ULONG OpType, BOOL SaveFlags = TRUE, INT32 Delta = 0); - -#endif \ No newline at end of file diff --git a/CodeVirtualizer/Jit2.cpp b/CodeVirtualizer/Jit2.cpp deleted file mode 100644 index 0382550..0000000 --- a/CodeVirtualizer/Jit2.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "Jit2.h" - - -PNATIVE_CODE_LINK JitEmitDwordOp(); - -BOOL JitMutateInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PJIT_MUTATE_DATA JitData) -{ - ULONG FourByte = Link->RawDataSize / 4; - ULONG TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2; - ULONG OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2)); - - switch (JitData->Operation) - { - case JIT_XOR: - { - - break; - } - case JIT_OR: - { - - break; - } - case JIT_AND: - { - - break; - } - case JIT_MOV: - { - for (ULONG i = 0; i < Link->RawDataSize; i++) - ToMutate[i] = (rand() % 255); - break; - } - } - return TRUE; -} - - -PNATIVE_CODE_BLOCK JitEmitPreOp(PNATIVE_CODE_LINK Link, PJIT_MUTATE_DATA Data, UCHAR OpType, BOOL SaveFlags, INT32 Delta) -{ - return NULL; -} - -PNATIVE_CODE_BLOCK JitEmitPostOp(PNATIVE_CODE_LINK Link, PJIT_MUTATE_DATA Data, UCHAR OpType, BOOL SaveFlags, INT32 Delta) -{ - return NULL; -} - - diff --git a/CodeVirtualizer/Jit2.h b/CodeVirtualizer/Jit2.h deleted file mode 100644 index 802614b..0000000 --- a/CodeVirtualizer/Jit2.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __JIT2_H -#define __JIT2_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -#define JIT_XOR 0 -#define JIT_OR 1 -#define JIT_AND 2 -#define JIT_MOV 3 - -typedef struct _JIT_MUTATE_DATA -{ - ULONG Part1[3]; - USHORT Part2; - UCHAR Part3; - UCHAR Operation; -}JIT_MUTATE_DATA, *PJIT_MUTATE_DATA; - - -BOOL JitMutateInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PJIT_MUTATE_DATA JitData); - -PNATIVE_CODE_BLOCK JitEmitPreOp(PNATIVE_CODE_LINK Link, PJIT_MUTATE_DATA Data, UCHAR OpType, BOOL SaveFlags = FALSE, INT32 Delta = 0); - -PNATIVE_CODE_BLOCK JitEmitPostOp(PNATIVE_CODE_LINK Link, PJIT_MUTATE_DATA Data, UCHAR OpType, BOOL SaveFlags = FALSE, INT32 Delta = 0); - -#endif \ No newline at end of file diff --git a/CodeVirtualizer/Junk.cpp b/CodeVirtualizer/Junk.cpp deleted file mode 100644 index 150e189..0000000 --- a/CodeVirtualizer/Junk.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Junk.h" \ No newline at end of file diff --git a/CodeVirtualizer/Junk.h b/CodeVirtualizer/Junk.h deleted file mode 100644 index 679a052..0000000 --- a/CodeVirtualizer/Junk.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __JUNK_CODE_H -#define __JUNK_CODE_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - - -#endif \ No newline at end of file diff --git a/CodeVirtualizer/Main.cpp b/CodeVirtualizer/Main.cpp index a7c511c..452ba1c 100644 --- a/CodeVirtualizer/Main.cpp +++ b/CodeVirtualizer/Main.cpp @@ -7,6 +7,68 @@ #include "XedWrap.h" #include "NativeCode.h" #include "Obfuscator.h" +#include "Random.h" + +__declspec(dllexport) VOID CvInit() +{ + XedTablesInit(); + srand(time(NULL)); +} + +__declspec(dllexport) PVOID CvDriverFunctionObfuscate(PVOID Code, ULONG CodeSize, PULONG OutSize, ULONG BranchCount, FLOAT MaxBranchSizePercentage) +{ + //trip 0xCC alignment at end of code + while (((PUCHAR)Code)[CodeSize - 1] == 0xCC) + { + //printf("%X", ((PUCHAR)Code)[CodeSize - 1]); + --CodeSize; + } + + NATIVE_CODE_BLOCK CodeBlock; + if (!NcDisassemble(&CodeBlock, Code, CodeSize)) + { + return NULL; + } + //printf("Dissasembled.\n"); + + if (!NcPromoteAllRelJmpTo32(&CodeBlock)) + { + return NULL; + } + //printf("Jmps Fixed.\n"); + + /*OPBR_SETS Obf; + Obf.Flags = 0; + Obf.ParentBlock = &CodeBlock; + Obf.MinBranchLength = InstructionCount / 5 ; + Obf.BranchLengthChangeAmount = 4; + Obf.SpaceBetweenBranches = 10; + Obf.BranchLengthChangeAmount = 4; + Obf.BranchImmediately = FALSE; + Obf.RandomizeBranchChangeAmount = TRUE; + Obf.RandomizeSpaceBetweenBranches = TRUE; + Obf.BranchRemainingInstructions = TRUE; + Obf.BranchChance = 75; + ULONG BranchesMade = */ + + while (BranchCount) + { + ObfGenOpaqueBranch(&CodeBlock, RndGetRandomFloat(0.F, MaxBranchSizePercentage)); + BranchCount--; + } + + //if (MutSettings) + // ObfMutateInstructions(MutSettings, &CodeBlock); + + return NcAssembleEx(&CodeBlock, OutSize); +} + +__declspec(dllexport) VOID CvDeleteCode(PVOID Code) +{ + if (Code) + delete[] Code; +} + VOID PrintByteArr(PVOID Buff, ULONG BufSize) { @@ -125,8 +187,8 @@ UCHAR IsEvenCode[]{ int main() { - XedTablesInit(); - srand(time(NULL)); + CvInit(); + //ULONG Delta = (*((PULONG)((PUCHAR)TestShelcode + 1))) + 5; //printf("Delta: %X\n", Delta); PVOID ActualFunction = TestShelcode; // (PVOID)((ULONG64)TestShelcode + Delta); @@ -140,40 +202,54 @@ int main() PrintByteArr(MemeBlock, 110); system("pause"); - NATIVE_CODE_BLOCK RetNumBlock; - //NcDisassemble(&RetNumBlock, RetNumCode, sizeof(RetNumCode)); - NcDisassemble(&RetNumBlock, MemeBlock, 110); - if (!NcPromoteAllRelJmpTo32(&RetNumBlock)) - { - printf("failed to promote all jmps.\n"); - } - OPBR_SETS Obf; - Obf.Flags = 0; - Obf.ParentBlock = &RetNumBlock; - Obf.Divisor = 1.3F; - Obf.MaxDepth = 10; - Obf.MinBranchSize = 5; - Obf.ChanceForBranch = 100; - Obf.MinDepthForBranch = 0; - ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); - INSTMUT_SETS Obf2; - Obf2.MutateChance = 100; - ObfMutateInstructions(&Obf2, &RetNumBlock); - Obf.MinBranchSize = 100; - printf("Size = %u\n", NcCountInstructions(&RetNumBlock, TRUE)); - ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); - - printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock)); + + + //NATIVE_CODE_BLOCK RetNumBlock; + ////NcDisassemble(&RetNumBlock, RetNumCode, sizeof(RetNumCode)); + //NcDisassemble(&RetNumBlock, MemeBlock, 110); + //if (!NcPromoteAllRelJmpTo32(&RetNumBlock)) + //{ + // printf("failed to promote all jmps.\n"); + //} + //OPBR_SETS Obf; + //Obf.Flags = 0; + //Obf.ParentBlock = &RetNumBlock; + //Obf.Divisor = 1.7F; + //Obf.MaxDepth = 10; + //Obf.MinBranchSize = 5; + //Obf.ChanceForBranch = 80; + //Obf.MinDepthForBranch = 0; + //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); + //INSTMUT_SETS Obf2; + //Obf2.MutateChance = 100; + ////ObfMutateInstructions(&Obf2, &RetNumBlock); + //Obf.MinBranchSize = 40; + //printf("Size = %u\n", NcCountInstructions(&RetNumBlock, TRUE)); + //Obf.ChanceForBranch = 100; + //ObfGenerateOpaqueBranches(&Obf, &RetNumBlock); + + //printf("Assembling %u %u", NcCountInstructions(&RetNumBlock), NcCalcBlockSizeInBytes(&RetNumBlock)); + //ULONG AsmSize; + //PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); + //if (!Asm) + //{ + // printf("failed to assemble\n"); + // system("pause"); + // return 1; + //} + //PutToFile(Asm, AsmSize); + //system("pause"); + ULONG AsmSize; - PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); + PVOID Asm = CvDriverFunctionObfuscate(MemeBlock, 110, &AsmSize, 5, 0.5); if (!Asm) { - printf("failed to assemble\n"); + printf("failed to obfuscate ngiga\n"); system("pause"); - return 1; + return 2; } PutToFile(Asm, AsmSize); - system("pause"); + typedef ULONG64(*FnTestShelcode)(ULONG64, ULONG64, ULONG64, ULONG64); PVOID Exec = NULL; @@ -315,4 +391,5 @@ int main() } system("pause");*/ -} \ No newline at end of file +} + diff --git a/CodeVirtualizer/NativeCode.cpp b/CodeVirtualizer/NativeCode.cpp index 69c4d64..a166341 100644 --- a/CodeVirtualizer/NativeCode.cpp +++ b/CodeVirtualizer/NativeCode.cpp @@ -1,4 +1,5 @@ #include "NativeCode.h" +#include "Random.h" _NATIVE_CODE_LINK::_NATIVE_CODE_LINK() { @@ -223,6 +224,36 @@ BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL return TRUE; } +BOOL NcInsertBlockStartToEnd(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NewBlock) +{ + NewBlock->Start->Prev = Start->Prev; + NewBlock->End->Next = End->Next; + + if (Start->Prev) + Start->Prev->Next = NewBlock->Start; + if (End->Next) + End->Next->Prev = NewBlock->End; + + if (Start->Block->Start == Start) + Start->Block->Start = NewBlock->Start; + + if (Start->Block->End == End) + Start->Block->End = NewBlock->End; + + //Update Block for the current isntructions + for (PNATIVE_CODE_LINK T = NewBlock->Start; T && T != NewBlock->End->Next; T = T->Next) + T->Block = Start->Block; + + PNATIVE_CODE_LINK EndBlock = End->Next; + for (PNATIVE_CODE_LINK T = Start; T && T != EndBlock;) + { + PNATIVE_CODE_LINK RealNext = T->Next; + delete T; + T = RealNext; + } + return TRUE; +} + BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) { ULONG CurrentLabelId = 0; @@ -253,7 +284,6 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) INT32 BranchDisplacement = XedDecodedInstGetBranchDisplacement(&T->XedInstruction); PNATIVE_CODE_LINK JmpPos = NcValidateJmp(T, BranchDisplacement); - printf("Ended.\n"); if (!JmpPos) { printf("Failed to validate jump. Type: %s, Displacement: %d\n", XedCategoryEnumToString(Category), BranchDisplacement); @@ -278,7 +308,6 @@ BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block) PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Jmp, INT32 Delta) { - printf("Started.\n"); PNATIVE_CODE_LINK T; if (Delta > 0) { @@ -377,7 +406,6 @@ BOOL NcDeepCopyBlock(PNATIVE_CODE_BLOCK Block, PNATIVE_CODE_BLOCK BlockCopy) BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link) { - ULONG OldSize = Link->RawDataSize; if (XedDecodedInstGetBranchDisplacementWidth(&Link->XedInstruction) == 32) return TRUE; @@ -390,7 +418,6 @@ BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link) UINT ReturnedSize; XED_ICLASS_ENUM IClass = XedDecodedInstGetIClass(&Link->XedInstruction); - //Do the encoding XedInst1(&EncoderInstruction, MachineState, IClass, 32, XedRelBr(0, 32)); XedEncoderRequestZeroSetMode(&EncoderRequest, &MachineState); if (!XedConvertToEncoderRequest(&EncoderRequest, &EncoderInstruction)) @@ -400,13 +427,11 @@ BOOL NcPromoteRelJmpTo32(PNATIVE_CODE_LINK Link) if (XED_ERROR_NONE != Err) return FALSE; - //fixup T->RawData delete[] Link->RawData; Link->RawDataSize = ReturnedSize; Link->RawData = new UCHAR[ReturnedSize]; RtlCopyMemory(Link->RawData, EncodeBuffer, ReturnedSize); - //Decode instruction so its proper and all that XedDecodedInstZeroSetMode(&Link->XedInstruction, &MachineState); if (XED_ERROR_NONE != XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize)) return FALSE; @@ -463,6 +488,44 @@ BOOL NcGetDeltaToLabel(PNATIVE_CODE_LINK Link, PINT32 DeltaOut) return FALSE; } +BOOL NcGetDeltaToRandomLabel(PNATIVE_CODE_LINK Link, PINT32 DeltaOut) +{ + std::vector Deltas; + INT32 Delta = 0; + //First checking backwards because I feel like thats the direction most jmps are in + for (PNATIVE_CODE_LINK T = Link; T; T = T->Prev) + { + if (T->Flags & CODE_FLAG_IS_LABEL) + { + if (T->Label == Link->Label) + { + Deltas.push_back(Delta); + } + continue; + } + Delta -= T->RawDataSize; + } + + //Now check forwards + Delta = 0; + for (PNATIVE_CODE_LINK T = Link->Next; T; T = T->Next) + { + if (T->Flags & CODE_FLAG_IS_LABEL) + { + if (T->Label == Link->Label) + { + Deltas.push_back(Delta); + } + continue; + } + Delta += T->RawDataSize; + } + if (Deltas.size() == 0) + return FALSE; + *DeltaOut = Deltas[RndGetRandomInt(0, Deltas.size() - 1)]; + return TRUE; +} + BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) { for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) @@ -533,6 +596,23 @@ BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block) return TRUE; } +BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block) +{ + //Iterate through and check for rip relative instructions + /*for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) + { + if (T->Flags & CODE_FLAG_IS_LABEL) + continue; + + ULONG OperandCount = XedDecodedInstNumOperands(&T->XedInstruction); + if (OperandCount == 0) + continue; + + }*/ + + return FALSE; +} + BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize) { PUCHAR Buf = (PUCHAR)Buffer; @@ -572,7 +652,7 @@ PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize) *OutSize = NcCalcBlockSizeInBytes(Block); - PUCHAR Buffer = (PUCHAR)malloc(*OutSize); + PUCHAR Buffer = new UCHAR[*OutSize]; // (PUCHAR)malloc(*OutSize); if (!Buffer) return NULL; @@ -595,9 +675,52 @@ PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize) return Buffer; } -PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize, BOOL ChooseRandomDuplicateLabel) +//assumes all jmps already promoted to 32 bit branch displacement size +PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize) { - return NULL; + for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) + { + if (T->Flags & CODE_FLAG_IS_REL_JMP) + { + INT32 BranchDisp = 0; + if (!NcGetDeltaToRandomLabel(T, &BranchDisp)) + return FALSE; + + ULONG DispWidth = XedDecodedInstGetBranchDisplacementWidth(&T->XedInstruction); + switch (DispWidth) + { + case 1: *(PINT8)&T->RawData[T->RawDataSize - DispWidth] = (INT8)BranchDisp; break; + case 2: *(PINT16)&T->RawData[T->RawDataSize - DispWidth] = (INT16)BranchDisp; break; + case 4: *(PINT32)&T->RawData[T->RawDataSize - DispWidth] = (INT32)BranchDisp; break; + } + } + + T = T->Next; + } + + *OutSize = NcCalcBlockSizeInBytes(Block); + + PUCHAR Buffer = new UCHAR[*OutSize]; + if (!Buffer) + return NULL; + + PUCHAR BufferOffset = Buffer; + + for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next; T = T->Next) + { + if (T->Flags & CODE_FLAG_IS_LABEL) + continue; + RtlCopyMemory(BufferOffset, T->RawData, T->RawDataSize); + if (T->Flags & CODE_FLAG_HAS_ASM_OP) + { + for (STDPAIR CONST& Op : T->AsmOperations) + Op.first(T, BufferOffset, Op.second); + } + BufferOffset += T->RawDataSize; + + } + + return Buffer; } VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block) diff --git a/CodeVirtualizer/NativeCode.h b/CodeVirtualizer/NativeCode.h index 26616ab..bc2fc07 100644 --- a/CodeVirtualizer/NativeCode.h +++ b/CodeVirtualizer/NativeCode.h @@ -59,6 +59,8 @@ BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL F BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block, BOOL FixLabels = TRUE); +BOOL NcInsertBlockStartToEnd(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NewBlock); + BOOL NcCreateLabels(PNATIVE_CODE_BLOCK Block); PNATIVE_CODE_LINK NcValidateJmp(PNATIVE_CODE_LINK Link, INT32 Delta); @@ -75,13 +77,17 @@ BOOL NcPromoteAllRelJmpTo32(PNATIVE_CODE_BLOCK Block); BOOL NcGetDeltaToLabel(PNATIVE_CODE_LINK Link, PINT32 DeltaOut); +BOOL NcGetDeltaToRandomLabel(PNATIVE_CODE_LINK Link, PINT32 DeltaOut); + BOOL NcFixRelJmps(PNATIVE_CODE_BLOCK Block); +BOOL NcHasIllegalInstructions(PNATIVE_CODE_BLOCK Block); + BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize); PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize); -PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize, BOOL ChooseRandomDuplicateLabel); +PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize); VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block); diff --git a/CodeVirtualizer/Nop.cpp b/CodeVirtualizer/Nop.cpp deleted file mode 100644 index 993e03c..0000000 --- a/CodeVirtualizer/Nop.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "Nop.h" - -PNATIVE_CODE_LINK NcEmitNop() -{ - UCHAR RawData[] = { 0x90 }; - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1, TRUE); - //XedDecode(&Link->XedInstruction, Link->RawData, 1); - return Link; -} - -BOOL NcEmitNopGroup(ULONG Count, PNATIVE_CODE_BLOCK Block) -{ - if (Count < 1) - return FALSE; - while (Count) - { - NcAppendToBlock(Block, NcEmitNop()); - Count--; - } - return TRUE; -} \ No newline at end of file diff --git a/CodeVirtualizer/Nop.h b/CodeVirtualizer/Nop.h deleted file mode 100644 index e328ce5..0000000 --- a/CodeVirtualizer/Nop.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __NOP_H -#define __NOP_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -PNATIVE_CODE_LINK NcEmitNop(); - -BOOL NcEmitNopGroup(ULONG Count, PNATIVE_CODE_BLOCK Block); - -#endif \ No newline at end of file diff --git a/CodeVirtualizer/ObfMisc.cpp b/CodeVirtualizer/ObfMisc.cpp new file mode 100644 index 0000000..bd7f157 --- /dev/null +++ b/CodeVirtualizer/ObfMisc.cpp @@ -0,0 +1 @@ +#include "Obfuscator.h" \ No newline at end of file diff --git a/CodeVirtualizer/Obfuscator.cpp b/CodeVirtualizer/Obfuscator.cpp index a734606..d51150e 100644 --- a/CodeVirtualizer/Obfuscator.cpp +++ b/CodeVirtualizer/Obfuscator.cpp @@ -4,82 +4,51 @@ BOOL ObfiRandomizeInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PVOID Context) { for (ULONG i = 0; i < Link->RawDataSize; i++) - ToMutate[i] = (rand() % 255); + ToMutate[i] = RndGetRandomInt(0, 255); return TRUE; } -VOID ObfGenerateOpaqueBranches(POPBR_SETS Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth) +VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage) { - if (Depth > Obf->MaxDepth) - return; - - ULONG InstructionCount = NcCountInstructions(Block, TRUE); - if (InstructionCount >= Obf->MinBranchSize) + ULONG BlockSize = NcCountInstructions(Block, TRUE); + ULONG BranchSize = (FLOAT)BlockSize * BranchSizePercentage; + ULONG BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize); + PNATIVE_CODE_LINK BranchStart = BranchStartPos ? NULL : Block->Start; + for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) { - ULONG TargetCount = (ULONG)((FLOAT)InstructionCount / Obf->Divisor); - ULONG CurrentCount = 0; - PNATIVE_CODE_LINK NewBlockStart = Block->Start; - for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) + if (T->Flags & CODE_FLAG_IS_LABEL || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE && !(T->Flags & CODE_FLAG_GROUP_END))) { - if (T->Flags & CODE_FLAG_IS_LABEL || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE && !(T->Flags & CODE_FLAG_GROUP_END))) - { - T = T->Next; - continue; - } - - if (++CurrentCount >= TargetCount) - { - if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize) - { - NATIVE_CODE_BLOCK NotTaken, Taken; - ObfCreateOpaqueBranches(NewBlockStart, T, &NotTaken, &Taken); - ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1); - ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1); - ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock)); - ObfInsertOpaqueBranchBlock(NewBlockStart, T, &NotTaken); - T = NotTaken.End; - } - else - { - NATIVE_CODE_BLOCK TempBlock; - if (NcDeepCopyPartialBlock(NewBlockStart, T, &TempBlock)) - { - ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1); - ObfInsertOpaqueBranchBlock(NewBlockStart, T, &TempBlock); - } - T = TempBlock.End; - } - NewBlockStart = T->Next; - CurrentCount = 0; - } T = T->Next; + continue; + } + + if (BranchStartPos) + { + --BranchStartPos; + if (BranchStartPos == 0) + BranchStart = T; + T = T->Next; + continue; } - if (NewBlockStart) //Deal with remaining instructions in the block + + if (BranchSize) { - if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize) - { - NATIVE_CODE_BLOCK NotTaken, Taken; - ObfCreateOpaqueBranches(NewBlockStart, Block->End, &NotTaken, &Taken); - ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1); - ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1); - ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock)); - ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &NotTaken); - } - else - { - NATIVE_CODE_BLOCK TempBlock; - if (NcDeepCopyPartialBlock(NewBlockStart, Block->End, &TempBlock)) - { - ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1); - ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &TempBlock); - } - } + --BranchSize; + T = T->Next; + continue; } + + NATIVE_CODE_BLOCK NotTaken, Taken; + ObfCreateOpaqueBranches(BranchStart, T, &NotTaken, &Taken); + ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Block), NcGenUnusedLabelId(Block)); + NcInsertBlockStartToEnd(BranchStart, T, &NotTaken); + return; } } -VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block) +ULONG ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, ULONG MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst) { + ULONG MutatedInstructions = 0; for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) { if ((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) || (T->Flags & CODE_FLAG_IS_REL_JMP)) @@ -90,8 +59,10 @@ VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block) PNATIVE_CODE_LINK RealNext = T->Next; - if ((rand() % 100) <= Obf->MutateChance) + if (RndGetRandomInt(0, 100) <= MutateChance || MutateFirst) { + MutateFirst = FALSE; + PNATIVE_CODE_BLOCK PreOp = JitEmitPreRipMov(T); PNATIVE_CODE_BLOCK PostOp = JitEmitPostRipMov(T); @@ -116,8 +87,15 @@ VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block) delete PreOp; delete PostOp; + + MutatedInstructions++; + + if (MutateOnlyFirst) + return MutatedInstructions; + } T = RealNext; } + return MutatedInstructions; } \ No newline at end of file diff --git a/CodeVirtualizer/Obfuscator.h b/CodeVirtualizer/Obfuscator.h index 84e6212..5fa0bfd 100644 --- a/CodeVirtualizer/Obfuscator.h +++ b/CodeVirtualizer/Obfuscator.h @@ -5,33 +5,46 @@ #include "Windas.h" #include "XedWrap.h" #include "NativeCode.h" -#include "Jit.h" -#include "OpaqueBranching.h" - -#define OBF_ATTRIBUTE_JIT (1<<0) -#define OBF_ATTRIBUTE_OPAQUE_BRANCHES (1<<1) -#define OBF_ATTRIBUTE_RANDOMIZE_DIVISOR (1<<2) - -typedef struct _OPBR_SETS -{ - ULONG MaxDepth; - ULONG MinBranchSize; - FLOAT Divisor; - ULONG Flags; - ULONG MinDepthForBranch; - ULONG ChanceForBranch; - PNATIVE_CODE_BLOCK ParentBlock; -}OPBR_SETS, *POPBR_SETS; - -typedef struct _INSTMUT_SETS -{ - ULONG MutateStart; - ULONG MutateChance; -}INSTMUT_SETS, *PINSTMUT_SETS; - -//Recursive obfuscation routine using opaque branches and jit -VOID ObfGenerateOpaqueBranches(POPBR_SETS Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth = 0); - -VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block); +#include "Random.h" + +#define DWORD_MOV_INST_LENGTH 10 +#define WORD_MOV_INST_LENGTH 9 +#define BYTE_MOV_INST_LENGTH 7 + + +//Jit +BOOL JitEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); + +BOOL JitEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); + +BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); + +PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0); + +PNATIVE_CODE_BLOCK JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta = 0); + + + + +VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage); + +ULONG ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, ULONG MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst); + + + + +XED_ICLASS_ENUM ObfGetRandomJccClass(); + +PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementSize = 32); + +PNATIVE_CODE_LINK ObfGenJmpToLabel(ULONG LabelId, ULONG DisplacementSize = 32); + +BOOL ObfCreateOpaqueBranches(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken); + +//Combines the two branches into one block that can easily be patched into the code +//Resulting block is put into NotTaken +BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, ULONG JccLabel, ULONG JmpLabel); + + #endif \ No newline at end of file diff --git a/CodeVirtualizer/OpaqueBranching.cpp b/CodeVirtualizer/OpaqueBranching.cpp index deb4b74..8d20dec 100644 --- a/CodeVirtualizer/OpaqueBranching.cpp +++ b/CodeVirtualizer/OpaqueBranching.cpp @@ -1,8 +1,8 @@ -#include "OpaqueBranching.h" +#include "Obfuscator.h" XED_ICLASS_ENUM ObfGetRandomJccClass() { - switch (rand() % 14) + switch (RndGetRandomInt(0, 14)) { case 0: return XED_ICLASS_JL; case 1: return XED_ICLASS_JLE; @@ -112,33 +112,3 @@ BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Ta return TRUE; } -BOOL ObfInsertOpaqueBranchBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK OpaqueBranchBlock) -{ - OpaqueBranchBlock->Start->Prev = Start->Prev; - OpaqueBranchBlock->End->Next = End->Next; - - if (Start->Prev) - Start->Prev->Next = OpaqueBranchBlock->Start; - if (End->Next) - End->Next->Prev = OpaqueBranchBlock->End; - - if (Start->Block->Start == Start) - Start->Block->Start = OpaqueBranchBlock->Start; - - if (Start->Block->End == End) - Start->Block->End = OpaqueBranchBlock->End; - - //Update group for the current isntructions - for (PNATIVE_CODE_LINK T = OpaqueBranchBlock->Start; T && T != OpaqueBranchBlock->End->Next; T = T->Next) - T->Block = Start->Block; - - PNATIVE_CODE_LINK EndBlock = End->Next; - for (PNATIVE_CODE_LINK T = Start; T && T != EndBlock;) - { - PNATIVE_CODE_LINK RealNext = T->Next; - delete T; - T = RealNext; - } - return TRUE; -} - diff --git a/CodeVirtualizer/OpaqueBranching.h b/CodeVirtualizer/OpaqueBranching.h index 451f7f5..4e4d498 100644 --- a/CodeVirtualizer/OpaqueBranching.h +++ b/CodeVirtualizer/OpaqueBranching.h @@ -5,19 +5,5 @@ #include "XedWrap.h" #include "NativeCode.h" -XED_ICLASS_ENUM ObfGetRandomJccClass(); - -PNATIVE_CODE_LINK ObfGenRandomJcc(ULONG LabelId, ULONG DisplacementSize = 32); - -PNATIVE_CODE_LINK ObfGenJmpToLabel(ULONG LabelId, ULONG DisplacementSize = 32); - -BOOL ObfCreateOpaqueBranches(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken); - -//Combines the two branches into one block that can easily be patched into the code -//Resulting block is put into NotTaken -BOOL ObfCombineOpaqueBranches(PNATIVE_CODE_BLOCK NotTaken, PNATIVE_CODE_BLOCK Taken, ULONG JccLabel, ULONG JmpLabel); - -BOOL ObfInsertOpaqueBranchBlock(PNATIVE_CODE_LINK Start, PNATIVE_CODE_LINK End, PNATIVE_CODE_BLOCK OpaqueBranchBlock); - #endif \ No newline at end of file diff --git a/CodeVirtualizer/PEFile.cpp b/CodeVirtualizer/PEFile.cpp new file mode 100644 index 0000000..699d09d --- /dev/null +++ b/CodeVirtualizer/PEFile.cpp @@ -0,0 +1,40 @@ +#include "PEFile.h" + + +VOID FiLoadFile(PPE_FILE File, PVOID RawData, ULONG RawDataSize) +{ + File->RawData = RawData; + File->RawDataSize = RawDataSize; + File->Flags = NULL; + + File->DosHeader = (PIMAGE_DOS_HEADER)File->RawData; + if (File->DosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return; + + File->NtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)File + File->DosHeader->e_lfanew); + if (File->NtHeaders->Signature != IMAGE_NT_SIGNATURE) + return; + + File->FileHeader = &(File->NtHeaders->FileHeader); + File->SectionHeaders = (PIMAGE_SECTION_HEADER)((PUCHAR)File->FileHeader + sizeof(IMAGE_FILE_HEADER) + File->FileHeader->SizeOfOptionalHeader); + + File->Flags |= PEFI_IS_LOADED; +} +VOID FiWriteFile(PPE_FILE File, STDSTRING CONST& Path) +{ + //xD +} +VOID FILoadSymbols(PPE_FILE File, PVOID PdbFileData) +{ + +} +VOID FiDestroy(PPE_FILE File) +{ + +} + +BOOL FiGood(PPE_FILE File) +{ + return (File->Flags & PEFI_IS_LOADED); +} + diff --git a/CodeVirtualizer/PEFile.h b/CodeVirtualizer/PEFile.h new file mode 100644 index 0000000..a991ebf --- /dev/null +++ b/CodeVirtualizer/PEFile.h @@ -0,0 +1,36 @@ +#ifndef __PEFILE_H +#define __PEFILE_H + +#include "Windas.h" + +#define PEFI_IS_LOADED (1<<0) +#define PEFI_SYMBOLS_LOADED (1<<1) + + +typedef struct _PEFI_SECTION +{ + PVOID RawData; + ULONG RawDataSize; +}PEFI_SECTION, *PPEFI_SECTION; + +typedef struct _PE_FILE +{ + PVOID RawData; + ULONG RawDataSize; + ULONG Flags; + PIMAGE_DOS_HEADER DosHeader; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_FILE_HEADER FileHeader; + PIMAGE_SECTION_HEADER SectionHeaders; + STDVECTOR SymbolData; +}PE_FILE, *PPE_FILE; + +VOID FiLoadFile(PPE_FILE File, PVOID RawData, ULONG RawDataSize); +VOID FiWriteFile(PPE_FILE File, STDSTRING CONST& Path); +VOID FILoadSymbols(PPE_FILE File, PVOID PdbFileData); +VOID FiDestroy(PPE_FILE File); + +BOOL FiGood(PPE_FILE File); + + +#endif \ No newline at end of file diff --git a/CodeVirtualizer/Random.cpp b/CodeVirtualizer/Random.cpp new file mode 100644 index 0000000..045572d --- /dev/null +++ b/CodeVirtualizer/Random.cpp @@ -0,0 +1,18 @@ +#include "Random.h" + + +INT RndGetRandomInt(INT min, INT max) +{ + std::random_device rd; + std::default_random_engine generator(rd()); + std::uniform_int_distribution distribution(min, max); + return distribution(generator); +} + +FLOAT RndGetRandomFloat(FLOAT min, FLOAT max) +{ + std::random_device Random; + std::mt19937 RandomGenerator(Random()); + std::uniform_real RandomDistribute(min, max); + return RandomDistribute(RandomGenerator); +} \ No newline at end of file diff --git a/CodeVirtualizer/Random.h b/CodeVirtualizer/Random.h new file mode 100644 index 0000000..7a387f9 --- /dev/null +++ b/CodeVirtualizer/Random.h @@ -0,0 +1,12 @@ +#ifndef __RANDOM_H +#define __RANDOM_H + + +#include "Windas.h" + +INT RndGetRandomInt(INT min, INT max); + +FLOAT RndGetRandomFloat(FLOAT min, FLOAT max); + + +#endif \ No newline at end of file diff --git a/CodeVirtualizer/RipAndInst.cpp b/CodeVirtualizer/RipAndInst.cpp deleted file mode 100644 index f546fdf..0000000 --- a/CodeVirtualizer/RipAndInst.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "RipAndInst.h" - -BOOL JitEmitRipRelativeAndD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x81, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PULONG)&Link->RawData[6] = Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeAndW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x66, 0x83, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[3] = RipDelta; - *(PUSHORT)&Link->RawData[7] = (USHORT)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeAndB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PUCHAR)&Link->RawData[6] = (UCHAR)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - diff --git a/CodeVirtualizer/RipAndInst.h b/CodeVirtualizer/RipAndInst.h deleted file mode 100644 index af6c515..0000000 --- a/CodeVirtualizer/RipAndInst.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __RIP_AND_INST_H -#define __RIP_AND_INST_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -BOOL JitEmitRipRelativeAndD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeAndW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeAndB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - - - -#endif diff --git a/CodeVirtualizer/RipMovInst.cpp b/CodeVirtualizer/RipMovInst.cpp index 09c8732..084e08b 100644 --- a/CodeVirtualizer/RipMovInst.cpp +++ b/CodeVirtualizer/RipMovInst.cpp @@ -1,4 +1,4 @@ -#include "RipMovInst.h" +#include "Obfuscator.h" BOOL JitEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data) { @@ -35,3 +35,137 @@ BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Dat NcAppendToBlock(Block, Link); return TRUE; } + +PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) +{ + 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); + RipDelta += Delta; + //Add the actual instruction + if (!JitEmitRipRelativeMovD(Block, RipDelta, DataOffset)) + { + NcDeleteBlock(Block); + delete Block; + return NULL; + } + DataOffset += 4; + --Count; + } + + if (TwoByte) + { + INT32 RipDelta = (OneByte * BYTE_MOV_INST_LENGTH); + RipDelta += (FourByte * 4); + RipDelta += Delta; + if (!JitEmitRipRelativeMovW(Block, RipDelta, DataOffset)) + { + NcDeleteBlock(Block); + delete Block; + return NULL; + } + DataOffset += 2; + } + + if (OneByte) + { + INT32 RipDelta = 0; + RipDelta += (FourByte * 4) + (TwoByte * 2); + RipDelta += Delta; + if (!JitEmitRipRelativeMovB(Block, RipDelta, DataOffset)) + { + NcDeleteBlock(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 JitEmitPostRipMov(PNATIVE_CODE_LINK Link, INT32 Delta) +{ + 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); + RipDelta += Delta; + ZeroValue = rand(); + if (!JitEmitRipRelativeMovD(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDeleteBlock(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); + RipDelta += Delta; + ZeroValue = rand(); + if (!JitEmitRipRelativeMovW(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDeleteBlock(Block); + delete Block; + return NULL; + } + } + + if (OneByte) + { + INT32 RipDelta = Link->RawDataSize - (FourByte * 4) - (TwoByte * 2); + RipDelta += (FourByte * DWORD_MOV_INST_LENGTH); + RipDelta += (TwoByte * WORD_MOV_INST_LENGTH); + RipDelta += BYTE_MOV_INST_LENGTH; + RipDelta *= (-1); + RipDelta += Delta; + ZeroValue = rand(); + if (!JitEmitRipRelativeMovB(Block, RipDelta, (PUCHAR)&ZeroValue)) + { + NcDeleteBlock(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; +} diff --git a/CodeVirtualizer/RipMovInst.h b/CodeVirtualizer/RipMovInst.h deleted file mode 100644 index 7109445..0000000 --- a/CodeVirtualizer/RipMovInst.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __RIP_MOV_INST_H -#define __RIP_MOV_INST_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -BOOL JitEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); - -BOOL JitEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); - -BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data); - - -#endif diff --git a/CodeVirtualizer/RipOrInst.cpp b/CodeVirtualizer/RipOrInst.cpp deleted file mode 100644 index f1c43b6..0000000 --- a/CodeVirtualizer/RipOrInst.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "RipOrInst.h" - -BOOL JitEmitRipRelativeOrD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x81, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PULONG)&Link->RawData[6] = Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeOrW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x66, 0x83, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[3] = RipDelta; - *(PUSHORT)&Link->RawData[7] = (USHORT)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeOrB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x80, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PUCHAR)&Link->RawData[6] = (UCHAR)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - diff --git a/CodeVirtualizer/RipOrInst.h b/CodeVirtualizer/RipOrInst.h deleted file mode 100644 index d3decd0..0000000 --- a/CodeVirtualizer/RipOrInst.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __RIP_OR_INST_H -#define __RIP_OR_INST_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -BOOL JitEmitRipRelativeOrD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeOrW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeOrB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - - - -#endif diff --git a/CodeVirtualizer/RipXorInst.cpp b/CodeVirtualizer/RipXorInst.cpp deleted file mode 100644 index fbd6536..0000000 --- a/CodeVirtualizer/RipXorInst.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "RipXorInst.h" - -BOOL JitEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PULONG)&Link->RawData[6] = Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x66, 0x81, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[3] = RipDelta; - *(PUSHORT)&Link->RawData[7] = (USHORT)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - -BOOL JitEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value) -{ - UCHAR RawData[] = { 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, sizeof(RawData)); - *(PINT32)&Link->RawData[2] = RipDelta; - *(PUCHAR)&Link->RawData[6] = (UCHAR)Value; - XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize); - NcAppendToBlock(Block, Link); - return TRUE; -} - diff --git a/CodeVirtualizer/RipXorInst.h b/CodeVirtualizer/RipXorInst.h deleted file mode 100644 index 6e0cb91..0000000 --- a/CodeVirtualizer/RipXorInst.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __RIP_XOR_INST_H -#define __RIP_XOR_INST_H - -#include "Windas.h" -#include "XedWrap.h" -#include "NativeCode.h" - -BOOL JitEmitRipRelativeXorD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeXorW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - -BOOL JitEmitRipRelativeXorB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, ULONG Value); - - - -#endif diff --git a/CodeVirtualizer/Virtualizer.cpp b/CodeVirtualizer/Virtualizer.cpp index 8b4f5eb..6f955bd 100644 --- a/CodeVirtualizer/Virtualizer.cpp +++ b/CodeVirtualizer/Virtualizer.cpp @@ -12,4 +12,14 @@ BOOL ViValidateNativeCodeBlock(PNATIVE_CODE_BLOCK Block) return FALSE; } return TRUE; -} \ No newline at end of file +} + +BOOL VmEmitEnter(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block) +{ + +} + +BOOL VmEmitExit(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block) +{ + +} diff --git a/CodeVirtualizer/Virtualizer.h b/CodeVirtualizer/Virtualizer.h index d5f03c8..0f9b310 100644 --- a/CodeVirtualizer/Virtualizer.h +++ b/CodeVirtualizer/Virtualizer.h @@ -7,12 +7,32 @@ /* +* Structure: * +* Instructions: +* - Two byte opcode +* - * * +* LOC register(Frame pointer): +* - A register for which all local variables are addressed from +* - Specific instructions for quick access of stuff around this ptr +* - Example Frame: +* - [Previous function variables +* - [Return Address +* - [Previous Functions LOC +* - LOC->[Empty Stack Space +* +* +* -VmEnter will essentially "call into" the vm and will be created using a function to rearrange and push arguments based on the arguments passed to said function. */ + + BOOL ViCanHandleInst(PNATIVE_CODE_LINK Link); BOOL ViValidateNativeCodeBlock(PNATIVE_CODE_BLOCK Block); +BOOL VmEmitEnter(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block); +BOOL VmEmitExit(ULONG ArgumentCount, PNATIVE_CODE_BLOCK Block); + #endif \ No newline at end of file diff --git a/CodeVirtualizer/Windas.h b/CodeVirtualizer/Windas.h index ee185c9..eb9b183 100644 --- a/CodeVirtualizer/Windas.h +++ b/CodeVirtualizer/Windas.h @@ -7,6 +7,7 @@ #include #include #include +#include #define INLINE inline #define STDSTRING std::string @@ -22,6 +23,7 @@ * Jit -> Jit related function * Xed -> Xed macro wrapper * Vm -> Virtual Machine function +* Fi -> File stuff used to dissasemble PE files */ diff --git a/README.md b/README.md index 087b2b5..fb9af5f 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,8 @@ virtualize x86_64 -# Ideas: -- Handle inputted buffers only for now, no nonsense with files yet. -- Output buffers containing the vm(with required instructions), vm handler table(offsets to insturctions in vm buffer), and one containing the x86 code(with the vm code right along side it(this means fixing up all relative jumps and rip relative instructions.. ugh >:| )) -- I want the vm code to be embedded right alongside the x86, so you see like - -``` -x86 instruction -x86 instruction -vmenter(which jumps to some place based on the handler table) -vm opcode (vm opcode and bytecode which looks like jibberish) -vm opcode -vm opcode -vm exits back to here ---. -x86 instruction <----` -x86 instruction -``` - -# Todo: -- Setup some il rope like structure to contain all x86 instructions -- Functions to find groups of x86 instructions that i can handle/convert into my vm.(the larger the group the better) -- Learn file structure, what are reallocations and how do imports work?!? +# Obfuscator +- Opaque Branching +- Just in time instruction Mutation with RIP relative bitwise operating and moving +- Junk: Both garbage with jmps to jump around it, and code that does something, then undos what it did. +- diff --git a/TestProject/Main.cpp b/TestProject/Main.cpp new file mode 100644 index 0000000..05f3559 --- /dev/null +++ b/TestProject/Main.cpp @@ -0,0 +1,7 @@ +#include + + +int main() +{ + +} \ No newline at end of file diff --git a/TestProject/TestProject.vcxproj b/TestProject/TestProject.vcxproj new file mode 100644 index 0000000..9592e69 --- /dev/null +++ b/TestProject/TestProject.vcxproj @@ -0,0 +1,150 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {0949e81d-fac5-471e-b533-cb0d9b53b346} + TestProject + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + false + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + false + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + Disabled + false + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/TestProject/TestProject.vcxproj.filters b/TestProject/TestProject.vcxproj.filters new file mode 100644 index 0000000..d3e9077 --- /dev/null +++ b/TestProject/TestProject.vcxproj.filters @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TestProject/TestProject.vcxproj.user b/TestProject/TestProject.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/TestProject/TestProject.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file