2009-02-28 31 views
10

Làm thế nào để xác định nhị phân của DLL nào phụ thuộc vào việc sử dụng các phương thức lập trình?Làm thế nào để xác định một cửa sổ thực thi DLL phụ thuộc programatically?

Để rõ ràng, tôi không cố gắng xác định phụ thuộc DLL của exec đang chạy, nhưng của bất kỳ exec tùy ý nào (có thể thiếu một DLL bắt buộc). Tôi đang tìm một giải pháp để thực hiện trong một ứng dụng C/C++. Đây là một cái gì đó mà cần phải được thực hiện bởi ứng dụng của tôi tại thời gian chạy và không thể được thực hiện bởi một ứng dụng của bên thứ ba (như phụ thuộc).

+0

Kiểm tra này [câu hỏi] (http://stackoverflow.com/questions/362560/how-do-i-detect-the-dlls-required-by-an-application). – alex2k8

Trả lời

9

Hãy xem API IMAGE_LOAD_FUNCTION. Nó sẽ trả về một con trỏ đến một cấu trúc LOADED_IMAGE, mà bạn có thể sử dụng để truy cập vào các phần khác nhau của một tệp PE.

Bạn có thể tìm thấy một số bài viết mô tả cách cấu trúc được đặt ra herehere. Bạn có thể tải xuống mã nguồn cho các bài viết here.

Tôi nghĩ điều này sẽ cung cấp cho bạn mọi thứ bạn cần.

Cập nhật:

Tôi chỉ cần tải mã nguồn của bài viết. Nếu bạn mở EXEDUMP.CPP và xem DumpImportsSection, mã này cần có mã bạn cần.

+0

Cảm ơn bạn đã đề xuất. Đặc biệt là cho các liên kết đến các ví dụ nguồn. Chính xác những gì tôi đang tìm kiếm. –

6

Không thể xác định được. Ít nhất không phải không có nhiều công việc. Bất kỳ nhị phân có thể gọi LoadLibrary để tải một DLL. Ngay cả khi bạn đã quét mã cho tất cả các cuộc gọi đến LoadLibrary, bạn sẽ phải xác định chuỗi nào đang được sử dụng để ID thư viện. Theo dõi xuống trong bộ nhớ động, chuỗi đã được đặt sẽ khó hơn bạn muốn giải quyết.

+1

Tại sao tôi bỏ phiếu ở đây? Câu trả lời này là chính xác về mặt kỹ thuật theo như tôi có thể nói. –

+0

Tôi đoán tại sao câu trả lời này bị bỏ phiếu: nó không phân biệt giữa phụ thuộc ngầm (có thể xác định, xem liên kết của alex2k8) và phụ thuộc rõ ràng (đó là điều bạn đang nói). Đừng u ám, câu trả lời đúng một nửa! – jdigital

+0

@jdigital: Câu trả lời này không phải là một nửa. Đó là câu trả lời đúng cho một câu hỏi, yêu cầu lập trình tìm tất cả các phụ thuộc của một hình ảnh thực thi. Câu hỏi đặt ra là hỏi về trường hợp chung, vì vậy bạn phải tính đến liên kết thời gian chạy động, sử dụng 'LoadLibrary', hoặc các mô-đun được nạp ngầm, khi tạo một đối tượng COM. Phụ thuộc Walker có một chế độ lược tả, cố gắng tính toán các tệp nhị phân, được tải trong thời gian chạy, nhưng bạn không thể đảm bảo phạm vi mã 100%, do đó, ngay cả nỗ lực đó cũng không thực hiện được. Giống như nó hay không, đây là câu trả lời đúng. – IInspectable

1

Tóm lại, bạn cần phải quét tệp PE nhập khẩu cho mỗi DLL được thực thi bởi tệp thi hành. Sau đó đệ quy xác định vị trí và quét từng dll cho đến khi bạn đã tìm thấy tất cả các phụ thuộc.

Tất nhiên, ứng dụng có thể sử dụng dòng chức năng LoadLibrary cho chức năng bắt buộc hoặc tùy chọn. Điều đó sẽ không được phát hiện với phương pháp này.

-1

Tất nhiên điều đó có thể và dễ dàng! Đó là ngay cả một Win32 FAQ cho lứa tuổi trên Win32 api Group

=> một vài dòng mã với DBAPIs

0

Làm thế nào về một DLL mà bạn có thể gọi để tính toán tất cả các thông tin này cho bạn và vượt qua trở lại câu trả lời như một mảng của CStrings?

PE Format DLL có thể làm điều này cho bạn. Cung cấp mã nguồn, không có giới hạn GPL. PE File Explorer là một ứng dụng GUI sử dụng DLL, cũng được cung cấp với nguồn (không có GPL).

4

76 dòng để làm điều đó dựa trên pedump mã (đừng quên để thêm Imagehlp.lib như dependancy):

#include <stdio.h> 
#include "windows.h" //DONT REMOVE IT 
#include "ImageHlp.h" 
#include "stdafx.h" 

template <class T> PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, T* pNTHeader) // 'T' == PIMAGE_NT_HEADERS 
{ 
    PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader); 
    unsigned i; 

    for (i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++) 
    { 
     // This 3 line idiocy is because Watcom's linker actually sets the 
     // Misc.VirtualSize field to 0. (!!! - Retards....!!!) 
     DWORD size = section->Misc.VirtualSize; 
     if (0 == size) 
      size = section->SizeOfRawData; 

     // Is the RVA within this section? 
     if ((rva >= section->VirtualAddress) && 
      (rva < (section->VirtualAddress + size))) 
      return section; 
    } 

    return 0; 
} 

