Annotation of mstools/samples/sdktools/walker/pefile.c, revision 1.1.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.