1
votes

First of all some parts of the code are from Calling function in injected DLL but somewhere it doesn't work.

I have a question regarding DLL Injection: after I loaded the library into another process:

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;
}

I wanted to call a function from inside that space:

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;
}

The GetPayloadExportAddr returns the Current Location from IDA (i guess that is the space where my function starts).

So the problem is at the InitPayload function when I try to create the new thread, it fails to do so and I don't know why.

My dll is the following:

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;
}

The thing is if I put the Start method at DLL_PROCESS_ATTACH it works, but otherwise it doesn't.

1
GetPayloadExportAddr may return a different address on different process due to module relocation. Meaning that DLL base address could be different across different process, so GetPayloadExportAddr should be called within the injected DLL, and not from a remote process.Jay

1 Answers

0
votes

Your GetPayloadExportAddr() returns the address of the function in your local process. This address will not be the same in other processes if the base address of the module is different, which is common with DLL files which can be relocated if their PreferredImageBase is not available.

You should modify your GetPayloadExportAddr() function to return the offset. Then get the address of the module in the target process. Add these two together and that is the correct address for you to call in the target process.