xor instructions before and after they execute
main
James 3 years ago
parent dcea33c072
commit a34538d700

@ -151,7 +151,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="NativeCode.cpp" /> <ClCompile Include="NativeCode.cpp" />
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
<ClCompile Include="CryptedCode.cpp" /> <ClCompile Include="XorInstructions.cpp" />
<ClCompile Include="Virtualizer.cpp" /> <ClCompile Include="Virtualizer.cpp" />
<ClCompile Include="VirtualMachine.cpp" /> <ClCompile Include="VirtualMachine.cpp" />
<ClCompile Include="VmCode.cpp" /> <ClCompile Include="VmCode.cpp" />
@ -160,7 +160,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="Code.h" /> <ClInclude Include="Code.h" />
<ClInclude Include="NativeCode.h" /> <ClInclude Include="NativeCode.h" />
<ClInclude Include="CryptedCode.h" /> <ClInclude Include="XorInstructions.h" />
<ClInclude Include="Virtualizer.h" /> <ClInclude Include="Virtualizer.h" />
<ClInclude Include="VirtualMachine.h" /> <ClInclude Include="VirtualMachine.h" />
<ClInclude Include="VmCode.h" /> <ClInclude Include="VmCode.h" />

@ -20,8 +20,8 @@
<ClInclude Include="VirtualMachine.h"> <ClInclude Include="VirtualMachine.h">
<Filter>VirtualMachine</Filter> <Filter>VirtualMachine</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="CryptedCode.h"> <ClInclude Include="XorInstructions.h">
<Filter>Obfuscator</Filter> <Filter>Obfuscator\XorInstructions</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -41,8 +41,8 @@
<ClCompile Include="VirtualMachine.cpp"> <ClCompile Include="VirtualMachine.cpp">
<Filter>VirtualMachine</Filter> <Filter>VirtualMachine</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CryptedCode.cpp"> <ClCompile Include="XorInstructions.cpp">
<Filter>Obfuscator</Filter> <Filter>Obfuscator\XorInstructions</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -64,5 +64,8 @@
<Filter Include="Obfuscator"> <Filter Include="Obfuscator">
<UniqueIdentifier>{cc5b78db-cdf7-4b83-9652-2722cbdec89e}</UniqueIdentifier> <UniqueIdentifier>{cc5b78db-cdf7-4b83-9652-2722cbdec89e}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="Obfuscator\XorInstructions">
<UniqueIdentifier>{51b7ca69-a7e9-4634-9eb2-d70f211fe2d2}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -1,3 +0,0 @@
#include "CryptedCode.h"
PNATIVE_CODE_BLOCK RxEmitXorForInstruction(PNATIVE_CODE_LINK Link);

@ -1,11 +0,0 @@
#ifndef __CRYPTED_CODE_H
#define __CRYPTED_CODE_H
#include "Windas.h"
#include "XedWrap.h"
#include "NativeCode.h"
PNATIVE_CODE_BLOCK RxEmitXorForInstruction(PNATIVE_CODE_LINK Link);
#endif

@ -4,6 +4,7 @@
#include "NativeCode.h" #include "NativeCode.h"
#include "XorInstructions.h"
UCHAR TestBuffer[]{ UCHAR TestBuffer[]{
0x48, 0x33, 0xC0, 0x48, 0x33, 0xC0,
@ -32,6 +33,18 @@ int main()
NcFromBuffer(&Block, TestBuffer, TestBufferSize); NcFromBuffer(&Block, TestBuffer, TestBufferSize);
NcDebugPrint(&Block); NcDebugPrint(&Block);
NATIVE_CODE_LINK T;
T.RawDataSize = 7;
XOR_INST_DATA Data;
RtlSecureZeroMemory(&Data, sizeof(XOR_INST_DATA));
PNATIVE_CODE_BLOCK NewBlock = ObfEmitPostXorForInst(&T, &Data, TRUE);
if (NewBlock)
{
printf("\n");
NcDebugPrint(NewBlock);
printf("\n");
NcPrintBlockCode(NewBlock);
}
//PNATIVE_CODE_LINK temp = new NATIVE_CODE_LINK("Hello"); //PNATIVE_CODE_LINK temp = new NATIVE_CODE_LINK("Hello");
system("pause"); system("pause");

@ -20,6 +20,18 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B)
Flags = CODE_FLAG_IS_LABEL; Flags = CODE_FLAG_IS_LABEL;
} }
_NATIVE_CODE_LINK::~_NATIVE_CODE_LINK()
{
if (RawData)
delete RawData;
}
_NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK()
{
Start = End = NULL;
HasRelativeJumps = FALSE;
}
VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2) VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2)
{ {
if (Link1) if (Link1)
@ -63,7 +75,7 @@ VOID NcConcat(PNATIVE_CODE_BLOCK Block1, PNATIVE_CODE_BLOCK Block2)
BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block) BOOL NcInsertBlockAfter(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block)
{ {
return FALSE;
} }
BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block) BOOL NcInsertBlockBefore(PNATIVE_CODE_LINK Link, PNATIVE_CODE_BLOCK Block)
@ -203,16 +215,21 @@ BOOL NcFromBuffer(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize)
delete Link; delete Link;
return FALSE; return FALSE;
} }
Link->RawDataSize = XedDecodedInstGetLength(&Link->XedInst);
Link->RawData = new UCHAR[Link->RawDataSize];
Link->Block = Block; Link->Block = Block;
Link->Prev = Block->End; Link->Prev = Block->End;
Block->End->Next = Link; Block->End->Next = Link;
Block->End = Link; Block->End = Link;
Offset += XedDecodedInstGetLength(&Link->XedInst); Offset += Link->RawDataSize;
} }
PNATIVE_CODE_LINK StartLink = Block->Start; PNATIVE_CODE_LINK StartLink = Block->Start;
Block->Start = Block->Start->Next; Block->Start = Block->Start->Next;
if (Block->Start)
Block->Start->Prev = NULL;
delete StartLink; delete StartLink;
NcCreateLabels(Block); NcCreateLabels(Block);
@ -260,3 +277,16 @@ VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block)
} }
} }
VOID NcPrintBlockCode(PNATIVE_CODE_BLOCK Block)
{
for (PNATIVE_CODE_LINK T = Block->Start; T; T = T->Next)
{
if (!(T->Flags & CODE_FLAG_IS_LABEL))
{
for (uint32_t i = 0; i < T->RawDataSize; i++)
{
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)T->RawData[i] << ' ';
}
}
}
}

