2009-02-28 6 views
10

프로그래밍 방식을 사용하여 바이너리 DLL을 결정하는 방법은 무엇입니까?Windows 실행 파일 DLL 종속성을 프로그래밍 방식으로 확인하는 방법은 무엇입니까?

분명히하기 위해 실행중인 exec의 DLL 종속성을 확인하지는 않지만 임의의 exec (필수 DLL이 누락되었을 수 있음)를 확인하려고합니다. C/C++ 응용 프로그램에서 구현할 솔루션을 찾고 있습니다. 이것은 런타임에 내 응용 프로그램에서 수행해야하는 작업이며 타사 응용 프로그램 (예 : 의존)에서 수행 할 수 없습니다.

+0

확인이 [질문] (http://stackoverflow.com/questions/362560/how-do-i-detect-the-dlls-required-by-an-application). – alex2k8

답변

9

IMAGE_LOAD_FUNCTION API를 살펴보십시오. PE 파일의 다양한 섹션에 액세스하는 데 사용할 수있는 LOADED_IMAGE 구조체에 대한 포인터를 반환합니다.

구조가 배열 된 방법을 설명하는 기사는 herehere입니다. 기사 here의 소스 코드를 다운로드 할 수 있습니다.

나는 이것이 당신에게 필요한 모든 것을 제공한다고 생각합니다.

업데이트 :

난 그냥 기사의 소스 코드를 다운로드했습니다. EXEDUMP.CPP을 열어 DumpImportsSection을 보면 필요한 코드가 있어야합니다.

+0

제안 해 주셔서 감사합니다. 특히 소스 예제에 대한 링크. 정확히 내가 무엇을 찾고 있었는지. –

6

확인할 수 없습니다. 적어도 많은 노력을 기울이지 않아도됩니다. 바이너리는 LoadLibrary를 호출하여 DLL을로드 할 수 있습니다. LoadLibrary에 대한 모든 호출 코드를 스캔하더라도 라이브러리를 식별하는 데 사용 된 문자열을 판별해야합니다. 동적 메모리에서 문자열이 배치 된 위치를 추적하면 해결하려는 것보다 더 어려워 질 것입니다.

+1

왜 나를 여기 투표 하죠? 이 답변은 제가 말할 수있는 한 기술적으로 정확합니다. –

+0

이 답변이 투표 된 이유에 대한 내 추측은 : 암시 적 종속성 (alex2k8의 링크 참조)과 명시 적 종속성 (어떤 내용인지)을 구분하지 않습니다. 우울하지 마십시오. 대답은 반쯤 맞았습니다! – jdigital

+0

@jdigital :이 답변은 반갑지 않습니다. 실행 가능한 이미지의 모든 종속성을 프로그래밍 방식으로 찾는 질문에 대한 정답입니다. 일반적인 경우를 묻는 질문은 COM 객체를 인스턴스화 할 때'LoadLibrary' 또는 암시 적으로로드 된 모듈을 사용하여 런타임 동적 연결을 고려해야합니다. Dependency Walker에는 프로파일 링 모드가 있습니다.이 모드는 런타임에로드되는 바이너리를 고려하지만 100 % 코드 적용 범위를 보장 할 수는 없으므로 해당 시도가 수행하지 않습니다. 좋든 싫든, 이것은 정답입니다. – IInspectable

1

간단히 말해 실행 파일에서 사용하는 각 DLL에 대해 수입 섹션을 스캔해야합니다. 그런 다음 모든 종속성을 찾을 때까지 반복적으로 각 DLL을 찾고 스캔합니다.

물론 응용 프로그램은 필수 또는 선택적 기능을 위해 LoadLibrary 기능 패밀리를 사용할 수 있습니다. 이 방법으로는 감지되지 않습니다.

-1

물론 가능합니다. 이

Win32 api Group에 연령대에 심지어는 Win32 자주 묻는 질문이다 => DBAPIs

0

어떻게 당신을 위해 모든 정보를 계산하고 배열로 답을 다시 전달하기 위해 호출 할 수있는 DLL에 대한과 몇 줄의 코드 CStrings?

PE Format DLL이 작업을 수행 할 수 있습니다. 소스 코드와 함께 제공되며 GPL 제한이 없습니다. PE 파일 탐색기는 소스 (GPL 없음)와 함께 제공된 DLL을 사용하는 GUI 응용 프로그램입니다.

4

76 라인은 그 pedump 코드를 기반으로 (의존성으로 Imagehlp.lib을 추가하는 것을 잊지 마세요)해야 할 일 :

#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 프로파일 메뉴를 사용하여이 작업을 수행 할 수 있습니다, 당신은 목표 실행 파일이있는 경우 . 실행 파일을로드하고 프로파일 링을 시작하도록 지시하면 프로그램을 실행하는 동안로드 된 모든 모듈이 나열됩니다.

Dependency Walker FAQ (first question...)

+0

프로파일 링은 이러한 모듈의 로딩 만보고 트리거 할 수 있습니다. 100 % 코드 커버리지를 보장 할 수 없다면 모든 의존성을 찾을 수 없습니다. 또한 프로그램에서 엄격하게 요구하지 않는로드 된 모듈 (예 : 파일 저장 대화 상자를 열 때 쉘 확장자)을 볼 수 있습니다. – IInspectable