判断dll / exe是否为托管(managed / unmanaged)

由于软件下发、部署的考虑,我们可能会对托管/非托管的dll采用不同的更新策略。

1、.NET方式
通过Assembly类的LoadFrom 、LoadFile均可, 异常为BadImageFormatException ,则基本可以判断是非托管dll/exe
(也存在硬修改为.dll或.exe的可能)

2、COM方式
http://www.codeguru.com/cpp/w-p/dll/openfaq/article.php/c14001/

BOOL IsManaged(LPTSTR lpszImageName)
{
   BOOL bIsManaged 
= FALSE;    //variable that indicates whether
                               
//managed or not.
   TCHAR szPath[MAX_PATH];     //for convenience

   HANDLE hFile 
= CreateFile(lpszImageName, GENERIC_READ,
                             FILE_SHARE_READ,NULL,OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,NULL);

   
//attempt the standard paths (Windows dir and system dir) if
   
//CreateFile failed in the first place.
   if(INVALID_HANDLE_VALUE == hFile)
   
{
      
//try to locate in Windows directory
      GetWindowsDirectory(szPath,MAX_PATH);
      _tcscat(szPath,_T(
"\\"));
      _tcscat(szPath,lpszImageName);
      hFile 
= CreateFile(szPath, GENERIC_READ, FILE_SHARE_READ,
                         NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
                         NULL);
   }


   
if(INVALID_HANDLE_VALUE == hFile)
   
{
      
//try to locate in system directory
      GetSystemDirectory(szPath,MAX_PATH);
      _tcscat(szPath,_T(
"\\"));
      _tcscat(szPath,lpszImageName);
      hFile 
= CreateFile(szPath, GENERIC_READ, FILE_SHARE_READ,
                         NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
                         NULL);
   }


   
if(INVALID_HANDLE_VALUE != hFile)
   
{
      
//succeeded
      HANDLE hOpenFileMapping = CreateFileMapping(hFile,NULL,
                                                  PAGE_READONLY,
0,
                                                  
0,NULL);
      
if(hOpenFileMapping)
      
{
         BYTE
* lpBaseAddress = NULL;

         
//Map the file, so it can be simply be acted on as a
         
//contiguous array of bytes
         lpBaseAddress = (BYTE*)MapViewOfFile(hOpenFileMapping,
                                              FILE_MAP_READ,
0,0,0);

         
if(lpBaseAddress)
         
{
            
//having mapped the executable, now start navigating
            
//through the sections

            
//DOS header is straightforward. It is the topmost
            
//structure in the PE file
            
//i.e. the one at the lowest offset into the file
            IMAGE_DOS_HEADER* pDOSHeader =
               (IMAGE_DOS_HEADER
*)lpBaseAddress;

            
//the only important data in the DOS header is the
            
//e_lfanew
            
//the e_lfanew points to the offset of the beginning
            
//of NT Headers data
            IMAGE_NT_HEADERS* pNTHeaders =
               (IMAGE_NT_HEADERS
*)((BYTE*)pDOSHeader +
               pDOSHeader
->e_lfanew);

            
//store the section header for future use. This will
            
//later be need to check to see if metadata lies within
            
//the area as indicated by the section headers
            IMAGE_SECTION_HEADER* pSectionHeader =
               (IMAGE_SECTION_HEADER
*)((BYTE*)pNTHeaders +
               
sizeof(IMAGE_NT_HEADERS));

            
//Now, start parsing
            
//First of all check if it is a PE file. All assemblies
            
//are PE files.
            if(pNTHeaders->Signature == IMAGE_NT_SIGNATURE)
            
{
               
//start parsing COM table (this is what points to
               
//the metadata and other information)
               DWORD dwNETHeaderTableLocation =
                  pNTHeaders
->OptionalHeader.DataDirectory
                  [IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].
                  VirtualAddress;

               
if(dwNETHeaderTableLocation)
               
{
                  
//.NET header data does exist for this module;
                  
//find its location in one of the sections
                  IMAGE_COR20_HEADER* pNETHeader =
                     (IMAGE_COR20_HEADER
*)((BYTE*)pDOSHeader +
                     GetActualAddressFromRVA(pSectionHeader,
                     pNTHeaders,dwNETHeaderTableLocation));

                  
if(pNETHeader)
                  
{
                     
//valid address obtained. Suffice it to say,
                     
//this is good enough to identify this as a
                     
//valid managed component
                     bIsManaged = TRUE;
                  }

               }

            }

            
else
            
{
               cout 
<< "Not PE file\r\n";
            }

            
//cleanup
            UnmapViewOfFile(lpBaseAddress);
         }

         
//cleanup
         CloseHandle(hOpenFileMapping);
      }

      
//cleanup
      CloseHandle(hFile);
   }

   
return bIsManaged;
}




posted @ 2008-06-13 10:50  蜡笔小王  阅读(808)  评论(0)    收藏  举报