Detours DLL injection works only for specific applications

  detours, dll, dll-injection, hook, windows

I try to hook some functions using Microsoft Detours. The method I’m using is CreateRemoteThread + LoadLibrary.

Yet, I’ve encountered that the exact same code works on notepad.exe, chrome.exe etc., but not on wmplayer.exe, Calculator.exe somehow. Is it correct to say that these applications probably tried to prevent this type of DLL injection? I can hardly come up with other possibilities.

Most of these code are copied from the Detours tutorial

The code can be seen and cloned from this repository in case anyone want to experiment them.

  • DLL:

    INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
    {
        try {
            std::ofstream file("D:output.txt");
            file << "Hello!n";
            file.close();
        }
        catch (...) {
            std::ofstream file("D:error.txt");
            file << "Hello!n";
            file.close();
        }
    }
    
  • Injector:

      int main(void)
      {
          if (fileExists("D:output.txt"))
          {
              printf("Removing...n");
              remove("D:output.txt");
          }
          PROCESSENTRY32 pe32;
          pe32.dwSize = sizeof(PROCESSENTRY32);
          HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
          if (Process32First(hTool32, &pe32))
          {
              while ((Process32Next(hTool32, &pe32)) == TRUE) {
                  char exeName[] = "Calculator.exe";
                  //char exeName[] = "notepad.exe";
                  if (strcmp(pe32.szExeFile, exeName) == 0)
                  {
                      printf("Found %s at %dn", exeName, pe32.th32ProcessID);
                      char* DirPath = new char[MAX_PATH];
                      char* FullPath = new char[MAX_PATH];
                      GetCurrentDirectory(MAX_PATH, DirPath);
                      sprintf_s(FullPath, MAX_PATH, "%s..x64DebugTestDLL.dll", DirPath);
                      printf("%s File exists: %dn", FullPath, fileExists(FullPath));
                      HANDLE hProcess = OpenProcess(
                          PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
                      LPVOID LoadLibraryAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
                      LPVOID LLParam = (LPVOID)VirtualAllocEx(hProcess, NULL, strlen(FullPath),
                          MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
                      BOOL status = WriteProcessMemory(hProcess, LLParam, FullPath, strlen(FullPath), NULL);
                      auto handle = CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibraryAddr,
                          LLParam, NULL, NULL);
                      CloseHandle(hProcess);
                      delete[] DirPath;
                      delete[] FullPath;
                      std::cin.get();
                  }
    
              }
          }
          CloseHandle(hTool32);
          return 0;
      }
    

when the variable exeName is set to "chrome.exe" or "notepad.exe", the file "D:output.txt" will be created, while setting the variable to "Calculator.exe" won’t.

If my guess is correct, is using other injection method(ex. SetWindowsHookEx) the only way I can make these work?

Source: Windows Questions

LEAVE A COMMENT