WEB开发网
开发学院软件开发VC 合并 DLL 阅读

合并 DLL

 2006-07-20 11:39:58 来源:WEB开发网   
核心提示: DWORD GetProcAddressDirectly(PIMAGE_DOS_HEADER dosHeader, char * FuncName){PIMAGE_NT_HEADERS pNTHeader;PIMAGE_EXPORT_DIRECTORY pExportDir;PWORD l
DWORD GetProcAddressDirectly(PIMAGE_DOS_HEADER dosHeader, char * FuncName) 
{
  PIMAGE_NT_HEADERS pNTHeader; 
  PIMAGE_EXPORT_DIRECTORY pExportDir; 
  PWORD lpNameOrdinals; 
  LPDWORD lpFunctions; 
  DWORD * lpName; 
  char * lpExpFuncName; 
  DWORD i; 
  DWORD j; 
  char * lpFuncName; 
  if(dosHeader->e_magic != IMAGE_DOS_SIGNATURE) return 0; 
  pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + dosHeader->e_lfanew); 
  if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) return 0; 
  if ((pNTHeader->FileHeader.SizeOfOptionalHeader != sizeof(pNTHeader->OptionalHeader)) || 
    (pNTHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)) 
    return 0; 
  DWORD exportsStartRVA, exportsEndRVA; 
  pImageBase = (PBYTE)dosHeader; 
  // Make pointers to 32 and 64 bit versions of the header. 
  pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,dosHeader->e_lfanew ); 
  exportsStartRVA = GetImgDirEntryRVA(pNTHeader,IMAGE_DIRECTORY_ENTRY_EXPORT); 
  exportsEndRVA = exportsStartRVA + 
    GetImgDirEntrySize(pNTHeader, IMAGE_DIRECTORY_ENTRY_EXPORT); 
  // Get the IMAGE_SECTION_HEADER that contains the exports. This is 
  // usually the .edata section, but doesn''t have to be. 
  PIMAGE_SECTION_HEADER header; 
  header = GetEnclosingSectionHeader( exportsStartRVA, pNTHeader ); 
  if ( !header ) return 0; 
  INT delta; 
  delta = (INT)(header->VirtualAddress - header->PointerToRawData); 
  pExportDir = (PIMAGE_EXPORT_DIRECTORY)GetPtrFromRVA(exportsStartRVA,
        pNTHeader, pImageBase); 
  pExportDir =(PIMAGE_EXPORT_DIRECTORY) (pNTHeader->
  OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 
  if (pExportDir == 0) 
  {
    MessageBox(NULL,"Error in GetProcAddressDirectly()",0,0); 
    return 0; 
  }
  pExportDir =(PIMAGE_EXPORT_DIRECTORY) ((DWORD)pExportDir + (DWORD)dosHeader); 
  lpNameOrdinals =(PWORD)((DWORD)pExportDir->AddressOfNameOrdinals + (DWORD)dosHeader); 
  lpName =(LPDWORD) (pExportDir->AddressOfNames + (DWORD)dosHeader); 
  lpFunctions =(LPDWORD) (pExportDir->AddressOfFunctions + (DWORD)dosHeader); 
  lpFuncName = FuncName; 
  if(HIWORD(lpFuncName)!=0 ) 
  {
    for( i = 0;i<=pExportDir->NumberOfFunctions - 1;i++) 
    {
      DWORD entryPointRVA = *lpFunctions; 
      // Skip over gaps in exported function 
      if ( entryPointRVA == 0 ) continue;
      for( j = 0;j<=pExportDir->NumberOfNames-1;j++) 
      {
        if( lpNameOrdinals[j] == i) 
        {
          lpExpFuncName = (char *) (lpName[j] +
              (DWORD)dosHeader); 
          if(strcmp((char *)lpExpFuncName,(char *)FuncName)==0) 
            return (DWORD) (lpFunctions[i] +
                (DWORD)dosHeader); 
        }
      }
    }
  }
  else
  {
    for (i = 0 ;i<=pExportDir->NumberOfFunctions - 1;i++) 
    {
      if (lpFuncName == (char *)(pExportDir->Base + i)) 
      {
        if (lpFunctions[i]) return (unsigned long) (lpFunctions[i] +
              dosHeader); 
      }
    }
  }
  return 0; 
}

在调用完函数后,不要忘记用 UnloadPbDllFromMemory 来从内存中移去 DLL 以释放分配的内存,该函数还会用 DLL_PROCESS_DETACH 参数调用 DLL 的入口函数 DllMain 来从调用进程的地址空间卸载该 DLL。 以下是 UnloadPbDllFromMemory 函数代码:

上一页  1 2 3 4  下一页

Tags:合并 DLL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接