Есть ли возможный способ использовать MS Detours в этом примере? - PullRequest
0 голосов
/ 25 сентября 2019

Прежде всего, я студент и хочу извлечь уроки из этой проблемы, поэтому мне не нужен полный код решения в качестве ответа, а нужна помощь.

Эти ссылки могут помочь вам:)

https://github.com/microsoft/Detours

https://github.com/microsoft/Detours/wiki

https://www.codeproject.com/Articles/30140/API-Hooking-with-MS-Detours

https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583

У меня есть код, который перехватитфункция на другую функцию, изменяющую точку быстрого исправления исходной функции.Проблема в том, что этот пример не работает с архитектурой x64, поэтому я должен использовать некоторые инструменты для реализации этого перехвата.Я использую MS Detours для этого, но есть проблема в моей реализации, и мне нужна помощь экспертов, потому что я новичок в этой области, и я хочу понять это и учиться как можно лучше.

Вот код, который у меня сейчас есть (::Trace(...) не важен, поэтому вы можете просто пропустить строки с ним):

//
// Constructor
//
CFunctionControll::CFunctionControll(const TCHAR* sczName, BYTE* pOrigFunc, BYTE* pDetourFunc)
{
   ::Trace(2, _T("CFunctionControll::CFuncDetour_Beging"));

   m_sczName = sczName;
   m_dwOrgProtect = 0;
   m_pOrigFunc = pOrigFunc;
   m_pDetourFunc = pDetourFunc;

   ::Trace(2, _T("CFunctionControll::CFuncDetour_End"));
}

//
// Destructor
//
CFunctionControll::~CFunctionControll()
{
   ::Trace(2, _T("CFunctionControll::~CFuncDetour_Beging"));

   Disable();

   ::Trace(2, _T("CFunctionControll::~CFuncDetour_End"));
}

//
// Enable - the hooking will be active
//
void CFunctionControll::Enable()
{
   ::Trace(2, _T("CFunctionControll::Enable_Begin"));

   try
   {
      Init();

      if (m_dwOrgProtect)
      {
         // saving the original hot-patch point
         memcpy(m_arrHotPatchPoint, m_pOrigFunc - 5, 7);

         // hot-patch point: "mov edi, edi" -> jmp short $-5
         m_pOrigFunc[0] = 0xEB;
         m_pOrigFunc[1] = 0xF9;

         // jmp relative to pOrigFuncNop
         // Before "hot-patch point" there is allways 5 times "nop" (until Windows 7) or "int 3" (Windows 10)
         BYTE* pOrigFuncNop = m_pOrigFunc - 5;
         pOrigFuncNop[0] = 0xE9;

         int addressdifference = m_pDetourFunc - (pOrigFuncNop + 5);

         memcpy(pOrigFuncNop + 1, &addressdifference, 4);
      }

   }
   catch (...)
   {
      // TODO
   }

   ::Trace(2, _T("CFunctionControll::Enable_End"));
}

//
// Disable - deactivating the hook function
//
void CFunctionControll::Disable()
{
   ::Trace(2, _T("CFunctionControll::Disable_Begin"));

   try
   {
      if (m_dwOrgProtect)
      {
         // Overwrite the hot-patch to original one
         memcpy(m_pOrigFunc - 5, m_arrHotPatchPoint, 7);
      }
   }
   catch (...)
   {
      // TODO
   }

   ::Trace(2, _T("CFunctionControll::Disable_End"));
}

//
// Init - marks hot-patch-point-memory as "EXECUTE/READ/WRITE"
//
void CFunctionControll::Init()
{
   if (!m_dwOrgProtect)
   {
      ::Trace(2, _T("CFunctionControll::Init_Begin"));

      if (m_pOrigFunc[0] == 0xFF && m_pOrigFunc[1] == 0x25) // "jmp dword ptr ds:[offset]": ds:[offset] - the true  function address
      {
         CString strMsg;
         strMsg.Format(_T("CFunctionControll::Enable: 'jmp dword ptr ds:[offset] hot-patch-point' in function: %s."), m_sczName);
         ::Trace(2, strMsg);
         DWORD dwAddress = *(DWORD*)(m_pOrigFunc + 2); // ds:[offset] - function address
         __asm
         {
            mov eax, dwAddress
            mov eax, dword ptr ds : [eax]
            mov dwAddress, eax
         }
         m_pOrigFunc = (BYTE*)dwAddress;
      }

      if (m_pOrigFunc[0] == 0x8B && m_pOrigFunc[1] == 0xFF || // "mov edi, edi" oder
         m_pOrigFunc[0] == 0xEB && m_pOrigFunc[1] == 0x9F) // "jmp short $-5": the function is already hooked
      {
         if (!VirtualProtect(m_pOrigFunc - 5, 7, PAGE_EXECUTE_READWRITE, &m_dwOrgProtect))
         {
            DWORD nErr = GetLastError();
            CString strMsg;
            strMsg.Format(_T("CFunctionControll::Enable: function  VirtualProtect failed. Errorcode: %X"), nErr);
            ::Trace(1, strMsg);
            m_dwOrgProtect = 0;
         }
         else if (m_pOrigFunc[0] == 0xEB && m_pOrigFunc[1] == 0x9F)
         {
            CString strMsg;
            strMsg.Format(_T("CFunctionControll::Enable: function %s is already hooked!"), m_sczName);
            ::Trace(1, strMsg);
         }
      }
      else
      {
         CString strMsg;
         strMsg.Format(_T("CFunctionControll::Enable: unknown 'hot-patch-point' format in function: %s!"), m_sczName);
         ::Trace(1, strMsg);
         m_dwOrgProtect = 0;
      }

      ::Trace(2, _T("CFunctionControll::Init_End"));
   }
}

Вот мой код после использования MS Detours:

// Constructor
CFunctionControll::CFunctionControll(BYTE* pOrigFunc, BYTE* pDetourFunc)
{
   m_pOrigFunc = pOrigFunc;
   m_pDetourFunc = pDetourFunc;
}


// Destructor
CFunctionControll::~CFunctionControll()
{
   Disable();
}


void CFunctionControll::Enable()
{

   try
   {
      DetourTransactionBegin();
      DetourUpdateThread(GetCurrentThread());
      DetourAttach(&(LPVOID&)m_pOrigFunc+2, m_pDetourFunc);
      if (!DetourTransactionCommit())
         throw transactionerror;
   }
   catch (TransactionError)
   {
      // Add proper exception handling later
   }
}


void CFunctionControll::Disable()
{

   try
   {
       DetourTransactionBegin();
       DetourUpdateThread(GetCurrentThread());
       DetourDetach(&(LPVOID&)m_pOrigFunc+2, m_pDetourFunc);
       if (!DetourTransactionCommit())
          throw transactionerror;
   }
   catch (TransactionError)
   {
      // Add proper exception handling later
   }
}

class TransactionError : public std::exception
{
   virtual const char* what() const throw()
   {
      return "DetourTransactionCommit() failed.";
   }
} transactionerror;

Вы можете найти объяснение функций MS Detours здесь: https://github.com/microsoft/Detours/wiki/Using-Detours

Может кто-нибудь помочь мне с проблемой?

...