You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
8.6 KiB

#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;
}