管道可以用于在不同的进程中共享Dll吗?

时间:2010-07-27 05:36:07

标签: dll winapi process hook

在我开始讨论我的问题之前,让我解释一下我正在做什么。我有一个主进程说ProcessA,我已经连接ProcessA并且还将dll(比如myDll.dll)注入ProcessA.Now的进程空间。在某一点上,ProcessA启动另一个进程,即ProcessB。进程A和B处于完全不同的进程内存空间。我想在ProcessB中共享myDll.dll(插入processA sapce)(实际上是ProcessB的processSpace)。可以使用管道线方法或任何其他合适的方法完成。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

DLL的代码将由不同的进程自动共享。仅用于优化,您应该选择DLL的良好基址(请参阅http://msdn.microsoft.com/en-US/library/f7f5138s.aspx)。

要在流程之间共享数据,您可以使用共享内存对象,或者只需将需要共享的一些变量放置到标记为共享的部分(有关详细信息,请参阅http://support.microsoft.com/kb/100634http://msdn.microsoft.com/en-us/library/h90dkhs0.aspx) 。要将“.SHAREDSECTIONNAME”部分标记为已共享,您可以使用

#pragma comment(linker, "/section:.SHAREDSECTIONNAME,RWS")

要在共享内存中写入/读取时没有冲突,您应该使用命名的事件或互斥锁,就像在所有其他多进程通信情况下一样。

根据评论

更新:如果您自己创建子流程,则会收到具有完全权限的子流程的句柄。因此,您有足够的权利在CreateRemoteThread API方面进行DLL感染。这是C中的一个工作代码,它启动CMD.EXE并在地址空间中注入一个MyTest.dll:

#include <Windows.h>

int main()
{
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = {0};
    TCHAR szCommandLine[4096] = TEXT("CMD.EXE");
    BOOL bIsSuccess;
    DWORD dwStatus;
    LPCTSTR pszLibFile = TEXT("C:\\Oleg\\MyTest\\Release\\MyTest.dll");
    PTSTR pszLibFileRemote = NULL;
    HANDLE hThread = NULL;
    int cb;
    HMODULE hModule = NULL;

    bIsSuccess = CreateProcess (NULL, szCommandLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);

    // Calculate the number of bytes needed for the DLL's pathname
    cb  = (1 + lstrlen(pszLibFile)) * sizeof(TCHAR);

    __try {
        PTHREAD_START_ROUTINE pfnThreadRtn;

        // Allocate space in the remote process for the pathname
        pszLibFileRemote = (PTSTR) VirtualAllocEx (pi.hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
        if (pszLibFileRemote == NULL) __leave;  // error

        // Copy the DLL's pathname to the remote process's address space
        if (!WriteProcessMemory (pi.hProcess, pszLibFileRemote, (PVOID) pszLibFile, cb, NULL)) __leave;

        // Get the real address of LoadLibraryW in Kernel32.dll
        // Real address of Kernel32.dll in dwProcessId and in our Process MUST be the same !!!
        // Remote Process MUST have Kernel32.dll loaded (SMSSS.EXE and System havn't)!!!
#ifdef UNICODE
        pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress (GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
#else
        pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress (GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");
#endif
        if (pfnThreadRtn == NULL) __leave;

        // Create a remote thread that calls LoadLibraryW(DLLPathname)
        hThread = CreateRemoteThread (pi.hProcess, NULL, 0, pfnThreadRtn, (LPVOID)pszLibFileRemote, 0, NULL);
        if (hThread == NULL) __leave;

        dwStatus = ResumeThread (pi.hThread);

        // Wait for the remote thread to terminate
        if (WaitForSingleObject (hThread, INFINITE) != WAIT_OBJECT_0) __leave;

        GetExitCodeThread (hThread, (PDWORD)&hModule);

        // hModule is the address in the destination process (CMD.EXE)
        // of the injected DLL
        // You can verify that it is really loaded for example with respect of 
        // Process Explorer (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx)
    }
    __finally {
        // Free the remote memory that contained the DLL's pathname
        if (pszLibFileRemote != NULL)
            bIsSuccess = VirtualFreeEx (pi.hProcess, pszLibFileRemote, 0, MEM_RELEASE);

        if (hThread != NULL)
            bIsSuccess = CloseHandle (hThread);

        if (pi.hProcess != NULL)
            bIsSuccess = CloseHandle (pi.hProcess);

        if (pi.hThread != NULL)
            bIsSuccess = CloseHandle (pi.hThread);
    }

    return 0;
}