2008-11-11 8 views
19

Chúng tôi có một DLL được sản xuất trong nhà, và chúng tôi có LIB tĩnh liên quan đến các sơ khai.Làm cách nào để đổi tên một DLL nhưng vẫn cho phép EXE tìm thấy nó?

Chúng tôi cũng có một EXE sử dụng DLL này bằng cách sử dụng phương pháp đơn giản liên kết tĩnh với tệp LIB của DLL (nghĩa là, không sử dụng LoadLibrary theo cách thủ công).

Khi chúng tôi triển khai EXE, chúng tôi muốn thay đổi tên tệp DLL vì lý do obfuscation (theo yêu cầu của khách hàng).

Làm cách nào để chúng tôi có thể thực hiện điều này để EXE của chúng tôi vẫn tìm thấy DLL tự động?

Tôi đã thử đổi tên tệp DLL và LIB (sau khi được xây dựng thành tên bình thường), sau đó thay đổi cài đặt dự án EXE để liên kết với LIB được đổi tên. Điều này không thành công trong thời gian chạy, vì tôi đoán tên của DLL được đưa vào tệp LIB và không chỉ đơn giản là do người liên kết thay thế ".lib" bằng ".dll".

Nói chung, chúng tôi không muốn áp dụng sự xáo trộn này cho tất cả việc sử dụng DLL, vì vậy chúng tôi muốn giữ các tệp đầu ra của dự án DLL hiện tại.

Tôi hy vọng rằng sẽ có một phương pháp theo đó chúng tôi có thể chỉnh sửa tệp LIB của DLL và thay thế tên được mã hóa cứng của tệp DLL bằng một thứ khác. Trong trường hợp này, điều này có thể được thực hiện hoàn toàn trong dự án EXE (có thể là một bước dựng sẵn).


Cập nhật: Tôi thấy rằng trễ Đang tải không hoạt động, như DLL của tôi chứa xuất khẩu lớp C++. Xem this article.

Có lựa chọn thay thế nào không?

Trả lời

-1

bạn sẽ phải sử dụng Assembly.Load và có tên lắp ráp bị xáo trộn được lưu trong app.config.

phương thức đó hoặc sử dụng cùng phương pháp mà plugin sử dụng. có một lớp trong assembly của bạn thực hiện một giao diện mà bạn tìm kiếm từ ứng dụng của bạn trong mỗi assembly trong một thư mục nào đó. nếu tìm thấy nó. tất nhiên bạn sẽ không làm xáo trộn tên Giao diện.

+0

Như các thẻ cho biết, điều này là dành cho một dự án gốc, do đó, các hội đồng không áp dụng. –

+0

oh đúng ... xấu của tôi. –

14

Sử dụng công cụ LIB (kèm theo studio trực quan), bạn có thể tạo tệp lib từ tệp def. Do nguồn dll của bạn không bao gồm tệp def, bạn phải tạo một tệp đầu tiên. Bạn có thể sử dụng dumpbin để hỗ trợ bạn. Ví dụ: dumpbin /exports ws2_32.dll

Trong đầu ra, bạn sẽ thấy tên của các hàm được xuất. Bây giờ tạo một file def như thế này:

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

Các @number là thứ trong đầu ra dumpbin

Sử dụng LIB /MACHINE:x86 /def:ws2_32.def để generete file lib.

Bây giờ bạn có thể dễ dàng sửa đổi tệp def và tạo một tệp libfile mới mỗi khi bạn đổi tên dll của mình.

bạn có thể xác minh libfile bằng cách sử dụng dumpbin: dumpbin /exports ws2_32.lib. Bạn sẽ nhận được kết quả tương tự như tệp lib gốc.

+0

Điều này dường như được viết ở đây bởi chính Microsoft: http://support.microsoft.com/kb/131313 – pauldoo

+0

Ngoài ra, ai đó đã tạo một tiện ích để tự động làm mọi thứ (http://www.geocities.com/SiliconValley/5806/ implib32.htm), nhưng nó rất cũ, và tôi không chắc nó vẫn đang làm việc với các trình biên dịch gần đây hơn. – wimh

15

Đây là một phương pháp thay thế tốt đẹp: trì hoãn tải.

Khi xây dựng ứng dụng của bạn, hãy liên kết tất cả như bạn làm với tên DLL ban đầu (nhưng đặt dll gốc sẽ được tải trễ).

Sau đó, bạn triển khai DLL được đổi tên theo yêu cầu của khách hàng.

EXE của bạn sẽ tìm cách định vị tệp DLL bằng tên gốc chứ không phải phiên bản đã đổi tên, sẽ không thành công, tuy nhiên với tải chậm trễ, bạn có thể chặn lỗi này và tải phiên bản đã đổi tên và sau đó có trình tải cửa sổ gốc giải quyết mọi thứ nếu không có gì thay đổi.

Đọc bài viết Linker Support for Delay-Loaded DLLs và xem Delay Hook example.

móc chậm trễ của bạn có thể giống như dưới đây:

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

Tôi gặp lỗi LNK1194 nếu thư viện của tôi chứa các lớp C++ đã xuất với vtables. http://msdn.microsoft.com/en-gb/library/w59k653y(VS.80).aspx http://www.tech-archive.net/Archive/VC/microsoft.public.vc.language/ 2004-09/0377.html – pauldoo

+2

Trong trường hợp nó giúp bất kỳ ai khác, [ví dụ này] (http://otb.manusoft.com/2013/01/using-delayload-to-specify-dependent-dll-path.htm) của cách tiếp cận trên đã được trình bày theo cách rất dễ dàng để tôi theo dõi. –

7

là khách hàng của bạn say rượu? Trong số tất cả các yêu cầu điên rồ trên toàn thế giới ...

Quay lại những ngày vinh quang của tôi với tư cách là một người lập trình C++ nửa đêm, tôi sử dụng để thêm các tệp DLL vào tệp .exe của tôi dưới dạng tài nguyên. Sau đó, lúc khởi động, tôi sẽ giải nén chúng và ghi chúng vào thư mục của exe. Chương trình của bạn có thể quyết định tên tệp DLL tại thời điểm này. Thực sự đi cho điều obfuscation - bắt đầu với một số ngẫu nhiên, nối một số thơ Edward Lear và xor nó với danh từ Đức đôi yêu thích của bạn; nên làm cho người mới bắt đầu anyway. Sau đó tải DLL bằng cách sử dụng LoadLibrary().

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); 
    } 
    } 
} 
0
  1. Sử dụng LoadLibrary (Đọc tên mới từ đăng ký) là một tùy chọn.
  2. Bạn có thể đổi tên dự án studio hình ảnh của mình thành tên chung (mà khách hàng của bạn không phản đối).
  3. Bản thân DLL cần được đổi tên. Nhưng lib vẫn mang tên cũ? Bạn đã vượt qua xác minh bằng cách sử dụng DUMPBIN/ALL * .lib> tập tin. grep cho tên DLL cũ. Nó vẫn còn đó? Kiểm tra tệp * .def trong dự án. Bạn đã đổi tên LIBRARY "OLDNAME"

Nếu không, không có lý do gì để LIB mang tên DLL cũ.

1

Tôi đã tạo một tập lệnh python nhỏ để đổi tên dll gốc một cách chính xác. Nó tạo ra một tệp lib mới để bạn sử dụng trong dự án liên kết trong MSVC.

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

Bạn sẽ cần sử dụng lời nhắc lệnh của nhà phát triển để nó hoạt động tất nhiên.