在注入的DLL中调用函数

And*_*dré 5 c++ dll-injection

我想在我已经注入的DLL的远程进程中调用一个函数.

我已成功注入我的DLL:

CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"), "LoadLibraryA"), pLibRemote, 0, NULL);
Run Code Online (Sandbox Code Playgroud)

执行DllMain并且DLL以待机模式运行.我想做的是以某种方式调用远程加载的DLL,以便做一些工作.

我试过导出这样的函数:

extern "C" __declspec(dllexport) void MyFunc(void)
Run Code Online (Sandbox Code Playgroud)

然后执行这样的函数:

CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("mydll"), "MyFunc"), NULL, 0, NULL);
Run Code Online (Sandbox Code Playgroud)

但它会导致崩溃.

我怎么解决这个问题?

Mik*_*wan 13

调用GetModuleHandle你将获得DLL的基础,因为它映射到你的进程(如果有的话).所以你需要做的是首先确保导出DLL中的函数.你可以做你做或创建一个.def文件,如这里.此后:

理论上

  1. 将DLL注入目标进程并获取其加载的基址
  2. 将DLL注入当前进程.使用GetProcAddress发现导出的函数和DLL的底座之间的偏移.
  3. 将此偏移量添加到从此CreateRemoteThread位置的步骤1获得的基址.

在实践中

在进行DLL注入时,您可以获得将DLL加载到目标中的基础.

HMODULE hInjected;

hThread = CreateRemoteThread( hProcess, NULL, 0,
      (LPTHREAD_START_ROUTINE)( GetProcAddress( hMod,
      "LoadLibraryW" ) ), lpAddress, 0, NULL );

// Locate address our payload was loaded
if( hThread != 0 ) {
  WaitForSingleObject( hThread, INFINITE );
  GetExitCodeThread( hThread, ( LPDWORD )&hInjected );
  CloseHandle( hThread );
}
Run Code Online (Sandbox Code Playgroud)

hInjected将是注入的DLL的基础.然后我有另一个功能:

void* GetPayloadExportAddr( LPCWSTR 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 (DWORD)hPayloadBase + dwOffset;
  }
}
Run Code Online (Sandbox Code Playgroud)

这样做首先将有效负载加载到我们自己的虚拟地址空间中.之后,我们可以使用GetProcAddress获取导出函数的地址.从这里,我们可以从DLL的基础获得函数的偏移量.将此偏移添加到hInjected我们之前得到的将告诉我们CreateRemoteThread应该在哪里进行调用.所以你可以像这样打电话:

BOOL InitPayload( HANDLE hProcess, LPCWSTR lpPath, HMODULE hPayloadBase, HWND hwndDlg ) {
  void* lpInit = GetPayloadExportAddr( lpPath, hPayloadBase, "Init" );
  if( lpInit == NULL ) {
    return FALSE;
  } else {
    HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0,
        lpInit, hwndDlg, 0, NULL );

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

  return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

这是从我拥有旧项目中删除的所有代码.欢迎你接受代码并随心所欲地做任何事情,但我知道如果我现在要重写代码,我会做很多不同的事情.