How to call specific function in dll injection?

蓝咒 提交于 2019-12-04 10:04:02

When your injected DLL's DllMain runs for the first time, call CreateThread to create a new thread that can do whatever you like. Note that you cannot call arbitrary code from DllMain as described in the documentation. Hence the call to CreateThread from DllMain.

Well, I'm using the following approach.

In the DLL that is being injected, I create a shared section, like this:

#pragma data_seg(".MyShared")

LPTHREAD_START_ROUTINE g_lpMyFunc = NULL;

#pragma data_seg()
#pragma section(".MyShared", read, write, shared)

The shared section variable g_lpMyFunc is then initialized inside DllMain like this:

BOOL APIENTRY DllMain(HMODULE, DWORD dwReasonForCall, LPVOID)
{
    if (NULL != GetModuleHandle(_T("MyApp.exe")))
    {
        if (DLL_PROCESS_ATTACH == dwReasonForCall)
        {
            g_lpMyFunc = (LPTHREAD_START_ROUTINE)&MyFunc;
        }
        else if (DLL_PROCESS_DETACH == dwReasonForCall)
        {
            g_lpMyFunc = NULL;
        }
    }
    return TRUE;
}

This code does the following. The function call GetModuleHandle tries to get MyApp's executable module handle. If it succeeds, it return non-NULL value and that means that the injected DLL's DllMain is called from the remote process. If it's the case, the address of MyFunc is saved to g_lpMyFunc shared variable. And if the DLL is detached from the process (when it exits, for example), I set g_lpMyFunc to NULL in order to not be able to call a function by remote address that is not there.

I then create an external function MyFuncExtern that calls MyFunc in the remote process like this:

extern "C" __declspec(dllexport) bool __cdecl MyFuncExtern(HANDLE hProcess)
{
    if (NULL == g_lpMyFunc)
    {
        return false;
    }

    return NULL != CreateRemoteThread(hProcess, NULL, 0, g_lpMyFunc, NULL, 0, NULL);
}

It is a very simplified version, but it shows the main concept: if g_lpMyFunc is not NULL, it creates a remote thread in hProcess (just like in your code) that calls a function at the address pointed to by g_lpMyFunc.

There are some limitations on that function though since CreateRemoteThread takes only one argument for the remote function (you can pass more, however it will need a significantly more complicated approach), and if you need a return value you will have to wait for remote thread to complete execution and get its exit code, that is a DWORD.

This approach is good at writing Initialize / Uninitialize functions and, moreover, it perfectly works for managed C++/CLI DLLs.

And of course you can use any other cross-process data storage to save the function pointer(s). Memory mapped files are one good example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!