|
|
|
#include "Obfuscator.h"
|
|
|
|
|
|
|
|
BOOL JitEmitRipRelativeMovD(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
|
|
|
|
{
|
|
|
|
UCHAR RawData[] = { 0xC7, 0x05, 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;
|
|
|
|
RtlCopyMemory(&Link->RawData[6], Data, 4);
|
|
|
|
XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
|
|
|
|
NcAppendToBlock(Block, Link);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL JitEmitRipRelativeMovW(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
|
|
|
|
{
|
|
|
|
UCHAR RawData[] = { 0x66, 0xC7, 0x05, 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;
|
|
|
|
RtlCopyMemory(&Link->RawData[7], Data, 2);
|
|
|
|
XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
|
|
|
|
NcAppendToBlock(Block, Link);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL JitEmitRipRelativeMovB(PNATIVE_CODE_BLOCK Block, INT32 RipDelta, PUCHAR Data)
|
|
|
|
{
|
|
|
|
UCHAR RawData[] = { 0xC6, 0x05, 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;
|
|
|
|
Link->RawData[6] = *Data;
|
|
|
|
XedDecode(&Link->XedInstruction, Link->RawData, Link->RawDataSize);
|
|
|
|
NcAppendToBlock(Block, Link);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
PNATIVE_CODE_BLOCK JitEmitPreRipMov(PNATIVE_CODE_LINK Link, INT32 Delta)
|
|
|
|
{
|
|
|
|
UINT FourByte = Link->RawDataSize / 4;
|
|
|
|
UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2;
|
|
|
|
UINT 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;
|
|
|
|
UINT 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)
|
|
|
|
{
|
|
|
|
UINT FourByte = Link->RawDataSize / 4;
|
|
|
|
UINT TwoByte = (Link->RawDataSize - (FourByte * 4)) / 2;
|
|
|
|
UINT OneByte = (Link->RawDataSize - (FourByte * 4) - (TwoByte * 2));
|
|
|
|
|
|
|
|
PNATIVE_CODE_BLOCK Block = new NATIVE_CODE_BLOCK;
|
|
|
|
|
|
|
|
Block->Start = Block->End = new NATIVE_CODE_LINK;
|
|
|
|
UINT ZeroValue = 0;
|
|
|
|
UINT 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;
|
|
|
|
}
|