PEFILE.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. #include "pefile.h"
  11. PIMAGE_SECTION_HEADER WINAPI IDSectionHeaderOffset (LPVOID);
  12. BOOL WINAPI DllMain (
  13.     HANDLE    hModule,
  14.     DWORD     dwFunction,
  15.     LPVOID    lpNot)
  16. {
  17.     return TRUE;
  18. }
  19. /* return offset to file header */
  20. PIMAGE_FILE_HEADER   WINAPI FileHeaderOffset (
  21.     LPVOID    lpFile)
  22. {
  23.     int       ImageHdrOffset = 0;
  24.     /* if DOS based file, skip DOS header and file signature */
  25.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  26. {
  27. /* file image header offset exists after DOS header and nt signature */
  28. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  29. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) != IMAGE_NT_SIGNATURE)
  30.     return NULL;
  31. }
  32.     /* optional header exists immediately after file header and image header */
  33.     return (PIMAGE_FILE_HEADER)((int)lpFile + ImageHdrOffset);
  34. }
  35. /* return optional header data */
  36. PIMAGE_OPTIONAL_HEADER WINAPI OptionalHeaderOffset (
  37.     LPVOID    lpFile)
  38. {
  39.     int       ImageHdrOffset = 0;
  40.     /* if DOS based file, skip DOS header and file signature */
  41.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  42. {
  43. /* file image header offset exists after DOS header and nt signature */
  44. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  45. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) != IMAGE_NT_SIGNATURE)
  46.     return NULL;
  47. }
  48.     /* optional header exists immediately after file header and image header */
  49.     return (PIMAGE_OPTIONAL_HEADER)((char *)lpFile + ImageHdrOffset + sizeof (IMAGE_FILE_HEADER));
  50. }
  51. /* return pointer to first section header */
  52. PIMAGE_SECTION_HEADER WINAPI SectionHeaderOffset (
  53.     LPVOID    lpFile)
  54. {
  55.     int       ImageHdrOffset = 0;
  56.     /* if DOS based file, skip DOS header and file signature */
  57.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  58. {
  59. /* file image header offset exists after DOS header and nt signature */
  60. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  61. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) != IMAGE_NT_SIGNATURE)
  62.     return NULL;
  63. }
  64.     /* optional header exists immediately after file header and image header */
  65.     return (PIMAGE_SECTION_HEADER)((int)OptionalHeaderOffset (lpFile) +
  66. (int)((PIMAGE_FILE_HEADER)((int)lpFile + ImageHdrOffset))->SizeOfOptionalHeader);
  67. }
  68. /* return offset to first IMAGE_IMPORT_DIRECTORY entry */
  69. PIMAGE_IMPORT_DIRECTORY  WINAPI ImportDirectoryOffset (
  70. LPVOID   lpFile)
  71. {
  72.     PIMAGE_OPTIONAL_HEADER   poh = OptionalHeaderOffset (lpFile);
  73.     PIMAGE_SECTION_HEADER    psh = SectionHeaderOffset (lpFile);
  74.     int       nSections = NumOfSections (lpFile);
  75.     int       i = 0;
  76.     LPVOID      VAImportDir;
  77.     VAImportDir = (LPVOID)poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  78.     /* locate section containing import directory */
  79.     while (i++<nSections)
  80. {
  81. if (psh->VirtualAddress <= (DWORD)VAImportDir &&
  82.     psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImportDir)
  83.     break;
  84. psh++;
  85. }
  86.     if (i > nSections)
  87. return 0;
  88.     /* return image import directory offset */
  89.     return (PIMAGE_IMPORT_DIRECTORY)(((int)lpFile + (int)VAImportDir - psh->VirtualAddress) +
  90.    (int)psh->PointerToRawData);
  91. }
  92. /* return pointer to image directory section header */
  93. PIMAGE_SECTION_HEADER WINAPI IDSectionHeaderOffset (
  94.     LPVOID    lpFile)
  95. {
  96.     int       ImageHdrOffset = 0;
  97.     PIMAGE_OPTIONAL_HEADER   poh = OptionalHeaderOffset (lpFile);
  98.     PIMAGE_SECTION_HEADER    psh = SectionHeaderOffset (lpFile);
  99.     int       nSections = NumOfSections (lpFile);
  100.     int       i = 0;
  101.     LPVOID      VAImportDir;
  102.     VAImportDir = (LPVOID)poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
  103.     /* locate section containing import directory */
  104.     while (i++<nSections)
  105. {
  106. if (psh->VirtualAddress <= (DWORD)VAImportDir &&
  107.     psh->VirtualAddress + psh->SizeOfRawData > (DWORD)VAImportDir)
  108.     break;
  109. psh++;
  110. }
  111.     if (i > nSections)
  112. return 0;
  113.     else
  114. return psh;
  115. }
  116. /* return the total number of sections in the module */
  117. int   WINAPI NumOfSections (
  118.     LPVOID    lpFile)
  119. {
  120.     int       ImageHdrOffset = 0;
  121.     /* if DOS based file, skip DOS header and file signature */
  122.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  123. {
  124. /* file image header offset exists after DOS header and nt signature */
  125. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  126. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) != IMAGE_NT_SIGNATURE)
  127.     return 0;
  128. }
  129.     /* section total is found in the file header */
  130.     return (int)((PIMAGE_FILE_HEADER)((int)lpFile + ImageHdrOffset))->NumberOfSections;
  131. }
  132. /* retrieve name of module from module's open file handle */
  133. void WINAPI RetrieveModuleName (
  134.     char      *lpszModule,
  135.     HANDLE    hFile)
  136. {
  137.     HANDLE      hMapFile;
  138.     LPVOID      lpFile;
  139.     char      *lpszName;
  140.     int       nSections;
  141.     ULONG      VAExportDir;
  142.     int       i=0;
  143.     int       ImageHdrOffset;
  144.     PIMAGE_SECTION_HEADER    psh;
  145.     PIMAGE_FILE_HEADER      pfh;
  146.     PIMAGE_OPTIONAL_HEADER   poh;
  147.     PIMAGE_EXPORT_DIRECTORY  ped;
  148.     /* memory map handle to DLL for easy access */
  149.     hMapFile = CreateFileMapping (hFile,
  150.   (LPSECURITY_ATTRIBUTES)NULL,
  151.   PAGE_READONLY,
  152.   0,
  153.   0,
  154.   NULL);
  155.     /* map view of entire file */
  156.     lpFile = MapViewOfFile (hMapFile, FILE_MAP_READ, 0, 0, 0);
  157.     /* if DOS based file */
  158.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  159. {
  160. /* file image header offset exists after DOS header and nt signature */
  161. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  162. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) !=
  163.     IMAGE_NT_SIGNATURE)
  164.     {
  165.     strcpy (lpszModule, "Error, no IMAGE_NT_SIGNATURE");
  166.     goto EXIT;
  167.     }
  168. }
  169.     pfh = (PIMAGE_FILE_HEADER)((char *)lpFile + ImageHdrOffset);
  170.     /* if optional header exists and exports directory exists proceed */
  171.     if (pfh->SizeOfOptionalHeader)
  172. {
  173. /* locate virtual address for Export Image Directory in OptionalHeader */
  174. poh = (PIMAGE_OPTIONAL_HEADER)((char *)pfh + sizeof (IMAGE_FILE_HEADER));
  175. VAExportDir = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  176. /* locate section where export virtual address is located */
  177. psh = (PIMAGE_SECTION_HEADER)((char *)poh + pfh->SizeOfOptionalHeader);
  178. nSections = pfh->NumberOfSections;
  179. while (i++<nSections)
  180.     {
  181.     if (psh->VirtualAddress <= VAExportDir &&
  182. psh->VirtualAddress + psh->SizeOfRawData > VAExportDir)
  183. break;
  184.     psh++;
  185.     }
  186. /* locate export image directory */
  187. if (i < nSections)
  188.     ped = (PIMAGE_EXPORT_DIRECTORY)((char *)lpFile +
  189. (VAExportDir - psh->VirtualAddress) + psh->PointerToRawData);
  190. else
  191.     {
  192.     strcpy (lpszModule, "IMAGE_EXPORT_DIRECTORY not found");
  193.     goto EXIT;
  194.     }
  195. /* read name from export directory */
  196. lpszName = (char *)lpFile + ped->Name + (psh->PointerToRawData - psh->VirtualAddress);
  197. strcpy (lpszModule, lpszName);
  198. }
  199.     else
  200. strcpy (lpszModule, "Error, no IMAGE_OPTIONAL_HEADER");
  201. EXIT:
  202.     /* clean up before exiting */
  203.     UnmapViewOfFile (lpFile);
  204.     CloseHandle (hMapFile);
  205. }
  206. /* retieve section names from module file handle */
  207. void WINAPI RetrieveSectionNames (
  208.     HANDLE   hHeap,
  209.     HANDLE   hFile,
  210.     SECTIONINFO   **pSection)
  211. {
  212.     HANDLE      hMapFile;
  213.     LPVOID      lpFile;
  214.     int       nSections;
  215.     int       i=0;
  216.     int       ImageHdrOffset;
  217.     PIMAGE_SECTION_HEADER    psh;
  218.     PIMAGE_FILE_HEADER      pfh;
  219.     SECTIONINFO       *ps;
  220.     /* memory map handle to DLL for easy access */
  221.     hMapFile = CreateFileMapping (hFile,
  222.   (LPSECURITY_ATTRIBUTES)NULL,
  223.   PAGE_READONLY,
  224.   0,
  225.   0,
  226.   NULL);
  227.     /* map view of entire file */
  228.     lpFile = MapViewOfFile (hMapFile, FILE_MAP_READ, 0, 0, 0);
  229.     /* if DOS based file */
  230.     if (*((USHORT *)lpFile) == IMAGE_DOS_SIGNATURE)
  231. {
  232. /* file image header offset exists after DOS header and nt signature */
  233. ImageHdrOffset = (int)((ULONG *)lpFile)[15] + sizeof (ULONG);
  234. if (*((ULONG *)((char *)lpFile + ImageHdrOffset - sizeof (ULONG))) !=
  235.     IMAGE_NT_SIGNATURE)
  236.     goto EXIT;
  237. }
  238.     pfh = (PIMAGE_FILE_HEADER)((char *)lpFile + ImageHdrOffset);
  239.     /* if optional header exists, offset first section header */
  240.     psh = (PIMAGE_SECTION_HEADER)((char *)pfh +
  241.       sizeof (IMAGE_FILE_HEADER) + pfh->SizeOfOptionalHeader);
  242.     /* allocate one section header for each section */
  243.     ps = *pSection = (SECTIONINFO *)HeapAlloc (hHeap,
  244.        HEAP_ZERO_MEMORY,
  245.        sizeof (SECTIONINFO));
  246.     nSections = pfh->NumberOfSections;
  247.     while (TRUE)
  248. {
  249. strcpy (ps->szSection, psh[i].Name);
  250. ps->uVirtualAddress = psh[i].VirtualAddress;
  251. ps->uSize = psh[i].SizeOfRawData;
  252. if (++i >= nSections)
  253.     break;
  254. /* allocate heap memory for sections */
  255. ps->Next = (LPSECTIONINFO)HeapAlloc (hHeap,
  256.      HEAP_ZERO_MEMORY,
  257.      sizeof (SECTIONINFO));
  258. ps = (SECTIONINFO *)ps->Next;
  259. }
  260. EXIT:
  261.     /* clean up before exiting */
  262.     UnmapViewOfFile (lpFile);
  263.     CloseHandle (hMapFile);
  264. }
  265. /* function returns the entry point for an exe module lpFile must
  266.    be a memory mapped file pointer to the beginning of the image file */
  267. LPVOID WINAPI GetModuleEntryPoint (
  268.     LPVOID    lpFile)
  269. {
  270.     PIMAGE_OPTIONAL_HEADER   poh = OptionalHeaderOffset (lpFile);
  271.     if (poh != NULL)
  272. return (LPVOID)(poh->AddressOfEntryPoint);
  273.     else
  274. return NULL;
  275. }
  276. /* retrieve entry point */
  277. LPVOID WINAPI GetImageBase (
  278.     LPVOID    lpFile)
  279. {
  280.     PIMAGE_OPTIONAL_HEADER   poh = OptionalHeaderOffset (lpFile);
  281.     if (poh != NULL)
  282. return (LPVOID)(poh->ImageBase);
  283.     else
  284. return NULL;
  285. }
  286. /* get import modules names separated by null terminators, return module count */
  287. int  WINAPI GetImportModuleNames (
  288.     LPVOID    lpFile,
  289.     HANDLE    hHeap,
  290.     char      **pszModules)
  291. {
  292.     PIMAGE_IMPORT_DIRECTORY  pid = ImportDirectoryOffset (lpFile);
  293.     PIMAGE_SECTION_HEADER    pidsh = IDSectionHeaderOffset (lpFile);
  294.     BYTE      *pData = (BYTE *)pid;
  295.     int       nCnt = 0, nSize = 0, i;
  296.     char      *pModule[1024];  /* hardcoded maximum number of modules?? */
  297.     char      *psz;
  298.     /* extract all import modules */
  299.     while (pid->dwRVAModule)
  300. {
  301. /* allocate temporary buffer for absolute string offsets */
  302. pModule[nCnt] = (char *)(pData + (pid->dwRVAModule-pidsh->VirtualAddress));
  303. nSize += strlen (pModule[nCnt]) + 1;
  304. /* increment to the next import directory entry */
  305. pid++;
  306. nCnt++;
  307. }
  308.     /* copy all strings to one chunk of heap memory */
  309.     *pszModules = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
  310.     psz = *pszModules;
  311.     for (i=0; i<nCnt; i++)
  312. {
  313. strcpy (psz, pModule[i]);
  314. psz += strlen (psz) + 1;
  315. }
  316.     return nCnt;
  317. }
  318. /* get import module function names separated by null terminators, return function count */
  319. int  WINAPI GetImportFunctionNamesByModule (
  320.     LPVOID    lpFile,
  321.     HANDLE    hHeap,
  322.     char      *pszModule,
  323.     char      **pszFunctions)
  324. {
  325.     PIMAGE_IMPORT_DIRECTORY  pid = ImportDirectoryOffset (lpFile);
  326.     PIMAGE_SECTION_HEADER    pidsh = IDSectionHeaderOffset (lpFile);
  327.     DWORD      dwBase = ((DWORD)pid - pidsh->VirtualAddress);
  328.     int       nCnt = 0, nSize = 0;
  329.     DWORD      dwFunction;
  330.     char      *psz;
  331.     /* find module's pid */
  332.     while (pid->dwRVAModule &&
  333.    strcmp (pszModule, (char *)(pid->dwRVAModule+dwBase)))
  334. pid++;
  335.     /* count functions and total space required for them */
  336.     nSize += strlen ((char *)((*(DWORD *)(pid->dwRVAFirstFunction + dwBase)) + dwBase+2)) + 1;
  337.     /* last image directory does not have a separate function list, so improvise */
  338.     if (!(dwFunction = pid->dwRVAFunctionList))
  339. dwFunction = pid->dwRVAFirstFunction + 4;
  340.     while (dwFunction &&
  341.    *(char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2))
  342. {
  343. nSize += strlen ((char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2)) + 1;
  344. dwFunction += 4;
  345. nCnt++;
  346. }
  347.     /* allocate memory off heap for function names */
  348.     *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
  349.     psz = *pszFunctions;
  350.     strcpy (psz, (char *)((*(DWORD *)(pid->dwRVAFirstFunction + dwBase)) + dwBase+2));
  351.     psz += strlen ((char *)((*(DWORD *)(pid->dwRVAFirstFunction + dwBase)) + dwBase+2)) + 1;
  352.     /* last image directory does not have a separate function list, so improvise */
  353.     if (!(dwFunction = pid->dwRVAFunctionList))
  354. dwFunction = pid->dwRVAFirstFunction + 4;
  355.     while (dwFunction &&
  356.    *((char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2)))
  357. {
  358. strcpy (psz, (char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2));
  359. psz += strlen ((char *)((*(DWORD *)(dwFunction + dwBase)) + dwBase+2)) + 1;
  360. dwFunction += 4;
  361. }
  362.     return nCnt;
  363. }
  364. /* get exported function names separated by null terminators, return count of functions */
  365. int  WINAPI GetExportFunctionNames (
  366.     LPVOID    lpFile,
  367.     HANDLE    hHeap,
  368.     char      **pszFunctions)
  369. {
  370.     return 0;
  371. }