template <class T> LPVOID GetPtrFromRVA(DWORD rva, T* pNTHeader, PBYTE imageBase) // 'T' = PIMAGE_NT_HEADERS 
{ 
    PIMAGE_SECTION_HEADER pSectionHdr; 
    INT delta; 

    pSectionHdr = GetEnclosingSectionHeader(rva, pNTHeader); 
    if (!pSectionHdr) 
     return 0; 

    delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData); 
    return (PVOID) (imageBase + rva - delta); 
} 


void DumpDllFromPath(wchar_t* path) { 
    char name[300]; 
    wcstombs(name,path,300); 

    PLOADED_IMAGE image=ImageLoad(name,0); 

    if (image->FileHeader->OptionalHeader.NumberOfRvaAndSizes>=2) { 
     PIMAGE_IMPORT_DESCRIPTOR importDesc= 
      (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA(
       image->FileHeader->OptionalHeader.DataDirectory[1].VirtualAddress, 
       image->FileHeader,image->MappedAddress); 
     while (1) 
     { 
      // See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR 
      if ((importDesc->TimeDateStamp==0) && (importDesc->Name==0)) 
       break; 

      printf(" %s\n", GetPtrFromRVA(importDesc->Name, 
              image->FileHeader, 
              image->MappedAddress)); 
      importDesc++; 
     } 
    } 
    ImageUnload(image); 

} 

//Pass exe or dll as argument 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DumpDllFromPath(argv[1]); 

    return 0; 
} 
1

Dependency Walker thể làm điều này bằng cách sử dụng các hồ sơ trình đơn, nếu bạn có một mục tiêu thực thi . Chỉ cần tải tệp thực thi, yêu cầu nó bắt đầu lược tả và nó sẽ liệt kê tất cả các mô-đun được tải trong khi thực hiện chương trình.

Dependency Walker FAQ (first question...)

+0

Hồ sơ chỉ thấy tải các mô-đun đó, mà bạn tình cờ kích hoạt. Trừ khi bạn có thể đảm bảo bảo hiểm mã 100%, bạn không thể chắc chắn tìm tất cả các phụ thuộc. Và sau đó bạn cũng sẽ thấy các mô-đun được tải, mà chương trình của bạn không yêu cầu nghiêm ngặt (ví dụ: tiện ích mở rộng vỏ khi mở hộp thoại Lưu tệp). – IInspectable

Các vấn đề liên quan