1

首先,代码的某些部分来自注入的 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;
}

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

所以问题出在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 上,它就可以工作,否则就不行。

4

1 回答 1

0

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

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

于 2020-03-28T21:51:25.593 回答