Skip to content

Instantly share code, notes, and snippets.

@mislavjakopovic
Created December 31, 2021 00:51
Show Gist options
  • Save mislavjakopovic/fde2724744d4087c6538790e701ac8d1 to your computer and use it in GitHub Desktop.
Save mislavjakopovic/fde2724744d4087c6538790e701ac8d1 to your computer and use it in GitHub Desktop.
#include "stdafx.h"
void __fastcall Hotpatch(void* pOFunc, void* pHkFunc)
{
DWORD dwOldProt = 0;
BYTE bPatch[5];
bPatch[0] = 0xE9;
VirtualProtect((void*)pOFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProt);
DWORD dwRelativeAddr = ((DWORD)pHkFunc - (DWORD)pOFunc - 5);
memcpy(&bPatch[1], &dwRelativeAddr, 4);
memcpy(pOFunc, bPatch, 5);
VirtualProtect((void*)pOFunc, 5, dwOldProt, NULL);
}
uint32_t __fastcall uiGetOpCodeSize(BYTE btOpCode)
{
switch (btOpCode)
{
// Only care about opcodes with a size greater than 1
case 0xD5: // AAD
return 2;
case 0xD4: // AAM
return 2;
#pragma region ADC
// ADC
case 0x14:
return 2;
case 0x15:
return 3;
case 0x12:
return 2; // Can be 4
case 0x13:
return 2; // Can be 4
case 0x80:
return 3; // Can be 5
case 0x81:
return 4; // Can be 6
case 0x83:
return 3; // Can be 5
case 0x10:
return 2; // Can be 4
case 0x11:
return 2; // Can be 4
#pragma endregion
#pragma region ADD
// ADD
case 0x4:
return 2;
case 0x5:
return 3;
case 0x2:
return 2; // Can be 4
case 0x3:
return 2; // Can be 4
case 0x0:
return 2; // Can be 4
case 0x1:
return 2; // Can be 4
#pragma endregion
#pragma region AND
case 0x24:
return 2;
case 0x25:
return 3;
case 0x22:
return 2; // Can be 4
case 0x23:
return 2; // Can be 4
case 0x20:
return 2; // Can be 4
case 0x21:
return 2; // Can be 4
#pragma endregion
case 0x63: // ARPL
return 2; // Can be 4
case 0x62: // BOUND
return 2; // Can be 4
case 0xF: // BSF || BSR || BSWAP
return 4; // Can be 2, 3, 4, 5, or 6
// MOST LIKELY TO BE 4
#pragma region CALL
case 0xE8:
return 5;
case 0xFF:
return 2; // Can be 4
case 0x9A:
return 5;
#pragma endregion
case 0x66: // CDQ
return 2;
case 0xF5: // CLTS
return 2;
#pragma region CMP
case 0x3C:
return 2;
case 0x3D:
return 3;
case 0x3A:
return 2; // Can be 4
case 0x3B:
return 2; // Can be 4
case 0x38:
return 2; // Can be 4
case 0x39:
return 2; // Can be 4
#pragma endregion
#pragma region DIV
case 0xF6:
return 2; // Can be 4
case 0xF7:
return 2; // Can be 4
#pragma endregion
case 0xC8: // ENTER
return 4;
#pragma region HolyFuckFloats
case 0xD9:
return 2;
case 0xDE:
return 2;
case 0xD8:
return 2; // Can be 4
case 0xDC:
return 2; // Can be 4
case 0x9B:
return 3;
case 0xDD:
return 2;
case 0xDA:
return 2; // Can be 4
case 0xDF:
return 2; // Can be 4
#pragma endregion
#pragma region IMUL
case 0x6B: // IMUL
return 3; // Can be 5
case 0x69:
return 6; // Can be 8
#pragma endregion
#pragma region IN_OPCODE
case 0xE4:
return 2;
case 0xE5:
return 2;
#pragma endregion
case 0xFE: // INC
return 2; // Can be 4
case 0xCD: // INT
return 2;
case 0x77: // JA
return 2;
case 0x73: // JAE
return 2;
case 0x72: // JB
return 2;
case 0x76: // JBE
return 2;
case 0xE3: // JCXZ
return 2;
case 0x67: // JECXZ, wtf
return 3;
case 0x74: // JE
return 2;
case 0x7F: // JG
return 4;
case 0x7D: // JGE
return 4;
case 0x7C: // JL
return 2;
case 0x7E: // JLE
return 2;
#pragma region JMP
case 0xEB:
return 2;
case 0xE9:
return 3;
case 0xEA:
return 5;
#pragma endregion
case 0x75: // JNE
return 2;
case 0x71: // JNO
return 2;
case 0x79: // JNS
return 2;
case 0x7B: // JNP
return 2;
case 0x70: // JO
return 2;
case 0x7A: // JP
return 2;
case 0x78: // JS
return 2;
case 0xC5: // LDS
return 2; // Can be 4
case 0x8D: // LEA
return 4; // Can be 2
case 0xC4: // LES
return 4; // Can be 2
case 0xE2: // LOOP
return 2;
case 0xE1: // LOOPE
return 2;
case 0xE0: // LOOPNZ
return 2;
#pragma region MOV
case 0xA0:
return 3;
case 0xA1:
return 3;
case 0xB0:
return 2;
case 0xB4:
return 2;
case 0xB8:
return 5; // ? wat john, these can be up to 5 bytes; this actually fucked shit up rofl
case 0xB1:
return 2;
case 0xB5:
return 2;
case 0xB9:
return 3;
case 0xB2:
return 2;
case 0xB6:
return 2;
case 0xBA:
return 3;
case 0xB3:
return 2;
case 0xB7:
return 2;
case 0xBB:
return 3;
case 0xBC:
return 3;
case 0xBD:
return 3;
case 0xBE:
return 3;
case 0xBF:
return 3;
case 0x8A:
return 4; // Can be 2
case 0x8B:
return 3; // Can be 4 // FUCK ME; Or even 3 john, once again breaking code. (changed from 2 to 3)
case 0xA2:
return 3;
case 0xA3:
return 3;
case 0xC6:
return 5; // Can be 3
case 0xC7:
return 7; // Can be 4, actually it can even be 7. (changed value from 6 to 7)
case 0x89:
return 4; // Can be 2
case 0x8C:
return 4; // Can be 2
case 0x8E:
return 4; // Can be 2
#pragma endregion
#pragma region OR
case 0xC:
return 2;
case 0xD:
return 3;
case 0xA:
return 4; // Can be 2
case 0xB:
return 4; // Can be 2
case 0x8:
return 4; // Can be 2
case 0x9:
return 4; // Can be 2
#pragma endregion
#pragma region OUT_OPCODE
case 0xE6:
return 2;
case 0xE7:
return 2;
#pragma endregion
case 0x8F: // POP
return 4; // Can be 2
case 0x6A: // PUSH
return 2;
case 0x68:
return 5;
#pragma region ROTATE_SHIFT_OPCODES
//RCR, RCL, ROR, ROL, SAL, SHL, SAR, SHR
case 0xD0:
return 4; // Can be 2
case 0xD2:
return 4; // Can be 2
case 0xC0:
return 5; // Can be 3
case 0xD1:
return 4; // Can be 2
case 0xD3:
return 4; // Can be 2
case 0xC1:
return 5; // Can be 3
#pragma endregion
#pragma region SBB
case 0x1C:
return 2;
case 0x1D:
return 3;
case 0x1A:
return 4; // Can be 2
case 0x1B:
return 4; // Can be 2
case 0x18:
return 4; // Can be 2
case 0x19:
return 4; // Can be 2
#pragma endregion
#pragma region SUB
case 0x2C:
return 2;
case 0x2D:
return 2;
case 0x2A:
return 2; // Can be 2 /*mambda note: set these from 4 to 2*/
case 0x2B:
return 2; // Can be 2
case 0x28:
return 2; // Can be 2
case 0x29:
return 2; // Can be 2
#pragma endregion
#pragma region TEST
case 0xA8:
return 2;
case 0xA9:
return 3;
case 0x84:
return 4; // Can be 2
case 0x85:
return 4; // Can be 2
#pragma endregion
#pragma region XCHG
case 0x86:
return 4; // Can be 2
case 0x87:
return 4; // Can be 2
#pragma endregion
#pragma region XOR
case 0x34:
return 2;
case 0x35:
return 2;
case 0x32:
return 2; // Can be 2 /*mambda: changed all these 3s to 2s*/
case 0x33:
return 2; // Can be 2
case 0x30:
return 2; // Can be 2
case 0x31:
return 2; // Can be 2
#pragma endregion
default:
return 1;
}
}
bool __fastcall bIsRelativeOpCode(BYTE btOpCode)
{
switch (btOpCode)
{
case 0xE8:
return true;
// TODO: Finish this function
default:
return false;
}
}
/*
PVOID __fastcall pFindCodeCave(PVOID pStartingAddr, uint32_t uiSize)
{
uiSize += 2;
PVOID pCodeCode = nullptr
while (pCodeCode == nullptr)
{
if(
}
return pCodeCode;
}
*/
struct OPCODE
{
unsigned short usSize;
PBYTE pbOpCode;
bool bRelative;
bool bMutated;
};
#pragma region MOV / POP / XOR / OR Register Byte definitions
namespace MOVRegisters
{
enum MovRegisters
{
EAX = 0xB8,
ECX,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI
};
}
namespace SUBRegisters
{
enum SUBRegisters
{
EAX = 0xC0,
ECX = EAX + 0x9,
EDX = ECX + 0x9,
EBX = EDX + 0x9,
ESP = EBX + 0x9,
EBP = ESP + 0x9,
ESI = EBP + 0x9,
EDI = ESI + 0x9
};
}
namespace ADDRegisters
{
enum ADDRegisters
{
EAX = 0x5,
ECX = 0xC1,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI
};
}
namespace ORRegisters
{
enum ORRegisters
{
EAX = 0xD,
ECX = 0xC9,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI
};
}
namespace XORRegisters
{
enum XorRegisters
{
EAX = 0xC0,
ECX = EAX + 0x9,
EDX = ECX + 0x9,
EBX = EDX + 0x9,
ESP = EBX + 0x9,
EBP = ESP + 0x9,
ESI = EBP + 0x9,
EDI = ESI + 0x9
};
}
namespace POPRegisters
{
enum POPRegister
{
EAX = 0x58,
ECX,
EDX,
EBX,
ESP,
EBP,
ESI,
EDI
};
}
#pragma endregion
bool __fastcall bIsMOV(PBYTE pInstruction)
{
if (*pInstruction == MOVRegisters::EAX || *pInstruction == MOVRegisters::ECX || *pInstruction == MOVRegisters::EDX || *pInstruction == MOVRegisters::EBX ||
*pInstruction == MOVRegisters::ESP || *pInstruction == MOVRegisters::EBP || *pInstruction == MOVRegisters::ESI || *pInstruction == MOVRegisters::EDI)
return true;
else
return false;
}
bool __fastcall bIsPUSH(PBYTE pInstruction)
{
return *pInstruction == 0x68;
}
//outAdd = value to add to uiOpCodeSize
void __fastcall MutatePUSH(OPCODE * pOpCodeIn, OPCODE * pOpCodeOut)
{
pOpCodeOut->pbOpCode[0] = 0x83;
pOpCodeOut->pbOpCode[1] = 0xEC;
pOpCodeOut->pbOpCode[2] = 0x4; // 3
pOpCodeOut->pbOpCode[3] = 0xC7;
pOpCodeOut->pbOpCode[4] = 0x04;
pOpCodeOut->pbOpCode[5] = 0x24; // 3
memcpy(&pOpCodeOut->pbOpCode[6], &pOpCodeIn->pbOpCode[1], 4); // 4
//5 bytes to 10 bytes, haha.
}
void __fastcall MutateMOV(OPCODE * pOpCode, OPCODE * pOutOpCode, int &outAdd)
{
srand(GetTickCount());
int chosenMorph = rand() % 9;
if (chosenMorph % 2 == 0)
{
pOutOpCode->pbOpCode = new BYTE[6];
switch (pOpCode->pbOpCode[0])
{
case MOVRegisters::EAX:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::EAX; // 0 -> 4 = 0x68 VALUE
break;
case MOVRegisters::ECX:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::ECX;
break;
case MOVRegisters::EDX:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::EDX;
break;
case MOVRegisters::EBX:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::EBX;
break;
case MOVRegisters::ESP:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::ESP;
break;
case MOVRegisters::EBP:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::EBP;
break;
case MOVRegisters::ESI:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::ESI;
break;
case MOVRegisters::EDI:
pOutOpCode->pbOpCode[0] = 0x68;
memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
pOutOpCode->pbOpCode[5] = POPRegisters::EDI;
break;
}
outAdd = 1;
}
else if (chosenMorph % 3 == 0)
{
if (pOpCode->pbOpCode[0] == MOVRegisters::EAX)
pOutOpCode->pbOpCode = new BYTE[7]; // initialize it in here because the size is variable
else
pOutOpCode->pbOpCode = new BYTE[8]; // initialize it in here because the size is variable
switch (pOpCode->pbOpCode[0])
{
case MOVRegisters::EAX:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::EAX;
pOutOpCode->pbOpCode[2] = ORRegisters::EAX;
memcpy(&pOutOpCode->pbOpCode[3], &pOpCode->pbOpCode[1], 4);
outAdd = 5;
return;
case MOVRegisters::ECX:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::ECX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::ECX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EDX:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::EDX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::EDX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EBX:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::EBX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::EBX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::ESP:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::ESP;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::ESP;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EBP:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::EBP;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::EBP;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::ESI:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::ESI;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::ESI;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EDI:
pOutOpCode->pbOpCode[0] = 0x31;
pOutOpCode->pbOpCode[1] = XORRegisters::EDI;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ORRegisters::EDI;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
}
outAdd = 6;
}
else
{
if (pOpCode->pbOpCode[0] == MOVRegisters::EAX)
pOutOpCode->pbOpCode = new BYTE[7]; // initialize it in here because the size is variable
else
pOutOpCode->pbOpCode = new BYTE[8]; // initialize it in here because the size is variable
switch (pOpCode->pbOpCode[0])
{
case MOVRegisters::EAX:
pOutOpCode->pbOpCode[0] = 0xC0;
pOutOpCode->pbOpCode[1] = SUBRegisters::EAX;
pOutOpCode->pbOpCode[2] = ADDRegisters::EAX;
memcpy(&pOutOpCode->pbOpCode[3], &pOpCode->pbOpCode[1], 4); // get that value.
outAdd = 5;
return;
case MOVRegisters::ECX:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::ECX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::ECX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EDX:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::EDX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::EDX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EBX:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::EBX;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::EBX;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::ESP:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::ESP;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::ESP;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EBP:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::EBP;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::EBP;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::ESI:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::ESI;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::ESI;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
case MOVRegisters::EDI:
pOutOpCode->pbOpCode[0] = 0x29;
pOutOpCode->pbOpCode[1] = SUBRegisters::EDI;
pOutOpCode->pbOpCode[2] = 0x81;
pOutOpCode->pbOpCode[3] = ADDRegisters::EDI;
memcpy(&pOutOpCode->pbOpCode[4], &pOpCode->pbOpCode[1], 4); // get that value.
break;
}
outAdd = 6;
}
}
PVOID __fastcall pMorphFunction(PVOID pFunction, PBYTE pFirstFive, DWORD& dwSize, PVOID pLastFunc = nullptr)
{
if (*pFirstFive == 0x0)
memcpy(pFirstFive, pFunction, 5);
else
memcpy(pFunction, pFirstFive, 5);
std::vector<OPCODE*> vOpCodes = std::vector<OPCODE*>();
uint32_t uiSize = 0;
PBYTE pCurrentByte = (PBYTE)pFunction;
while (*pCurrentByte != 0xC3 && *pCurrentByte != 0xC2 && *pCurrentByte != 0xCB && *pCurrentByte != 0xCA)
{
OPCODE* pNewOp = new OPCODE();
pNewOp->pbOpCode = pCurrentByte;
#pragma region MOV Mutation
if (bIsMOV(pNewOp->pbOpCode))
{
OPCODE * pMovOP = new OPCODE();
int outAdd;
MutateMOV(pNewOp, pMovOP, outAdd);
uint32_t uiOpCodeSize = uiGetOpCodeSize(*pMovOP->pbOpCode) + outAdd;
pMovOP->usSize = uiOpCodeSize;
pMovOP->bRelative = bIsRelativeOpCode(*pMovOP->pbOpCode);
pMovOP->bMutated = true;
delete pNewOp;
vOpCodes.push_back(pMovOP);
pCurrentByte += uiOpCodeSize - (uiOpCodeSize - 5);
uiSize += uiOpCodeSize;
continue;
}
#pragma endregion
#pragma region PUSH Mutation
else if (bIsPUSH(pCurrentByte))
{
OPCODE * pPushOP = new OPCODE();
pPushOP->pbOpCode = new BYTE[9];
MutatePUSH(pNewOp, pPushOP);
uint32_t uiOpCodeSize = uiGetOpCodeSize(*pPushOP->pbOpCode) + 7;
pPushOP->usSize = uiOpCodeSize;
pPushOP->bRelative = bIsRelativeOpCode(*pPushOP->pbOpCode);
pPushOP->bMutated = true;
delete pNewOp;
vOpCodes.push_back(pPushOP);
pCurrentByte += uiOpCodeSize - 5;
uiSize += uiOpCodeSize;
continue;
}
#pragma endregion
uint32_t uiOpCodeSize = uiGetOpCodeSize(*pCurrentByte);
pNewOp->usSize = uiOpCodeSize;
pNewOp->bRelative = bIsRelativeOpCode(*pCurrentByte);
pNewOp->bMutated = false;
vOpCodes.push_back(pNewOp);
pCurrentByte += uiOpCodeSize;
uiSize += uiOpCodeSize;
}
if (*pCurrentByte == 0xC2 || *pCurrentByte == 0xCA)
{
OPCODE* pNewOp = new OPCODE();
pNewOp->pbOpCode = pCurrentByte;
pNewOp->usSize = 3;
pNewOp->bRelative = false;
vOpCodes.push_back(pNewOp);
uiSize += 3;
}
else
{
OPCODE* pNewOp = new OPCODE();
pNewOp->pbOpCode = pCurrentByte;
pNewOp->usSize = 1;
pNewOp->bRelative = false;
vOpCodes.push_back(pNewOp);
++uiSize;
}
uint32_t uiOpCodesSize = vOpCodes.size();
PVOID pNewFunction = VirtualAlloc(pLastFunc != nullptr ? pLastFunc : NULL, uiOpCodesSize + uiSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memset(pNewFunction, 0x90, uiOpCodesSize + uiSize);
uint32_t uiCurrentOffset = 0;
for (unsigned int i = 0; i < uiOpCodesSize; ++i)
{
OPCODE* pOpCode = vOpCodes.at(i);
memcpy((PVOID)((uint32_t)pNewFunction + uiCurrentOffset), pOpCode->pbOpCode, pOpCode->usSize);
if (pOpCode->bRelative)
{
DWORD dwNewRelative = ((DWORD)pOpCode->pbOpCode + *(DWORD*)(pOpCode->pbOpCode + 1)) - ((DWORD)pNewFunction + uiCurrentOffset);
memcpy((PVOID)((uint32_t)pNewFunction + uiCurrentOffset + 1), &dwNewRelative, sizeof(DWORD));
}
uiCurrentOffset += pOpCode->usSize;
++uiCurrentOffset;
if (pOpCode->bMutated)
delete[pOpCode->usSize] pOpCode->pbOpCode;
delete pOpCode;
int holdMeHereThanksBreakpoint = 0;
}
Hotpatch(pFunction, pNewFunction);
dwSize = uiOpCodesSize + uiSize;
return pNewFunction;
}
void __cdecl TestFunc()
{
int eaxVal = 0;
_asm
{
push ecx
mov ecx, 5
mov eaxVal, ecx
pop ecx
}
printf("Testing %d\n", eaxVal);
}
int _tmain(int argc, _TCHAR* argv[])
{
PBYTE pFirstFive = (PBYTE)malloc(5);
RtlZeroMemory(pFirstFive, 5);
TestFunc();
PVOID pLastFunc = nullptr;
DWORD dwLastSize = NULL;
while (true)
{
if (pLastFunc != nullptr)
{
VirtualFree(pLastFunc, dwLastSize, MEM_DECOMMIT);
VirtualFree(pLastFunc, 0, MEM_RELEASE);//dwLastSize needs to be 0 for this to work best jumbooo
}
pLastFunc = pMorphFunction(TestFunc, pFirstFive, dwLastSize);
TestFunc();
system("pause");
}
TestFunc();
system("pause");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment