在注入DLL调用函数(Calling function in injected DLL)

2019-06-23 11:06发布

我想调用一个函数在我做了一个DLL注入的远程进程。

我已经成功地注入我的DLL有:

CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"), "LoadLibraryA"), pLibRemote, 0, NULL);

该DllMain的执行和DLL是在待机模式下运行。 我想这样做是有点调用远程加载的DLL,以做一些工作。

我曾尝试导出这样的功能:

extern "C" __declspec(dllexport) void MyFunc(void)

然后执行这样的功能:

CreateRemoteThread(pHandle, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("mydll"), "MyFunc"), NULL, 0, NULL);

但它会导致崩溃。

我该如何解决这个问题?

Answer 1:

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

理论上

  1. 注入DLL到目标进程,并让它在装载基址
  2. 注入DLL到当前进程。 使用GetProcAddress发现导出的函数和DLL的底座之间的偏移。
  3. 添加该偏移从步骤1中获得的基地址CreateRemoteThread在该位置。

在实践中

如果做你的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 );
}

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

这样做是第一次加载载荷到我们自己的虚拟地址空间。 之后,我们可以使用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;
}

这是拆出来的所有代码, 旧的项目我有 。 欢迎您乘坐代码,做你想做的事情不管,但我知道,如果我现在要重写代码,我会做很多不同的事情。



Answer 2:

小李的回答工作,如果你是注入DLL 32位到32位进程。

如果要注入DLL 64位到64位的过程中,你不能获得DLL的基址GetExitCodeThread ,因为它只会给你的64位地址的低32位。

为了获得在这种情况下,正确的地址,您必须编写的代码到调用进程LoadLibrary (存储在处理内存中的特定位置的结果),执行的代码块(使用CreateRemoteThread ),然后读回从使用位置的地址ReadProcessMemory

你可以找到更多细节在这里(包括PowerShell和ASM代码)在这里: http://clymb3r.wordpress.com/2013/05/26/implementing-remote-loadlibrary-and-remote-getprocaddress-using-powershell-and -部件/

然后,您可以计算偏移量导出的函数一样迈克介绍,但要小心存放在64位值的差异,而不是在一个DWORD(这是32位)。



文章来源: Calling function in injected DLL