将 dll 注入 Windows 10 记事本

Posted

技术标签:

【中文标题】将 dll 注入 Windows 10 记事本【英文标题】:Injecting a dll into Windows 10 notepad 【发布时间】:2020-04-29 14:41:42 【问题描述】:

我正在尝试。 注入器和 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(dllName) for const char* dllName 在 x64 上总是 8 个字节,这不是你需要的。请改用strlen(dllName) @ssbssa 哇。你甚至不知道我在这件事上被困了多久。非常感谢,有时我只需要别人来看看和发现我想念的小东西。 【参考方案1】:

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

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

【讨论】:

以上是关于将 dll 注入 Windows 10 记事本的主要内容,如果未能解决你的问题,请参考以下文章

使用 C 崩溃记事本进行 DLL 注入

我在试着做一个木马Loader注入记事本然后CreateRemoteThread启动DLL 但是似乎注入成功,DLL没有启动

不小心把DLL文件打开方式默认为记事本了。。。

dll文件怎么打开

Windows 记事本将支持 Unix 换行符

使用挂钩函数时应用程序崩溃