Broihon

Untitled

Jan 2nd, 2017
1,029
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "Detour.h"
  2.  
  3. #ifdef _WIN64
  4. #define DET_MIN_SIZE 0x0C
  5. #else
  6. #define DET_MIN_SIZE 5
  7. #endif
  8.  
  9. Detour::Detour()
  10. {
  11.     m_pTarget   = nullptr;
  12.     m_pHook     = nullptr;
  13.     m_pTrp      = nullptr;
  14.     m_Length    = 0;
  15.     m_State     = false;
  16.     m_Init      = false;
  17. }
  18.  
  19. Detour::~Detour()
  20. {
  21.     Remove();
  22. }
  23.  
  24. void * Detour::CreateDetour(void * pTarget, void * pHook, UINT Length, bool Active)
  25. {
  26.     if (!pTarget || !pHook || Length < DET_MIN_SIZE)
  27.         return nullptr;
  28.  
  29.     if (m_Init)
  30.         Remove();
  31.  
  32.     m_pTrp = VirtualAlloc(nullptr, Length + DET_MIN_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  33.     if (!m_pTrp)
  34.         return nullptr;
  35.  
  36.     m_pTarget   = pTarget;
  37.     m_pHook     = pHook;
  38.     m_Length    = Length;
  39.    
  40.     memcpy(m_pTrp, m_pTarget, m_Length);
  41.  
  42.     #ifdef _WIN64
  43.  
  44.     BYTE CodeCave[] =
  45.     {
  46.         0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00 (+ 0x02)  -> mov rax, pHook
  47.         0xFF, 0xE0                                                  // + 0x0A           -> jmp rax
  48.     };
  49.     *reinterpret_cast<UINT_PTR*>(CodeCave + 2) = reinterpret_cast<UINT_PTR>(m_pTarget) + Length;
  50.  
  51.     #else
  52.  
  53.     BYTE CodeCave[] =
  54.     {
  55.         0xE9, 0x00, 0x00, 0x00, 0x00    // + 0x00 (+ 0x01)  -> jmp pHook
  56.     };
  57.     *reinterpret_cast<DWORD*>(CodeCave + 1) = reinterpret_cast<DWORD>(m_pTarget) - reinterpret_cast<DWORD>(m_pTrp) - 5;
  58.  
  59.     #endif
  60.  
  61.     memcpy(reinterpret_cast<BYTE*>(m_pTrp) + Length, CodeCave, sizeof(CodeCave));
  62.  
  63.     m_Init = true;
  64.    
  65.     if (Active)
  66.         Activate();
  67.  
  68.     return m_pTrp;
  69. }
  70.  
  71. bool Detour::Activate()
  72. {
  73.     if (m_State)
  74.         return true;
  75.  
  76.     if (!m_pTarget || !m_pHook || !m_Length || !m_Init)
  77.         return false;
  78.  
  79.     if (!Hook())
  80.         return false;
  81.  
  82.     m_State = true;
  83.  
  84.     return true;
  85. }
  86.  
  87. bool Detour::Deactivate()
  88. {
  89.     if (!m_State)
  90.         return true;
  91.  
  92.     if (!m_pTarget || !m_pHook || !m_Length || !m_Init)
  93.         return false;
  94.  
  95.     DWORD dwOld;
  96.     if(!VirtualProtect(m_pTarget, m_Length, PAGE_EXECUTE_READWRITE, &dwOld))
  97.         return false;
  98.  
  99.     memcpy(m_pTarget, m_pTrp, m_Length);
  100.     VirtualProtect(m_pTarget, m_Length, dwOld, &dwOld);
  101.  
  102.     m_State = false;
  103.  
  104.     return true;
  105. }
  106.  
  107. bool Detour::Remove()
  108. {
  109.     if (Deactivate())
  110.     {
  111.         VirtualFree(m_pTrp, 0, MEM_RELEASE);
  112.         m_pTarget   = nullptr;
  113.         m_pHook     = nullptr;
  114.         m_pTrp      = nullptr;
  115.         m_Length    = 0;
  116.         m_State     = false;
  117.         m_Init      = false;
  118.        
  119.         return true;
  120.     }
  121.     return false;
  122. }
  123.  
  124. bool Detour::Hook()
  125. {
  126.     if (!m_Init)
  127.         return false;
  128.  
  129.     #ifdef _WIN64
  130.  
  131.     BYTE CodeCave[] =
  132.     {
  133.         0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00 (+ 0x02)  -> mov rax, pHook
  134.         0xFF, 0xE0                                                  // + 0x0A           -> jmp rax
  135.     };
  136.     *reinterpret_cast<UINT_PTR*>(CodeCave + 2) = reinterpret_cast<UINT_PTR>(m_pHook);
  137.  
  138.     #else
  139.  
  140.     BYTE CodeCave[] =
  141.     {
  142.         0xE9, 0x00, 0x00, 0x00, 0x00 // + 0x00 (+ 0x01) -> jmp pHook
  143.     };
  144.     *reinterpret_cast<DWORD*>(CodeCave + 1) = reinterpret_cast<DWORD>(m_pHook) - reinterpret_cast<DWORD>(m_pTarget) - 5;
  145.  
  146.     #endif
  147.  
  148.     DWORD dwOld = 0;
  149.     if (!VirtualProtect(m_pTarget, sizeof(CodeCave), PAGE_EXECUTE_READWRITE, &dwOld))
  150.         return false;
  151.  
  152.     memcpy(m_pTarget, CodeCave, sizeof(CodeCave));
  153.     VirtualProtect(m_pTarget, sizeof(CodeCave), dwOld, &dwOld);
  154.  
  155.     return true;
  156. }
Add Comment
Please, Sign In to add comment