title: Hooking with MS Detours crash when hook function is called C++
body: <p>I wrote a simple program that does 3 things:<br></p>
  
  <p>It calls MessageBoxA (MBA) with the text "NOT HOOKED"<br></p>
  
  <p>Then it loads a dll file that I've created that hooks the MBA function and recalls MBA with the text "HOOKED".<br></p>
  
  <p>After that, it calls MBA again with the same text ("NOT HOOKED").
  Of course, the second MBA call should be hooked and display a message with "HOOKED" text it.</p>
  
  <p>Eventually it calls FreeLibrary and exits.</p>
  
  <p>Here is the .cpp file:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;Windows.h&gt;
  
  using namespace std;
  
  int main()
  {
      //Place the path of the dll file here, "DLLs\\HookDLL.dll" is the default path.
      char dllPath[] = "HookDLL.dll"; 
  
      //Display a pop-up message with the "NOT HOOKED" message and title. 
      MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
  
      //Load the dll file
      HMODULE hModule = LoadLibraryA((LPCSTR)dllPath);
  
      //If hModule is null, then the dll wasn't loaded.
      //An error message will be printed out to the console.
      if (!hModule) {
          cout &lt;&lt; "Couldn't load the DLL file!" &lt;&lt; endl;
  
          return 1;
      }
  
      //This is the tricky part.
      //This should display a pop-up message like before with the "NOT HOOKED" message and title,
      //but the dll that was loaded should hook MessageBoxA function,
      //and call a new one with a "HOOKED" message and title instead.
      MessageBoxA(NULL, "NOT HOOKED", "NOT HOOKED", MB_OK);
  
      FreeLibrary(hModule);
  
      return 0;
  }
  </code></pre>
  
  <p>here is the .dll file:</p>
  
  <pre><code>#include "pch.h"
  #include "detours.h"
  #include &lt;iostream&gt;
  #include &lt;Windows.h&gt;
  
  using namespace std;
  
  typedef int(WINAPI* MBA)(HWND, LPCSTR, LPCSTR, UINT);
  
  MBA originalMBA = NULL;
  
  int HookedMessageBoxA(
      HWND   hWnd,
      LPCSTR lpText,
      LPCSTR lpCaption,
      UINT   uType
  ) {
      return originalMBA(NULL, "HOOKED", "HOOKED", MB_OK);
  }
  
  BOOL APIENTRY DllMain(HMODULE hModule,
      DWORD  reason,
      LPVOID lpReserved
  )
  {
      if (reason == DLL_PROCESS_ATTACH) {
          DetourRestoreAfterWith();
          DetourTransactionBegin();
          DetourUpdateThread(GetCurrentThread());
  
          originalMBA = (MBA)DetourFindFunction("user32.dll", "MessageBoxA");//Pointer the the original MBA (MessageBoxA) function.
          DetourAttach(&amp;(PVOID&amp;)originalMBA, (PVOID)HookedMessageBoxA);
  
          DetourTransactionCommit();
      }
  
      return TRUE;
  }
  </code></pre>
  
  <p>When I build and run on Debug mode, it crashes on the second MBA call (in the .cpp file of course):<br>
  It displays the hooked MBA with "HOOKED" in it like it should, then the it crashes, printing the error below and the program exits with code 3:</p>
  
  <pre>
  Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.
  This is usually a result of calling a function declared with one calling convention with a function
  pointer declared with a different calling convention.
  </pre>
  
  <p>I've checked this error and the exit code and found lots of informative posts and solutions, but I couldn't make any of them work for me (maybe I've done something wrong).</p>
  
  <p><strong>NOTE1:</strong><br>
  If I'm on Release mode, I can call as many MBA calls as I want <strong>as long as they precedes</strong> the FreeLibrary call, and all of them will be hooked fine by the .dll file, and the program will exit correctly.
  But if I try to call the MBA function <strong>after</strong> the FreeLibrary call - the program crashes with this error:</p>
  
  <pre>
  Exception thrown at 0x50011000 in ProgrammingTask.exe: 0xC0000005: Access violation executing location 0x50011000.
  </pre>
  
  <p><strong>NOTE2:</strong><br>
  I tried detaching the dll using DetourDetouch, but it didn't solve it, maybe I did it wrong.<br>
  Also, I tried reading about CreateRemoteThread, but was too messy for me.</p>
  
  <p>Thanks in advance.</p>