@ -19,6 +19,7 @@ typedef struct _NATIVE_CODE_LINK
XED_DECODED_INST XedInst; XED_DECODED_INST XedInst;
_NATIVE_CODE_LINK(); _NATIVE_CODE_LINK();
_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); _NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B);
~_NATIVE_CODE_LINK();
}NATIVE_CODE_LINK, *PNATIVE_CODE_LINK; }NATIVE_CODE_LINK, *PNATIVE_CODE_LINK;
typedef struct _NATIVE_CODE_BLOCK typedef struct _NATIVE_CODE_BLOCK
@ -26,6 +27,7 @@ typedef struct _NATIVE_CODE_BLOCK
PNATIVE_CODE_LINK Start; PNATIVE_CODE_LINK Start;
PNATIVE_CODE_LINK End; PNATIVE_CODE_LINK End;
BOOL HasRelativeJumps; BOOL HasRelativeJumps;
_NATIVE_CODE_BLOCK();
}NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK; }NATIVE_CODE_BLOCK, *PNATIVE_CODE_BLOCK;
VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2); VOID NcInsertLinkAfter(PNATIVE_CODE_LINK Link1, PNATIVE_CODE_LINK Link2);
@ -50,6 +52,6 @@ VOID NcDelete(PNATIVE_CODE_BLOCK Block);
VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block); VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block);
VOID NcPrintBlockCode(PNATIVE_CODE_BLOCK Block);
#endif #endif

@ -4,6 +4,8 @@
#include <Windows.h> #include <Windows.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <iostream>
#include <iomanip>
#define INLINE inline #define INLINE inline
#define STDSTRING std::string #define STDSTRING std::string

@ -0,0 +1,303 @@
#include "XorInstructions.h"
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;
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;
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);
*(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;
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);
*(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;
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);
*(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;
return TRUE;
}
PNATIVE_CODE_BLOCK ObfEmitPreXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags)
{
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;
if (SaveFlags && !ObfEmitPushfqInst(Block))
{
NcDelete(Block);
delete Block;
return NULL;
}
ULONG Count = FourByte;
while (Count)
{
//Account for remaining XORs
INT32 RipDelta = (((Count - 1) * DWORD_XOR_INST_LENGTH) + (TwoByte * WORD_XOR_INST_LENGTH) + (OneByte * BYTE_XOR_INST_LENGTH));
//Account for POPFQ
if (SaveFlags)
RipDelta += 1;
//Account for already XORd instructions
RipDelta += ((FourByte - Count) * 4);
//Add the actual instruction
if (!ObfEmitRipRelativeXorD(Block, RipDelta, XorData->Data[FourByte-Count]))
{
NcDelete(Block);
delete Block;
return NULL;
}
--Count;
}
if (TwoByte)
{
INT32 RipDelta = (OneByte * BYTE_XOR_INST_LENGTH);
if (SaveFlags)
RipDelta += 1;
RipDelta += (FourByte * 4);
if (!ObfEmitRipRelativeXorW(Block, RipDelta, XorData->Data[3]))
{
NcDelete(Block);
delete Block;
return NULL;
}
}
if (OneByte)
{
INT32 RipDelta = 0;
if (SaveFlags)
RipDelta += 1;
RipDelta += (FourByte * 4) + (TwoByte * 2);
if (!ObfEmitRipRelativeXorB(Block, RipDelta, XorData->Data[4]))
{
NcDelete(Block);
delete Block;
return NULL;
}
}
if (SaveFlags && !ObfEmitPopfqInst(Block))
{
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 ObfEmitPostXorForInst(PNATIVE_CODE_LINK Link, PXOR_INST_DATA XorData, BOOL SaveFlags)
{
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;
if (SaveFlags && !ObfEmitPushfqInst(Block))
{
NcDelete(Block);
delete Block;
return NULL;
}
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;
}
if (TwoByte)
{
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]))
{
NcDelete(Block);
delete Block;
return NULL;
}
}
if (OneByte)
{
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);
delete Block;
return NULL;
}
}
if (SaveFlags && !ObfEmitPopfqInst(Block))
{
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;
}

@ -0,0 +1,34 @@
#ifndef __CRYPTED_CODE_H
#define __CRYPTED_CODE_H
#include "Windas.h"
#include "XedWrap.h"
#include "NativeCode.h"
#define DWORD_XOR_INST_LENGTH 10
#define DWORD_XOR_INST_RIP_OFFSET 2
#define DWORD_XOR_INST_XOR_OFFSET 6
#define WORD_XOR_INST_LENGTH 9
#define WORD_XOR_INST_RIP_OFFSET 3
#define WORD_XOR_INST_XOR_OFFSET 7
#define BYTE_XOR_INST_LENGTH 7
#define BYTE_XOR_INST_RIP_OFFSET 2
#define BYTE_XOR_INST_XOR_OFFSET 6
typedef struct _XOR_INST_DATA
{
ULONG Data[5];
}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);
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

Binary file not shown.
Loading…
Cancel
Save