Annotation of mstools/samples/sdktools/walker/pefile.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.