Advertisement
EDHpastebin

Retcheck by Eternal

Feb 9th, 2018
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.28 KB | None | 0 0
  1. DWORD unprotect(DWORD addr)
  2. {
  3.     BYTE* tAddr = (BYTE*)addr;
  4.  
  5.     /* Calcualte the size of the function
  6.     In theory this will run until it hits the next
  7.     functions prolog. It assumes all calls are aligned to
  8.     16 bytes. (grazie katie)
  9.     */
  10.     do
  11.     {
  12.         tAddr += 16;
  13.     } while (!(tAddr[0] == 0x55 && tAddr[1] == 0x8B && tAddr[2] == 0xEC));
  14.  
  15.     DWORD funcSz = tAddr - (BYTE*)addr;
  16.  
  17.     /* Allocate memory for the new function */
  18.     PVOID nFunc = VirtualAlloc(NULL, funcSz, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  19.     if (nFunc == NULL)
  20.         return addr;
  21.  
  22.     /* Copy the function to the newly allocated memory */
  23.     memcpy(nFunc, (void*)addr, funcSz);
  24.  
  25.     BYTE* pos = (BYTE*)nFunc;
  26.     BOOL valid = false;
  27.     do
  28.     {
  29.         /* Check for the return check with the sig:
  30.         72 ?? A1 ?? ?? ?? ?? 8B
  31.         If the sig matches replace the the jb with a jmp.
  32.         */
  33.         if (pos[0] == 0x72 && pos[2] == 0xA1 && pos[7] == 0x8B) {
  34.             *(BYTE*)pos = 0xEB;
  35.  
  36.             DWORD cByte = (DWORD)nFunc;
  37.             do
  38.             {
  39.                 /* Check if the current byte is a call if it is,
  40.                 calculate the new relative call(s).
  41.                 *(->E8 + 1) = originalFunction - nextInstruction
  42.  
  43.                 oFuncPos - Position of call in original function
  44.                 = originalFunction + (->E8 - newFunction)
  45.  
  46.                 oFuncAddr - Original call location
  47.                 = oFuncPos + rel32Offset + sizeof(call)
  48.  
  49.                 relativeAddr - New relative address
  50.                 = oFuncAddr - ->E8 - sizeof(call)
  51.  
  52.                 Since we are not using a disassembler we assume
  53.                 that if we hit a E8 byte which is properly aligned
  54.                 it is a relative call.
  55.                 For a small amount of compensation I skip location
  56.                 of the call, since it is possible to have the byte
  57.                 E8 inside of it.
  58.                 */
  59.                 if (*(BYTE*)cByte == 0xE8)
  60.                 {
  61.                     DWORD oFuncPos = addr + (cByte - (DWORD)nFunc);
  62.                     DWORD oFuncAddr = (oFuncPos + *(DWORD*)(oFuncPos + 1)) + 5;
  63.  
  64.                     if (oFuncAddr % 16 == 0)
  65.                     {
  66.                         DWORD relativeAddr = oFuncAddr - cByte - 5;
  67.                         *(DWORD*)(cByte + 1) = relativeAddr;
  68.  
  69.                         cByte += 4;
  70.                     }
  71.                 }
  72.  
  73.                 cByte += 1;
  74.             } while (cByte - (DWORD)nFunc < funcSz);
  75.  
  76.             valid = true;
  77.         }
  78.         pos += 1;
  79.     } while ((DWORD)pos < (DWORD)nFunc + funcSz);
  80.  
  81.     /* This function has no return check, let's not waste memory */
  82.     if (!valid)
  83.     {
  84.         VirtualFree(nFunc, funcSz, MEM_RELEASE);
  85.         return addr;
  86.     }
  87.  
  88.     return (DWORD)nFunc;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement