web-dev-qa-db-ja.com

DLLの名前を変更しても、EXEがそれを見つけられるようにするにはどうすればよいですか?

DLLは社内で作成され、スタブの静的LIBが関連付けられています。

DLLのLIBファイルに静的にリンクする簡単な方法を使用して(つまり、LoadLibraryを手動で使用せずに)これを使用するEXEもありますDLL。

EXEを展開するとき、難読化の理由で(顧客の要求に応じて)、DLLファイル名を変更する必要があります)。

EXEがDLLを自動的に検出するようにするにはどうすればよいですか?

DLLファイルとLIBファイル(通常の名前にビルドされた後)の名前を変更してから、EXEプロジェクトの設定を変更して、名前が変更されたLIBにリンクしようとしました。これは実行時に失敗します。 DLLの名前はLIBファイルに焼き付けられており、「。lib」を「.dll」に置き換えるリンカーによって単純に推測されるのではありません。

一般に、この難読化をDLLのすべての用途に適用する必要はないため、現在のDLLプロジェクト出力ファイルはそのままにしておきます。

DLLのLIBファイルを編集し、ハードコードされたDLLファイルの名前を別のものに置き換えることができる方法があることを望んでいます。その場合、これは完全に内で行うことができます。 EXEプロジェクト(おそらくビルド前のステップとして)。


Update:私のDLLにはエクスポートされたC++クラスが含まれているため、遅延ロードが機能しないことがわかりました。 この記事

代替手段はありますか?

22
pauldoo

これが素晴らしい代替アプローチです:遅延読み込み

アプリケーションをビルドするときは、元のDLL name)と同じようにすべてをリンクします(ただし、元のdllを遅延ロードするように設定します)。

次に、顧客の要求に応じて名前を変更したDLLをデプロイします。

EXEは、名前が変更されたバージョンではなく元の名前を使用してDLLを見つけようとします。そのため失敗しますが、読み込みが遅れると、この失敗をインターセプトして名前を変更したバージョンを自分で読み込み、ネイティブを使用できます。 Windowsローダーは何も変更されていないかのようにすべてを解決します。

記事 遅延ロードされたDLLのリンカサポート を読み、 遅延フックの例 を参照してください。

遅延フックは次のようになります。

FARPROC WINAPI delayHook( unsigned dliNotify, PDelayLoadInfo pdli )
{
    switch( dliNotify )
    {
        case dliNotePreLoadLibrary:
            if( strcmp( pdli->szDll, "origional.dll" ) == 0 )
                return (FARPROC)LoadLibrary( "renamed.dll" );
            break;
        default:
            return NULL;
    }

    return NULL;
}
18
QAZ

LIBツール(Visual Studioに含まれています)を使用して、defファイルからlibファイルを生成できます。 dllソースにdefファイルが含まれていないと仮定すると、最初にdefファイルを作成する必要があります。あなたはあなたを助けるためにdumpbinを使うことができます。例えば: dumpbin /exports ws2_32.dll

出力には、エクスポートされた関数の名前が表示されます。次に、次のようなdefファイルを作成します。

LIBRARY WS2_32
EXPORTS
    accept      @1
    bind        @2
    closesocket @3
    connect     @4

@numberは、dumpbin出力の序数です。

使用する LIB /MACHINE:x86 /def:ws2_32.deflibファイルを生成します。

これで、defファイルを簡単に変更し、dllの名前を変更するたびに新しいlibfileを生成できます。

dumpbinを使用してlibfileを検証できます:dumpbin /exports ws2_32.lib。元のlibファイルと同じ出力が得られるはずです。

16

あなたの顧客は酔っていますか?すべての世界のすべてのクレイジーな要件の中で...

梅毒の狂人の真夜中のC++プログラマーとしての栄光の時代に、私はDLLをリソースとして.exeファイルに追加していました。次に、起動時にそれらを解凍し、exeのディレクトリに書き込みます。プログラムは、この時点でDLLファイル名を決定できます。実際には難読化を行います。乱数から始めて、Edward Learの詩を連結し、お気に入りのドイツ語の二重名詞とxorします。 ;とにかく初心者のために行う必要があります。次に、LoadLibrary()を使用してDLLをロードします。

enum ukOverwrite {dontOverwriteAnything = 0, overwriteWhateverPresent = 1};
void unpackResource (ukOverwrite param1, int resourceID, const char* basePath,  
const char* endFilename)
{
  char* lpName = 0;
  lpName += resourceID;
  HRSRC MrResource = FindResource (0, lpName, "file");

  if (MrResource)
  {
    HGLOBAL loadedResource = LoadResource (0, MrResource);
    if (loadedResource)
    {
      void* lockedResource = LockResource (loadedResource);
      if (lockedResource)
      {
        DWORD size = SizeofResource (0, MrResource);
        if (size)
        {
          unsigned long creationDisposition = CREATE_NEW;
          if (param1 == overwriteWhateverPresent)
            creationDisposition = CREATE_ALWAYS;

          char filepath [MAX_PATH];
          strcpy (filepath, basePath);
          strcat (filepath, endFilename);
          HANDLE rabbit = CreateFile (filepath, GENERIC_WRITE, 0, 0,  
creationDisposition, 0, 0);
          if (rabbit != INVALID_HANDLE_VALUE)
          {
            DWORD numBytesWritten = 0;
            int wf = WriteFile (rabbit, lockedResource, size, &numBytesWritten,  
0);
            CloseHandle (rabbit);
          }
        }
      }
      FreeResource (loadedResource);
    }
  }
}
7
Philip Morant

ネイティブdllの名前を正しく変更するための小さなpythonスクリプトを作成しました。これにより、MSVCのプロジェクトリンクで使用する新しいlibファイルが生成されます。

https://github.com/cmberryau/rename_dll/blob/master/rename_dll.py

もちろん、それを機能させるには、開発者コマンドプロンプトを使用する必要があります。

5
Chris Berry
  1. LoadLibrary(レジストリから新しい名前を読み取る)を使用することは1つのオプションです。
  2. Visual Studioプロジェクトの名前を一般化された名前に変更できます(顧客はこれに異議を唱えません)。
  3. DLL自体の名前を変更する必要がありますが、ライブラリにはまだ古い名前が付いていますか?DUMPBIN/ALL * .lib>ファイルを使用して相互検証しましたか?古いDLL名前。まだありますか?プロジェクトの* .defファイルを確認してください。ライブラリの名前を「OLDNAME」に変更しましたか。

それ以外の場合、LIBが古いDLL名を保持する理由はありません。

0
Woods