Advertisement
Guest User

Untitled

a guest
Apr 18th, 2011
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.04 KB | None | 0 0
  1. #include "detourxs.h"
  2. #include "ADE32.h"
  3.  
  4. #pragma warning(disable: 4311)
  5. #pragma warning(disable: 4312)
  6. #pragma warning(disable: 4244)
  7.  
  8. #define DETOUR_MAX_SRCH_OPLEN 64
  9.  
  10. #define JMP32_SZ 5
  11. #define BIT32_SZ 4
  12.  
  13. // jmp32 sig
  14. #define SIG_SZ 3
  15. #define SIG_OP_0 0xCC
  16. #define SIG_OP_1 0x90
  17. #define SIG_OP_2 0xC3
  18.  
  19. static DWORD dwOldProt;
  20.  
  21. int GetDetourLen(int patchType);
  22. int GetDetourLenAuto(PBYTE &pbFuncOrig, int minDetLen);
  23.  
  24. // Thin wrapper for APIs
  25. LPVOID DetourCreate(LPCSTR lpModuleName, LPCSTR lpProcName, LPVOID lpFuncDetour, int patchType, int detourLen)
  26. {
  27.     LPVOID lpFuncOrig = NULL;
  28.        
  29.     if((lpFuncOrig = GetProcAddress(GetModuleHandleA(lpModuleName), lpProcName)) == NULL)
  30.         return NULL;
  31.  
  32.     return DetourCreate(lpFuncOrig, lpFuncDetour, patchType, detourLen);
  33. }
  34.  
  35. LPVOID DetourCreate(LPVOID lpFuncOrig, LPVOID lpFuncDetour, int patchType, int detourLen)
  36. {
  37.     LPVOID lpMallocPtr = NULL;
  38.     DWORD dwProt = NULL;
  39.     PBYTE pbMallocPtr = NULL;
  40.     PBYTE pbFuncOrig = (PBYTE)lpFuncOrig;
  41.     PBYTE pbFuncDetour = (PBYTE)lpFuncDetour;
  42.     PBYTE pbPatchBuf = NULL;
  43.     int minDetLen = 0;
  44.     int detLen = 0;
  45.  
  46.     // Get detour length
  47.     if((minDetLen = GetDetourLen(patchType)) == 0)
  48.         return NULL;
  49.  
  50.     if(detourLen != DETOUR_LEN_AUTO)
  51.         detLen = detourLen;
  52.  
  53.     else if((detLen = GetDetourLenAuto(pbFuncOrig, minDetLen)) < minDetLen)
  54.         return NULL;
  55.  
  56.     // Alloc mem for the overwritten bytes
  57.     if((lpMallocPtr = (LPVOID)malloc(detLen+JMP32_SZ+SIG_SZ)) == NULL)
  58.         return NULL;
  59.  
  60.     pbMallocPtr = (PBYTE)lpMallocPtr;
  61.  
  62.     // Enable writing to original
  63.     VirtualProtect(lpFuncOrig, detLen, PAGE_READWRITE, &dwProt);
  64.  
  65.     // Write overwritten bytes to the malloc
  66.     memcpy(lpMallocPtr, lpFuncOrig, detLen);
  67.     pbMallocPtr += detLen;
  68.     pbMallocPtr[0] = 0xE9;
  69.     *(DWORD*)(pbMallocPtr+1) = (DWORD)((pbFuncOrig+detLen)-pbMallocPtr)-JMP32_SZ;
  70.     pbMallocPtr += JMP32_SZ;
  71.     pbMallocPtr[0] = SIG_OP_0;
  72.     pbMallocPtr[1] = SIG_OP_1;
  73.     pbMallocPtr[2] = SIG_OP_2;
  74.  
  75.     // Create a buffer to prepare the detour bytes
  76.     pbPatchBuf = new BYTE[detLen];
  77.     memset(pbPatchBuf, 0x90, detLen);
  78.  
  79.     switch(patchType)
  80.     {
  81.         case DETOUR_TYPE_JMP:
  82.             pbPatchBuf[0] = 0xE9;
  83.             *(DWORD*)&pbPatchBuf[1] = (DWORD)(pbFuncDetour - pbFuncOrig) - 5;
  84.             break;
  85.  
  86.         case DETOUR_TYPE_PUSH_RET:
  87.             pbPatchBuf[0] = 0x68;
  88.             *(DWORD*)&pbPatchBuf[1] = (DWORD)pbFuncDetour;
  89.             pbPatchBuf[5] = 0xC3;
  90.             break;
  91.  
  92.         case DETOUR_TYPE_NOP_JMP:
  93.             pbPatchBuf[0] = 0x90;
  94.             pbPatchBuf[1] = 0xE9;
  95.             *(DWORD*)&pbPatchBuf[2] = (DWORD)(pbFuncDetour - pbFuncOrig) - 6;
  96.             break;
  97.  
  98.         case DETOUR_TYPE_NOP_NOP_JMP:
  99.             pbPatchBuf[0] = 0x90;
  100.             pbPatchBuf[1] = 0x90;
  101.             pbPatchBuf[2] = 0xE9;
  102.             *(DWORD*)&pbPatchBuf[3] = (DWORD)(pbFuncDetour - pbFuncOrig) - 7;
  103.             break;
  104.  
  105.         case DETOUR_TYPE_STC_JC:
  106.             pbPatchBuf[0] = 0xF9;
  107.             pbPatchBuf[1] = 0x0F;
  108.             pbPatchBuf[2] = 0x82;
  109.             *(DWORD*)&pbPatchBuf[3] = (DWORD)(pbFuncDetour - pbFuncOrig) - 7;
  110.             break;
  111.  
  112.         case DETOUR_TYPE_CLC_JNC:
  113.             pbPatchBuf[0] = 0xF8;
  114.             pbPatchBuf[1] = 0x0F;
  115.             pbPatchBuf[2] = 0x83;
  116.             *(DWORD*)&pbPatchBuf[3] = (DWORD)(pbFuncDetour - pbFuncOrig) - 7;
  117.             break;
  118.        
  119.         default:
  120.             return NULL;
  121.     }
  122.  
  123.     // Write the detour
  124.     for(int i=0; i<detLen; i++)
  125.         pbFuncOrig[i] = pbPatchBuf[i];
  126.  
  127.     delete [] pbPatchBuf;
  128.  
  129.     // Reset original mem flags
  130.     VirtualProtect(lpFuncOrig, detLen, dwProt, &dwOldProt);
  131.  
  132.     return lpMallocPtr;
  133. }
  134.  
  135. BOOL DetourRemove(LPVOID lpDetourCreatePtr)
  136. {
  137.     PBYTE pbMallocPtr = NULL;
  138.     DWORD dwFuncOrig = NULL;
  139.     DWORD dwProt = NULL;
  140.     int i=0;
  141.  
  142.     if((pbMallocPtr = (PBYTE)lpDetourCreatePtr) == NULL)
  143.         return FALSE;
  144.  
  145.     // Find the orig jmp32 opcode sig
  146.     for(i=0; i<=DETOUR_MAX_SRCH_OPLEN; i++)
  147.     {
  148.         if(pbMallocPtr[i] == SIG_OP_0
  149.             && pbMallocPtr[i+1] == SIG_OP_1
  150.             && pbMallocPtr[i+2] == SIG_OP_2)
  151.             break;
  152.  
  153.         if(i == DETOUR_MAX_SRCH_OPLEN)
  154.             return FALSE;
  155.     }
  156.  
  157.     // Calculate the original address
  158.     pbMallocPtr += (i-JMP32_SZ+1); // Inc to jmp
  159.     dwFuncOrig = *(DWORD*)pbMallocPtr; // Get 32bit jmp
  160.     pbMallocPtr += BIT32_SZ; // Inc to end of jmp
  161.     dwFuncOrig += (DWORD)pbMallocPtr; // Add this addr to 32bit jmp
  162.     dwFuncOrig -= (i-JMP32_SZ); // Dec by detour len to get to start of orig
  163.  
  164.     // Write the overwritten bytes back to the original
  165.     VirtualProtect((LPVOID)dwFuncOrig, (i-JMP32_SZ), PAGE_READWRITE, &dwProt);
  166.     memcpy((LPVOID)dwFuncOrig, lpDetourCreatePtr, (i-JMP32_SZ));
  167.     VirtualProtect((LPVOID)dwFuncOrig, (i-JMP32_SZ), dwProt, &dwOldProt);
  168.  
  169.     // Memory cleanup
  170.     free(lpDetourCreatePtr);
  171.  
  172.     return TRUE;
  173. }
  174.  
  175. int GetDetourLen(int patchType)
  176. {
  177.     switch(patchType)
  178.     {
  179.         case DETOUR_TYPE_JMP:
  180.             return 5;
  181.  
  182.         case DETOUR_TYPE_PUSH_RET:
  183.         case DETOUR_TYPE_NOP_JMP:
  184.             return 6;
  185.        
  186.         case DETOUR_TYPE_NOP_NOP_JMP:
  187.         case DETOUR_TYPE_STC_JC:
  188.         case DETOUR_TYPE_CLC_JNC:
  189.             return 7;
  190.        
  191.         default:
  192.             return 0;
  193.     }
  194. }
  195.  
  196. int GetDetourLenAuto(PBYTE &pbFuncOrig, int minDetLen)
  197. {
  198.     int len = 0;
  199.     PBYTE pbCurOp = pbFuncOrig;
  200.  
  201.     while(len < minDetLen)
  202.     {
  203.         int i = oplen(pbCurOp);
  204.        
  205.         if(i == 0 || i == -1)
  206.             return 0;
  207.  
  208.         if(len > DETOUR_MAX_SRCH_OPLEN)
  209.             return 0;
  210.  
  211.         len += i;
  212.         pbCurOp += i;
  213.     }
  214.  
  215.     return len;
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement