首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++动态链接库注入-- Hello world动态链接库只有在注入到注入它的同一个.exe中时才能工作

C++动态链接库注入-- Hello world动态链接库只有在注入到注入它的同一个.exe中时才能工作
EN

Stack Overflow用户
提问于 2012-11-18 17:04:07
回答 1查看 6.5K关注 0票数 4

过去一周,我一直在努力让我的简单注入应用程序成功地将dll注入到其他进程中。然而,到目前为止,只有当我将dll注入到注入器本身时,它才能工作。当我试图注入一个不同的应用程序时,我的函数报告成功(线程被成功创建,内存被分配并写入目标),但是我的dllMain似乎没有被调用。此外,错误代码0 (ERROR_SUCCESS)由GetLastError()指定。

targetProcessId指定为GetCurrentProcess()时,将显示对话框,并成功执行RemoteThread。

但是,当我尝试将targetProcessId设置为正在运行的calc.exe实例时,什么也没有发生。我在其他地方读到,从DllMain调用MessageBox不是一个好主意,因为它的模块可能还没有加载,所以我也尝试在我的DllMain中创建一个无限循环,并检查calc.exe中的线程计数是否增加了1。它保持不变。

这是我在StackOverflow上的第一个问题,我试着在发帖前对这个话题做了尽可能多的研究,但几个小时后我一直没有运气。我显然是dll注入的新手(我最近读完了Ritcher的书,Windows via C/C++)。任何帮助都是非常感谢的。

我的所有代码都是从面向x64平台的Visual Studio2010编译而来的。

下面是我的Injector应用程序中的相关代码:

代码语言:javascript
复制
BOOL WINAPI Inject(DWORD processID, PCWSTR sourceDLL)
{
    BOOL success = false;
    HANDLE targetProcess = NULL, createdThread = NULL;
    PWSTR pszLibFileRemote = NULL;
    __try
    {
        std::cout << "Process ID: "<< processID << std::endl;
        targetProcess = OpenProcess(
            PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION  | PROCESS_VM_WRITE,
            FALSE, processID);
        if (targetProcess == NULL)
        {
            std::cout << "ERROR: " << GetLastError();
            MessageBox(NULL, L"Unable to open process.", L"Error", MB_OK);
            __leave;
        }

        int cch = 1 + lstrlenW(sourceDLL); //Calculate the number of bytes required for the DLL's path
        int cb = cch * sizeof(wchar_t);

        pszLibFileRemote = (PWSTR)VirtualAllocEx(targetProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
        if (pszLibFileRemote == NULL)
        {
            MessageBox(NULL, L"Could not allocate dll pathname in target process.", L"Error", MB_OK);
            __leave;
        }

        if (!WriteProcessMemory(targetProcess, pszLibFileRemote, (PVOID) sourceDLL, cb, NULL))
        {
            MessageBox(NULL, L"Could not write dll pathname in target process.", L"Error", MB_OK);
            __leave;
        }

        PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");

        if (pfnThreadRtn == NULL)
        {
            MessageBox(NULL, L"Error finding LoadLibraryW address.", L"Error", MB_OK);
            __leave;
        }

        createdThread = CreateRemoteThread(targetProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
        if (createdThread == NULL)
        {
            __leave;
        }

        WaitForSingleObject(createdThread, INFINITE);
        success = true;

    }
    __finally { // Now, we can clean everything up
        // Free the remote memory that contained the DLL's pathname
        if (pszLibFileRemote != NULL)
            VirtualFreeEx(targetProcess, pszLibFileRemote, 0, MEM_RELEASE);
        if (createdThread != NULL)
            CloseHandle(createdThread);
        if (targetProcess != NULL)
            CloseHandle(targetProcess);
    }

    return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
    PCWSTR srcDll = L"test.dll"; //dll in the same directory as the injector.exe, its code is specified below.
    DWORD processID = "768"; //Hard coded process ID of a running calc.exe. When I change this line to GetCurrentProcessId() the messagebox from my dll shows.      
    if (Inject(processID, srcDll))
    {
        std::cout << "Injection successful" << std::endl;
        Eject(processID, srcDll); //This detaches the dll by calling freelibrary from a remote thread. This function was omitted from this response to keep things relavent.
    }
    system("PAUSE");
    return 0;
}

下面是我的简单helloworld test.dll的代码:

代码语言:javascript
复制
#include "stdafx.h"
#include <Windows.h>
#include <tchar.h>
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
        break;
    case DLL_THREAD_ATTACH:
        MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
        break;
    case DLL_THREAD_DETACH:
        MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
        break;
    case DLL_PROCESS_DETACH:
        MessageBox(NULL, L"HULLO.", L"DLL", MB_OK);
        break;
    }
    return TRUE;
}

已解决:注入的dll的目录必须指定为相对于目标进程的目录,或者指定为完整路径,以便目标进程可以找到它。(我把它放在Injector的目录中,这是导致加载问题的原因-- calc不知道它在哪里。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-18 19:53:48

代码语言:javascript
复制
PCWSTR srcDll = L"test.dll"; //dll in the same directory as the injector.exe

因为您是在目标程序中执行LoadLibraryW(),而不是在注入器中执行,所以它不知道什么是“与注入器相同的目录”-它只是搜索它的in standard directories documented on MSDN

您需要传递完整路径,而不是相对路径。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13438812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档