5

作成したインジェクトされた 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);

しかし、それはクラッシュを引き起こします。

どうすればこれを解決できますか?

4

2 に答える 2

13

あなたが持っているように呼び出す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;
}

これはすべて、私が持っている古いプロジェクトから切り取ったコードです。コードを手に入れて、それを使って好きなことをするのは大歓迎ですが、今コードを書き直すとしたら、多くのことを別の方法で行うことになることはわかっています。

于 2012-04-07T21:40:21.340 に答える