Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <Windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <vector>
- #define ASM_RET 0xC3
- #define ASM_MOV1 0x8B
- #define ASM_MOV2 0x89
- #define ASM_CALL 0xE8
- #define ASM_JMP 0xE9
- #define ASM_CALL_SIZE 0x01
- #define ASM_CALL_FULL_SIZE 0x05
- using namespace std;
- 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;
- }
- }
- 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
- };
- }
- INT add(INT x, INT y)
- {
- int result;
- __asm
- {
- mov eax, x
- add eax, y
- mov result, eax
- xor eax, eax
- }
- return result;
- }
- struct OPCODE
- {
- unsigned short usSize;
- PBYTE pbOpCode;
- bool bMutated;
- };
- void __fastcall MutateMOV(OPCODE * pOpCode, OPCODE * pOutOpCode, int &outAdd)
- {
- int chosenMorph = 9;
- if (chosenMorph == 9)
- {
- 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;
- }
- }
- 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);
- }
- PVOID pMorphFunc(PVOID pFunc, DWORD &dwSize, PVOID pLastFunc = nullptr)
- {
- std::vector<OPCODE*> vOpCodes = std::vector<OPCODE*>();
- uint32_t uiSize = 0;
- PBYTE pByte = (PBYTE)pFunc;
- while (*pByte != ASM_RET)
- {
- OPCODE* pNewOp = new OPCODE();
- pNewOp->pbOpCode = pByte;
- if (*pByte == MOVRegisters::EAX || *pByte == MOVRegisters::EBP || *pByte == MOVRegisters::EBX || *pByte == MOVRegisters::ECX || *pByte == MOVRegisters::EDI
- || *pByte == MOVRegisters::EDX || *pByte == MOVRegisters::ESI || *pByte == MOVRegisters::ESP)
- {
- OPCODE * pMovOP = new OPCODE();
- int outAdd;
- MutateMOV(pNewOp, pMovOP, outAdd);
- uint32_t uiOpCodeSize = uiGetOpCodeSize(*pMovOP->pbOpCode) + outAdd;
- pMovOP->usSize = uiOpCodeSize;
- pMovOP->bMutated = true;
- delete pNewOp;
- vOpCodes.push_back(pMovOP);
- pByte += uiOpCodeSize - (uiOpCodeSize - 5);
- uiSize += uiOpCodeSize;
- continue;
- }
- uint32_t uiOpCodeSize = uiGetOpCodeSize(*pByte);
- pNewOp->usSize = uiOpCodeSize;
- pNewOp->bMutated = false;
- vOpCodes.push_back(pNewOp);
- pByte += uiOpCodeSize;
- uiSize += uiOpCodeSize;
- if (*pByte == ASM_RET)
- {
- OPCODE* pNewOp = new OPCODE();
- pNewOp->pbOpCode = pByte;
- pNewOp->usSize = 1;
- 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 (UINT i = 0; i < uiOpCodesSize; ++i)
- {
- OPCODE* pOpCode = vOpCodes.at(i);
- memcpy((PVOID)((uint32_t)pNewFunction + uiCurrentOffset), pOpCode->pbOpCode, pOpCode->usSize);
- uiCurrentOffset += pOpCode->usSize;
- ++uiCurrentOffset;
- if (pOpCode->bMutated)
- delete[pOpCode->usSize] pOpCode->pbOpCode;
- delete pOpCode;
- }
- Hotpatch(pFunc, pNewFunction);
- dwSize = uiSize + uiOpCodesSize;
- return pNewFunction;
- }
- }
- INT main()
- {
- PVOID pLastFunc = nullptr;
- DWORD dwLastSize = NULL;
- cout << add(3, 5);
- while (true)
- {
- if (pLastFunc != nullptr)
- {
- VirtualFree(pLastFunc, dwLastSize, MEM_DECOMMIT);
- VirtualFree(pLastFunc, 0, MEM_RELEASE);
- }
- pLastFunc = pMorphFunc(add, dwLastSize);
- cout << add(2, 4);
- system("pause");
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment