26

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

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

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

EXE が DLL を自動的に見つけられるようにするにはどうすればよいでしょうか。

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

一般に、この難読化を DLL のすべての使用に適用したくないため、現在の DLL プロジェクトの出力ファイルをそのまま維持したいと考えています。

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


更新: DLL にエクスポートされた C++ クラスが含まれているため、遅延読み込みが機能しないことがわかりました。この記事を参照してください。

代替手段はありますか?

4

6 に答える 6

19

LIB ツール (Visual Studio に含まれています) を使用すると、def ファイルから lib ファイルを生成できます。dll ソースに 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 ファイルと同じ出力が得られるはずです。

于 2008-11-11T10:45:06.707 に答える
19

これは良い代替アプローチです:読み込みを遅らせます。

アプリケーションをビルドするときは、元の DLL 名と同じようにすべてをリンクします (ただし、元の 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;
}
于 2008-11-11T14:25:49.460 に答える
7

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

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

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

于 2018-02-25T00:52:16.103 に答える
6

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

梅毒の狂人である真夜中の C++ プログラマーとしての栄光の日々に戻ると、私は自分の DLL をリソースとして .exe ファイルに追加していました。次に、起動時にそれらを解凍し、exe のディレクトリに書き込みます。この時点で、プログラムは DLL ファイル名を決定できます。実際に難読化を行ってください。乱数から始めて、エドワード・リアの詩をいくつか連結し、お気に入りのドイツ語の二重バレル名詞と 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);
    }
  }
}
于 2008-11-12T23:55:29.840 に答える
0
  1. LoadLibrary を使用する (レジストリから新しい名前を読み取る) は、1 つのオプションです。
  2. Visual Studio プロジェクトの名前を一般化された名前に変更できます (顧客は異議を唱えていません)。
  3. DLL 自体の名前を変更する必要があります。しかし、ライブラリはまだ古い名前を持っていますか? DUMPBIN /ALL *.lib > file を使用して相互検証しましたか。古い DLL 名を grep します。まだありますか?プロジェクトの *.def ファイルを確認してください。LIBRARY「OLDNAME」の名前を変更しましたか

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

于 2010-03-05T12:22:05.317 に答える
-2

Assembly.Load を使用し、難読化されたアセンブリ名を app.config に保存する必要があります。

それか、プラグインが使用するのと同じアプローチを使用します。アセンブリ内のクラスに、特定のディレクトリ内のすべてのアセンブリでアプリから検索するインターフェイスを実装させます。見つかった場合は、それをロートします。もちろん、インターフェイス名を難読化する必要はありません。

于 2008-11-11T10:23:57.327 に答える