Guest User

Untitled

a guest
Aug 21st, 2016
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.24 KB | None | 0 0
  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <vector>
  8.  
  9.  
  10. #define ASM_RET 0xC3
  11. #define ASM_MOV1 0x8B
  12. #define ASM_MOV2 0x89
  13. #define ASM_CALL 0xE8
  14. #define ASM_JMP 0xE9
  15. #define ASM_CALL_SIZE 0x01
  16. #define ASM_CALL_FULL_SIZE 0x05
  17.  
  18. using namespace std;
  19.  
  20. uint32_t __fastcall uiGetOpCodeSize(BYTE btOpCode)
  21. {
  22. switch (btOpCode)
  23. {
  24. // Only care about opcodes with a size greater than 1
  25. case 0xD5: // AAD
  26. return 2;
  27. case 0xD4: // AAM
  28. return 2;
  29.  
  30. #pragma region ADC
  31. // ADC
  32. case 0x14:
  33. return 2;
  34. case 0x15:
  35. return 3;
  36. case 0x12:
  37. return 2; // Can be 4
  38. case 0x13:
  39. return 2; // Can be 4
  40. case 0x80:
  41. return 3; // Can be 5
  42. case 0x81:
  43. return 4; // Can be 6
  44. case 0x83:
  45. return 3; // Can be 5
  46. case 0x10:
  47. return 2; // Can be 4
  48. case 0x11:
  49. return 2; // Can be 4
  50. #pragma endregion
  51. #pragma region ADD
  52. // ADD
  53. case 0x4:
  54. return 2;
  55. case 0x5:
  56. return 3;
  57. case 0x2:
  58. return 2; // Can be 4
  59. case 0x3:
  60. return 2; // Can be 4
  61. case 0x0:
  62. return 2; // Can be 4
  63. case 0x1:
  64. return 2; // Can be 4
  65. #pragma endregion
  66. #pragma region AND
  67. case 0x24:
  68. return 2;
  69. case 0x25:
  70. return 3;
  71. case 0x22:
  72. return 2; // Can be 4
  73. case 0x23:
  74. return 2; // Can be 4
  75. case 0x20:
  76. return 2; // Can be 4
  77. case 0x21:
  78. return 2; // Can be 4
  79. #pragma endregion
  80. case 0x63: // ARPL
  81. return 2; // Can be 4
  82. case 0x62: // BOUND
  83. return 2; // Can be 4
  84. case 0xF: // BSF || BSR || BSWAP
  85. return 4; // Can be 2, 3, 4, 5, or 6
  86. // MOST LIKELY TO BE 4
  87. #pragma region CALL
  88. case 0xE8:
  89. return 5;
  90. case 0xFF:
  91. return 2; // Can be 4
  92. case 0x9A:
  93. return 5;
  94. #pragma endregion
  95. case 0x66: // CDQ
  96. return 2;
  97. case 0xF5: // CLTS
  98. return 2;
  99. #pragma region CMP
  100. case 0x3C:
  101. return 2;
  102. case 0x3D:
  103. return 3;
  104. case 0x3A:
  105. return 2; // Can be 4
  106. case 0x3B:
  107. return 2; // Can be 4
  108. case 0x38:
  109. return 2; // Can be 4
  110. case 0x39:
  111. return 2; // Can be 4
  112. #pragma endregion
  113. #pragma region DIV
  114. case 0xF6:
  115. return 2; // Can be 4
  116. case 0xF7:
  117. return 2; // Can be 4
  118. #pragma endregion
  119. case 0xC8: // ENTER
  120. return 4;
  121. #pragma region HolyFuckFloats
  122. case 0xD9:
  123. return 2;
  124. case 0xDE:
  125. return 2;
  126. case 0xD8:
  127. return 2; // Can be 4
  128. case 0xDC:
  129. return 2; // Can be 4
  130. case 0x9B:
  131. return 3;
  132. case 0xDD:
  133. return 2;
  134. case 0xDA:
  135. return 2; // Can be 4
  136. case 0xDF:
  137. return 2; // Can be 4
  138. #pragma endregion
  139. #pragma region IMUL
  140. case 0x6B: // IMUL
  141. return 3; // Can be 5
  142. case 0x69:
  143. return 6; // Can be 8
  144. #pragma endregion
  145. #pragma region IN_OPCODE
  146. case 0xE4:
  147. return 2;
  148. case 0xE5:
  149. return 2;
  150. #pragma endregion
  151. case 0xFE: // INC
  152. return 2; // Can be 4
  153. case 0xCD: // INT
  154. return 2;
  155. case 0x77: // JA
  156. return 2;
  157. case 0x73: // JAE
  158. return 2;
  159. case 0x72: // JB
  160. return 2;
  161. case 0x76: // JBE
  162. return 2;
  163. case 0xE3: // JCXZ
  164. return 2;
  165. case 0x67: // JECXZ, wtf
  166. return 3;
  167. case 0x74: // JE
  168. return 2;
  169. case 0x7F: // JG
  170. return 4;
  171. case 0x7D: // JGE
  172. return 4;
  173. case 0x7C: // JL
  174. return 2;
  175. case 0x7E: // JLE
  176. return 2;
  177. #pragma region JMP
  178. case 0xEB:
  179. return 2;
  180. case 0xE9:
  181. return 3;
  182. case 0xEA:
  183. return 5;
  184. #pragma endregion
  185. case 0x75: // JNE
  186. return 2;
  187. case 0x71: // JNO
  188. return 2;
  189. case 0x79: // JNS
  190. return 2;
  191. case 0x7B: // JNP
  192. return 2;
  193. case 0x70: // JO
  194. return 2;
  195. case 0x7A: // JP
  196. return 2;
  197. case 0x78: // JS
  198. return 2;
  199. case 0xC5: // LDS
  200. return 2; // Can be 4
  201. case 0x8D: // LEA
  202. return 4; // Can be 2
  203. case 0xC4: // LES
  204. return 4; // Can be 2
  205. case 0xE2: // LOOP
  206. return 2;
  207. case 0xE1: // LOOPE
  208. return 2;
  209. case 0xE0: // LOOPNZ
  210. return 2;
  211. #pragma region MOV
  212. case 0xA0:
  213. return 3;
  214. case 0xA1:
  215. return 3;
  216. case 0xB0:
  217. return 2;
  218. case 0xB4:
  219. return 2;
  220. case 0xB8:
  221. return 5; // ? wat john, these can be up to 5 bytes; this actually fucked shit up rofl
  222. case 0xB1:
  223. return 2;
  224. case 0xB5:
  225. return 2;
  226. case 0xB9:
  227. return 3;
  228. case 0xB2:
  229. return 2;
  230. case 0xB6:
  231. return 2;
  232. case 0xBA:
  233. return 3;
  234. case 0xB3:
  235. return 2;
  236. case 0xB7:
  237. return 2;
  238. case 0xBB:
  239. return 3;
  240. case 0xBC:
  241. return 3;
  242. case 0xBD:
  243. return 3;
  244. case 0xBE:
  245. return 3;
  246. case 0xBF:
  247. return 3;
  248. case 0x8A:
  249. return 4; // Can be 2
  250. case 0x8B:
  251. return 3; // Can be 4 // FUCK ME; Or even 3 john, once again breaking code. (changed from 2 to 3)
  252. case 0xA2:
  253. return 3;
  254. case 0xA3:
  255. return 3;
  256. case 0xC6:
  257. return 5; // Can be 3
  258. case 0xC7:
  259. return 7; // Can be 4, actually it can even be 7. (changed value from 6 to 7)
  260. case 0x89:
  261. return 4; // Can be 2
  262. case 0x8C:
  263. return 4; // Can be 2
  264. case 0x8E:
  265. return 4; // Can be 2
  266. #pragma endregion
  267. #pragma region OR
  268. case 0xC:
  269. return 2;
  270. case 0xD:
  271. return 3;
  272. case 0xA:
  273. return 4; // Can be 2
  274. case 0xB:
  275. return 4; // Can be 2
  276. case 0x8:
  277. return 4; // Can be 2
  278. case 0x9:
  279. return 4; // Can be 2
  280. #pragma endregion
  281. #pragma region OUT_OPCODE
  282. case 0xE6:
  283. return 2;
  284. case 0xE7:
  285. return 2;
  286. #pragma endregion
  287. case 0x8F: // POP
  288. return 4; // Can be 2
  289. case 0x6A: // PUSH
  290. return 2;
  291. case 0x68:
  292. return 5;
  293. #pragma region ROTATE_SHIFT_OPCODES
  294. //RCR, RCL, ROR, ROL, SAL, SHL, SAR, SHR
  295. case 0xD0:
  296. return 4; // Can be 2
  297. case 0xD2:
  298. return 4; // Can be 2
  299. case 0xC0:
  300. return 5; // Can be 3
  301. case 0xD1:
  302. return 4; // Can be 2
  303. case 0xD3:
  304. return 4; // Can be 2
  305. case 0xC1:
  306. return 5; // Can be 3
  307. #pragma endregion
  308. #pragma region SBB
  309. case 0x1C:
  310. return 2;
  311. case 0x1D:
  312. return 3;
  313. case 0x1A:
  314. return 4; // Can be 2
  315. case 0x1B:
  316. return 4; // Can be 2
  317. case 0x18:
  318. return 4; // Can be 2
  319. case 0x19:
  320. return 4; // Can be 2
  321. #pragma endregion
  322. #pragma region SUB
  323. case 0x2C:
  324. return 2;
  325. case 0x2D:
  326. return 2;
  327. case 0x2A:
  328. return 2; // Can be 2 /*mambda note: set these from 4 to 2*/
  329. case 0x2B:
  330. return 2; // Can be 2
  331. case 0x28:
  332. return 2; // Can be 2
  333. case 0x29:
  334. return 2; // Can be 2
  335. #pragma endregion
  336. #pragma region TEST
  337. case 0xA8:
  338. return 2;
  339. case 0xA9:
  340. return 3;
  341. case 0x84:
  342. return 4; // Can be 2
  343. case 0x85:
  344. return 4; // Can be 2
  345. #pragma endregion
  346. #pragma region XCHG
  347. case 0x86:
  348. return 4; // Can be 2
  349. case 0x87:
  350. return 4; // Can be 2
  351. #pragma endregion
  352. #pragma region XOR
  353. case 0x34:
  354. return 2;
  355. case 0x35:
  356. return 2;
  357. case 0x32:
  358. return 2; // Can be 2 /*mambda: changed all these 3s to 2s*/
  359. case 0x33:
  360. return 2; // Can be 2
  361. case 0x30:
  362. return 2; // Can be 2
  363. case 0x31:
  364. return 2; // Can be 2
  365. #pragma endregion
  366.  
  367. default:
  368. return 1;
  369. }
  370. }
  371.  
  372. namespace MOVRegisters
  373. {
  374. enum MovRegisters
  375. {
  376. EAX = 0xB8,
  377. ECX,
  378. EDX,
  379. EBX,
  380. ESP,
  381. EBP,
  382. ESI,
  383. EDI
  384. };
  385. }
  386.  
  387. namespace SUBRegisters
  388. {
  389. enum SUBRegisters
  390. {
  391. EAX = 0xC0,
  392. ECX = EAX + 0x9,
  393. EDX = ECX + 0x9,
  394. EBX = EDX + 0x9,
  395. ESP = EBX + 0x9,
  396. EBP = ESP + 0x9,
  397. ESI = EBP + 0x9,
  398. EDI = ESI + 0x9
  399. };
  400. }
  401.  
  402. namespace ADDRegisters
  403. {
  404. enum ADDRegisters
  405. {
  406. EAX = 0x5,
  407. ECX = 0xC1,
  408. EDX,
  409. EBX,
  410. ESP,
  411. EBP,
  412. ESI,
  413. EDI
  414. };
  415. }
  416.  
  417. namespace ORRegisters
  418. {
  419. enum ORRegisters
  420. {
  421. EAX = 0xD,
  422. ECX = 0xC9,
  423. EDX,
  424. EBX,
  425. ESP,
  426. EBP,
  427. ESI,
  428. EDI
  429. };
  430. }
  431.  
  432. namespace XORRegisters
  433. {
  434. enum XorRegisters
  435. {
  436. EAX = 0xC0,
  437. ECX = EAX + 0x9,
  438. EDX = ECX + 0x9,
  439. EBX = EDX + 0x9,
  440. ESP = EBX + 0x9,
  441. EBP = ESP + 0x9,
  442. ESI = EBP + 0x9,
  443. EDI = ESI + 0x9
  444. };
  445. }
  446.  
  447. namespace POPRegisters
  448. {
  449. enum POPRegister
  450. {
  451. EAX = 0x58,
  452. ECX,
  453. EDX,
  454. EBX,
  455. ESP,
  456. EBP,
  457. ESI,
  458. EDI
  459. };
  460. }
  461.  
  462. INT add(INT x, INT y)
  463. {
  464. int result;
  465. __asm
  466. {
  467. mov eax, x
  468. add eax, y
  469. mov result, eax
  470. xor eax, eax
  471. }
  472. return result;
  473. }
  474.  
  475. struct OPCODE
  476. {
  477. unsigned short usSize;
  478. PBYTE pbOpCode;
  479. bool bMutated;
  480. };
  481.  
  482. void __fastcall MutateMOV(OPCODE * pOpCode, OPCODE * pOutOpCode, int &outAdd)
  483. {
  484.  
  485. int chosenMorph = 9;
  486.  
  487. if (chosenMorph == 9)
  488. {
  489. pOutOpCode->pbOpCode = new BYTE[6];
  490. switch (pOpCode->pbOpCode[0])
  491. {
  492. case MOVRegisters::EAX:
  493. pOutOpCode->pbOpCode[0] = 0x68;
  494. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  495. pOutOpCode->pbOpCode[5] = POPRegisters::EAX; // 0 -> 4 = 0x68 VALUE
  496. break;
  497. case MOVRegisters::ECX:
  498. pOutOpCode->pbOpCode[0] = 0x68;
  499. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  500. pOutOpCode->pbOpCode[5] = POPRegisters::ECX;
  501. break;
  502. case MOVRegisters::EDX:
  503. pOutOpCode->pbOpCode[0] = 0x68;
  504. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  505. pOutOpCode->pbOpCode[5] = POPRegisters::EDX;
  506. break;
  507. case MOVRegisters::EBX:
  508. pOutOpCode->pbOpCode[0] = 0x68;
  509. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  510. pOutOpCode->pbOpCode[5] = POPRegisters::EBX;
  511. break;
  512. case MOVRegisters::ESP:
  513. pOutOpCode->pbOpCode[0] = 0x68;
  514. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  515. pOutOpCode->pbOpCode[5] = POPRegisters::ESP;
  516. break;
  517. case MOVRegisters::EBP:
  518. pOutOpCode->pbOpCode[0] = 0x68;
  519. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  520. pOutOpCode->pbOpCode[5] = POPRegisters::EBP;
  521. break;
  522. case MOVRegisters::ESI:
  523. pOutOpCode->pbOpCode[0] = 0x68;
  524. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  525. pOutOpCode->pbOpCode[5] = POPRegisters::ESI;
  526. break;
  527. case MOVRegisters::EDI:
  528. pOutOpCode->pbOpCode[0] = 0x68;
  529. memcpy(&pOutOpCode->pbOpCode[1], &pOpCode->pbOpCode[1], 4);
  530. pOutOpCode->pbOpCode[5] = POPRegisters::EDI;
  531. break;
  532. }
  533. outAdd = 1;
  534. }
  535. }
  536.  
  537. void __fastcall Hotpatch(void* pOFunc, void* pHkFunc)
  538. {
  539. DWORD dwOldProt = 0;
  540. BYTE bPatch[5];
  541. bPatch[0] = 0xE9;
  542. VirtualProtect((void*)pOFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProt);
  543. DWORD dwRelativeAddr = ((DWORD)pHkFunc - (DWORD)pOFunc - 5);
  544. memcpy(&bPatch[1], &dwRelativeAddr, 4);
  545. memcpy(pOFunc, bPatch, 5);
  546. VirtualProtect((void*)pOFunc, 5, dwOldProt, NULL);
  547. }
  548.  
  549. PVOID pMorphFunc(PVOID pFunc, DWORD &dwSize, PVOID pLastFunc = nullptr)
  550. {
  551. std::vector<OPCODE*> vOpCodes = std::vector<OPCODE*>();
  552. uint32_t uiSize = 0;
  553. PBYTE pByte = (PBYTE)pFunc;
  554.  
  555. while (*pByte != ASM_RET)
  556. {
  557. OPCODE* pNewOp = new OPCODE();
  558. pNewOp->pbOpCode = pByte;
  559. if (*pByte == MOVRegisters::EAX || *pByte == MOVRegisters::EBP || *pByte == MOVRegisters::EBX || *pByte == MOVRegisters::ECX || *pByte == MOVRegisters::EDI
  560. || *pByte == MOVRegisters::EDX || *pByte == MOVRegisters::ESI || *pByte == MOVRegisters::ESP)
  561. {
  562. OPCODE * pMovOP = new OPCODE();
  563. int outAdd;
  564. MutateMOV(pNewOp, pMovOP, outAdd);
  565. uint32_t uiOpCodeSize = uiGetOpCodeSize(*pMovOP->pbOpCode) + outAdd;
  566.  
  567. pMovOP->usSize = uiOpCodeSize;
  568.  
  569. pMovOP->bMutated = true;
  570. delete pNewOp;
  571. vOpCodes.push_back(pMovOP);
  572.  
  573. pByte += uiOpCodeSize - (uiOpCodeSize - 5);
  574. uiSize += uiOpCodeSize;
  575. continue;
  576. }
  577. uint32_t uiOpCodeSize = uiGetOpCodeSize(*pByte);
  578. pNewOp->usSize = uiOpCodeSize;
  579.  
  580. pNewOp->bMutated = false;
  581. vOpCodes.push_back(pNewOp);
  582. pByte += uiOpCodeSize;
  583. uiSize += uiOpCodeSize;
  584.  
  585. if (*pByte == ASM_RET)
  586. {
  587. OPCODE* pNewOp = new OPCODE();
  588. pNewOp->pbOpCode = pByte;
  589. pNewOp->usSize = 1;
  590.  
  591. vOpCodes.push_back(pNewOp);
  592. ++uiSize;
  593. }
  594.  
  595. uint32_t uiOpCodesSize = vOpCodes.size();
  596. PVOID pNewFunction = VirtualAlloc(pLastFunc != nullptr ? pLastFunc : NULL, uiOpCodesSize + uiSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  597. memset(pNewFunction, 0x90, uiOpCodesSize + uiSize);
  598.  
  599. uint32_t uiCurrentOffset = 0;
  600. for (UINT i = 0; i < uiOpCodesSize; ++i)
  601. {
  602. OPCODE* pOpCode = vOpCodes.at(i);
  603.  
  604. memcpy((PVOID)((uint32_t)pNewFunction + uiCurrentOffset), pOpCode->pbOpCode, pOpCode->usSize);
  605.  
  606. uiCurrentOffset += pOpCode->usSize;
  607.  
  608. ++uiCurrentOffset;
  609.  
  610. if (pOpCode->bMutated)
  611. delete[pOpCode->usSize] pOpCode->pbOpCode;
  612.  
  613. delete pOpCode;
  614.  
  615. }
  616. Hotpatch(pFunc, pNewFunction);
  617.  
  618. dwSize = uiSize + uiOpCodesSize;
  619. return pNewFunction;
  620. }
  621. }
  622.  
  623. INT main()
  624. {
  625. PVOID pLastFunc = nullptr;
  626. DWORD dwLastSize = NULL;
  627. cout << add(3, 5);
  628. while (true)
  629. {
  630. if (pLastFunc != nullptr)
  631. {
  632. VirtualFree(pLastFunc, dwLastSize, MEM_DECOMMIT);
  633. VirtualFree(pLastFunc, 0, MEM_RELEASE);
  634. }
  635. pLastFunc = pMorphFunc(add, dwLastSize);
  636. cout << add(2, 4);
  637. system("pause");
  638. }
  639.  
  640. system("pause");
  641. return 0;
  642. }
Advertisement
Add Comment
Please, Sign In to add comment