将 dll 注入 Windows 10 记事本

Injecting a dll into Windows 10 notepad

我正在尝试将一个 dll 注入 Windows 10 记事本。 注入器和dll都是在x64中编译的。

我正在使用 LoadLibrary 将 dll 注入记事本进程。我几乎可以肯定我的方法有效,因为,嗯,结果表明它有效。但它似乎并没有安静工作。

mydll.h:

#pragma once
#ifdef DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif
extern "C"
{
    DECLDIR void Share();
    void Keep();
}

DllMain.cpp:

#include <Windows.h>

#define DLL_EXPORT
#include "mydll.h"

extern "C"
{
    DECLDIR void Share()
    {
        MessageBox(NULL, "Share function", "Share", MB_OK);
    }
    void Keep()
    {
        MessageBox(NULL, "Keep function", "Keep", MB_OK);
    }
}

BOOLEAN WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved)
{
    BOOLEAN bSuccess = TRUE;

    //  Perform global initialization.
    switch (nReason)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hDllHandle);
        Share();
        Keep();
        break;
    case DLL_THREAD_ATTACH: break;
    case DLL_THREAD_DETACH: break;
    case DLL_PROCESS_DETACH: break;
    }

    return bSuccess;

}

Injector.h

#pragma once
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>

class Injector
{
public:
    static bool inject(const char* targetProcName, const char* dllName);

private:
    static DWORD getTargetProcessID(const char* targetProcName);

};

Injector.cpp

#include "Injector.h"

/*
Function to inject a dll into a running process.
Input:
    targetProcName - The exe file name of the running process.
    dllName - The path to the dll.
Output: TRUE if success, FALSE if failed.
*/
bool Injector::inject(const char* targetProcName, const char* dllName)
{
    try
    {
        // Get the process id of the target process.
        DWORD targetProcID = getTargetProcessID(targetProcName);
        if (!targetProcID) {
            throw "Target process Was not found";
        }

        // Get a static address of the LoadLibrary function as a thread-start-routine function.
        LPTHREAD_START_ROUTINE funcLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
        if (!funcLoadLibrary) {
            throw "Failed to retrieve a static function pointer to `LoadLbraryA`";
        }

        // Open the target process.
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcID);
        if (hProcess == INVALID_HANDLE_VALUE) {
            throw "Failed to open target process";
        }

        // Virtually allocate memory for the path of the dll in the target process.
        LPVOID pDllPathAddr = VirtualAllocEx(hProcess, 0, sizeof(dllName) + 1, MEM_COMMIT, PAGE_READWRITE);
        if (!pDllPathAddr) {
            throw "Failed to allocate memory in the target process";
        }

        // Write the dll path to the target process using WPM.
        WriteProcessMemory(hProcess, pDllPathAddr, (LPVOID)dllName, sizeof(dllName) + 1, NULL);

        // Create a remote thread in the target process with LoadLibrary to load our dll into the target process.
        HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, NULL, funcLoadLibrary, pDllPathAddr, NULL, NULL);
        if (!hRemoteThread || hRemoteThread == INVALID_HANDLE_VALUE) {
            throw "Failed to load dll into target process";
        }

        // Wait until the remote thread is done loading the dll.
        WaitForSingleObject(hRemoteThread, INFINITE);
    }
    catch (const char* err) {
        std::cout << "An erro occurred: " << err << std::endl;
        return false;
    }

    return true;
}

/*
Function to retrieve the ID of a running process.
Input:
    targetProcName - The exe file name of the target process.
Output: The process's ID.
*/
DWORD Injector::getTargetProcessID(const char* targetProcName)
{
    // PROCESSENTRY32 is used to open and get information about a running process..
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    // We use a th32snapprocess to iterate through all running processes.
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    // Success check oon the snapshot tool.
    if (!hSnap) {
        throw "Snapshot tool failed to open";
    }

    // If a first process exist (there are running processes), iterate through
    // all running processes.
    DWORD ProcID = NULL;
    if (Process32First(hSnap, &entry)) {
        do 
        {
            // If the current process entry is the target process, store its ID.
            if (!strcmp(entry.szExeFile, targetProcName))
            {
                ProcID = entry.th32ProcessID;
            }
        }
        while (Process32Next(hSnap, &entry) && !ProcID);        // Move on to the next running process.
    }
    else {
        // If there was no first process, notify the user.
        throw "No running processes found";
    }

    return ProcID;
}

main.cpp

#include "Injector.h"

#define TARGET_PROC "notepad.exe"
#define DLL_NAME "../Debug/mydll.dll"

/*
Program to inject a dll into the notepad.exe process.
*/
int main()
{
    char fullname[MAX_PATH] = { 0 };
    GetFullPathName(DLL_NAME, MAX_PATH, fullname, NULL);
    bool success = Injector::inject(TARGET_PROC, fullname);

    std::cout << "Did the injecition succeded? " << success << std::endl;

    return 0;
}

结果显示注入成功,但我没有收到应该从记事本进程中收到的消息框。

sizeof() 将 return 指针的大小,而不是字符数。

您需要对 dllName 使用 strlen 才能将正确的字节数写入目标进程。