DLL注入:在dll中调用一个函数

时间:2012-08-17 16:51:31

标签: winapi dll dll-injection

首先,代码的某些部分来自Calling function in injected DLL,但某处不起作用。

我有一个关于DLL注入的问题:在我将库加载到另一个进程之后:

HANDLE InjectDLL(DWORD ProcessID, char *dllName)
{
    HANDLE Proc;
    char buf[50]={0};
    LPVOID RemoteString, LoadLibAddy;

    if(!ProcessID)
        return NULL;

    Proc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, ProcessID);

    if(!Proc)
    {
        sprintf(buf, "OpenProcess() failed: %d", GetLastError());
        MessageBox(NULL, buf, "Loader", NULL);
        return NULL;
    }

    LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");

    RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(Proc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL);
    HANDLE hThread = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);   

    if( hThread != 0 ) {
        WaitForSingleObject( hThread, INFINITE );
        GetExitCodeThread( hThread, ( LPDWORD )&hInjected );
        CloseHandle( hThread );
    }

    CloseHandle(Proc);

    return  hThread != 0 ? Proc : NULL;
}

我想从该空间内调用一个函数:

void* GetPayloadExportAddr( LPCSTR lpPath, HMODULE hPayloadBase, LPCSTR lpFunctionName ) 
{
    // Load payload in our own virtual address space
    HMODULE hLoaded = LoadLibrary( lpPath );

    if( hLoaded == NULL ) {
        return NULL;
    } else {
        void* lpFunc   = GetProcAddress( hLoaded, lpFunctionName );
        DWORD dwOffset = (char*)lpFunc - (char*)hLoaded;

        FreeLibrary( hLoaded );
        return (void*)((DWORD)hPayloadBase + dwOffset);
    }
}

BOOL InitPayload( HANDLE hProcess, LPCSTR lpPath, HMODULE hPayloadBase) 
{   
    void* lpInit = GetPayloadExportAddr( lpPath, hPayloadBase, "Start" );
    if( lpInit == NULL ) {
        return FALSE;
    }
    else {
        HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
            (LPTHREAD_START_ROUTINE)lpInit, (LPVOID) NULL, 0, NULL );

        if( hThread == NULL ) {
          return FALSE;
        } 
        else {
          CloseHandle( hThread );
        }
      }
    return TRUE;
}

GetPayloadExportAddr从IDA返回当前位置(我猜这是我的函数开始的空间)。

所以当我尝试创建新线程时问题出现在InitPayload函数上,它没有这样做,我不知道为什么。

我的dll如下:

extern "C"
{
    __declspec(dllexport) void* Start(LPVOID param)
    {
        MessageBox(NULL, L"Start", L"Hello", MB_OK);
        return NULL;
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

问题是,如果我把Start方法放在DLL_PROCESS_ATTACH它可以工作,但否则它没有。

1 个答案:

答案 0 :(得分:0)

您的GetPayloadExportAddr()返回您本地进程中函数的地址。如果模块的基址不同,则该地址在其他进程中将是不同的,这对于DLL文件是常见的,如果DLL文件的PreferredImageBase不可用,则可以重新定位。

您应该修改GetPayloadExportAddr()函数以返回偏移量。然后在目标进程中获取模块的地址。将这两个加在一起,这是您在目标进程中调用的正确地址。