[C/C++] PE Header Infos

Dieses Thema im Forum "Projekte / Codes" wurde erstellt von N0S, 3. Oktober 2010 .

Schlagworte:
  1. 3. Oktober 2010
    PE Header Infos

    Sicher nützlich für Leute die sich noch nicht mit dem PE Header beschäftigt haben...

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <commdlg.h>
    
    char file[MAX_PATH];
    char directory[MAX_PATH];
    BOOL getFile();
    BOOL readFileMemory();
    
    DWORD findTablesAddress(int entry);
    
    void showExportTable();
    void showImportTable();
    void showTLS();
    
    BYTE * BaseOfImage;
    
    PIMAGE_DOS_HEADER pDosHeader = 0;
    PIMAGE_NT_HEADERS32 pNTHeader = 0;
    PIMAGE_SECTION_HEADER pSectionHeader = 0;
    
    //export table
    PIMAGE_EXPORT_DIRECTORY pExportTable = 0;
    
    //import table
    PIMAGE_IMPORT_DESCRIPTOR pImportTable = 0;
    PIMAGE_THUNK_DATA32 pIAT = 0;
    PIMAGE_IMPORT_BY_NAME pImportName = 0;
    
    //TLS
    PIMAGE_TLS_DIRECTORY32 pTLS = 0;
    
    void printDosHeader() 
    {
     printf("########################\nDOS HEADER\n########################\n\n");
     printf("e_magic\t\t%X\t- %d\n",pDosHeader->e_magic,pDosHeader->e_magic);
     printf("e_lfanew\t%X\t- %d\n",pDosHeader->e_lfanew,pDosHeader->e_lfanew);
    }
    
    void printNTHeader()
    {
     printf("\n########################\nNT HEADER\n########################\n\n");
     printf("Signature\t\t\t%X\t- %d\n\n",pNTHeader->Signature,pNTHeader->Signature);
    
     printf("FileHeader:\n");
     printf("- Machine\t\t\t%X\t- %d\n",pNTHeader->FileHeader.Machine,pNTHeader->FileHeader.Machine);
     printf("- NumberOfSections\t\t%X\t- %d\n",pNTHeader->FileHeader.NumberOfSections,pNTHeader->FileHeader.NumberOfSections);
     printf("- SizeOfOptionalHeader\t\t%X\t- %d\n",pNTHeader->FileHeader.SizeOfOptionalHeader,pNTHeader->FileHeader.SizeOfOptionalHeader);
     printf("- Characteristics\t\t%X\t- %d\n",pNTHeader->FileHeader.Characteristics,pNTHeader->FileHeader.Characteristics);
    
     printf("\nOptionalHeader\n");
     printf("- SizeOfCode\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.SizeOfCode,pNTHeader->OptionalHeader.SizeOfCode);
     printf("- AddressOfEntryPoint\t\t%X\t- %d\n",pNTHeader->OptionalHeader.AddressOfEntryPoint,pNTHeader->OptionalHeader.AddressOfEntryPoint);
     printf("- BaseOfCode\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.BaseOfCode,pNTHeader->OptionalHeader.BaseOfCode);
     printf("- BaseOfData\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.BaseOfData,pNTHeader->OptionalHeader.BaseOfData);
     printf("- ImageBase\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.ImageBase,pNTHeader->OptionalHeader.ImageBase);
     printf("- SizeOfImage\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.SizeOfImage,pNTHeader->OptionalHeader.SizeOfImage);
     printf("- SizeOfHeaders\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.SizeOfHeaders,pNTHeader->OptionalHeader.SizeOfHeaders);
     printf("- CheckSum\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.CheckSum,pNTHeader->OptionalHeader.CheckSum);
     printf("- DllCharacteristics\t\t%X\t- %d\n",pNTHeader->OptionalHeader.DllCharacteristics,pNTHeader->OptionalHeader.DllCharacteristics);
     printf("- NumberOfRvaAndSizes\t\t%X\t- %d\n",pNTHeader->OptionalHeader.NumberOfRvaAndSizes,pNTHeader->OptionalHeader.NumberOfRvaAndSizes);
     printf("- Subsystem\t\t\t%X\t- %d\n",pNTHeader->OptionalHeader.Subsystem,pNTHeader->OptionalHeader.Subsystem);
    }
    
    int main(int argc, char *argv[])
    {
     if (getFile())
     {
     if (!readFileMemory())
     {
     return 0;
     }
     }
    
     pDosHeader = (PIMAGE_DOS_HEADER)BaseOfImage;
     if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
     {
     MessageBox(0,"IMAGE_DOS_SIGNATURE doesn't match.","Error",MB_OK);
     return 0;
     }
     printDosHeader();
    
     pNTHeader = (PIMAGE_NT_HEADERS32)(BaseOfImage + pDosHeader->e_lfanew);
    
     if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
     {
     MessageBox(0,"IMAGE_NT_SIGNATURE doesn't match.","Error",MB_OK);
     return 0;
     }
    
     if (pNTHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
     {
     //64bit
     MessageBox(0,"x64 exe not supported right now.","Error",MB_OK);
     return 0;
     }
    
     printNTHeader();
    
     printf("\n########################\nDATA DIRECTORIES (%d)\n########################\n\n",pNTHeader->OptionalHeader.NumberOfRvaAndSizes);
     for (DWORD i = 0; i < pNTHeader->OptionalHeader.NumberOfRvaAndSizes; i++)
     {
     IMAGE_DATA_DIRECTORY dataDir = pNTHeader->OptionalHeader.DataDirectory[i];
     if (dataDir.VirtualAddress != 0 && dataDir.Size != 0)
     {
     printf("IMAGE_DATA_DIRECTOR Number %d:\n",i);
     printf("- VirtualAddress\t%X\t- %d\n",dataDir.VirtualAddress,dataDir.VirtualAddress);
     printf("- Size\t\t\t%X\t- %d\n\n",dataDir.Size,dataDir.Size);
     }
     }
    
     printf("\n########################\nSection table\n########################\n");
     pSectionHeader = (PIMAGE_SECTION_HEADER)(BaseOfImage + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
    
     char name[9] = {0};
    
     for (WORD i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
     {
     printf("\nIMAGE_SECTION_HEADER Number %d:\n",i+1);
     //not null terminated
     memcpy(name,pSectionHeader->Name,8);
     printf("- Name: \t\t%s\n",name);
     printf("- VirtualSize: \t\t%X\t\t- \t%d\n",pSectionHeader->Misc.VirtualSize,pSectionHeader->Misc.VirtualSize);
     printf("- VirtualAddress: \t%X\t\t- \t%d\n",pSectionHeader->VirtualAddress,pSectionHeader->VirtualAddress);
     printf("- SizeOfRawData: \t%X\t\t- \t%d\n",pSectionHeader->SizeOfRawData,pSectionHeader->SizeOfRawData);
     printf("- PointerToRawData: \t%X\t\t- \t%d\n",pSectionHeader->PointerToRawData,pSectionHeader->PointerToRawData);
     printf("- Characteristics: \t%X\t- \t%d\n",pSectionHeader->Characteristics,pSectionHeader->Characteristics);
     pSectionHeader++;
     }
    
    
     if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != 0)
     {
     showExportTable();
     }
     if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != 0)
     {
     showImportTable();
     }
     if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0)
     {
     showTLS();
     }
    
     delete[] BaseOfImage;
     //getchar();
     return 0;
    }
    
    void showTLS()
    {
     printf("\n########################\nTLS table\n########################\n\n");
     DWORD TLSTableVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress;
     DWORD TLSTableOffset = findTablesAddress(IMAGE_DIRECTORY_ENTRY_TLS);
     pTLS = (PIMAGE_TLS_DIRECTORY32)TLSTableOffset;
     printf("\nIMAGE_TLS_DIRECTORY\n");
     printf("- StartAddressOfRawData: \t%X\t- \t%d\n",pTLS->StartAddressOfRawData,pTLS->StartAddressOfRawData);
     printf("- EndAddressOfRawData: \t\t%X\t- \t%d\n",pTLS->EndAddressOfRawData,pTLS->EndAddressOfRawData);
     printf("- SizeOfZeroFill: \t\t%X\t- \t%d\n",pTLS->SizeOfZeroFill,pTLS->SizeOfZeroFill);
     printf("- Characteristics: \t\t%X\t- \t%d\n",pTLS->Characteristics,pTLS->Characteristics);
     printf("- AddressOfIndex: \t\t%X\t- \t%d\n",pTLS->AddressOfIndex,pTLS->AddressOfIndex);
     printf("- AddressOfCallBacks: \t\t%X\t- \t%d\n",pTLS->AddressOfCallBacks,pTLS->AddressOfCallBacks);
    }
    
    void showExportTable()
    {
     printf("\n########################\nExport table\n########################\n\n");
    
     DWORD exportTableVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
     DWORD exportTableOffset = findTablesAddress(IMAGE_DIRECTORY_ENTRY_EXPORT);
     pExportTable = (PIMAGE_EXPORT_DIRECTORY)(exportTableOffset);
    
     printf("\nIMAGE_EXPORT_DIRECTORY\n");
     char * pName = (char *)((pExportTable->Name)-exportTableVA) + exportTableOffset;
     printf("- Name: \t\t\t%s\n",pName);
     printf("- rvaName: \t\t\t%X\t- \t%d\n",pExportTable->Name,pExportTable->Name);
     printf("- Base: \t\t\t%X\t- \t%d\n",pExportTable->Base,pExportTable->Base);
     printf("- NumberOfFunctions: \t\t%X\t- \t%d\n",pExportTable->NumberOfFunctions,pExportTable->NumberOfFunctions);
     printf("- NumberOfNames: \t\t%X\t- \t%d\n",pExportTable->NumberOfNames,pExportTable->NumberOfNames);
     printf("- AddressOfFunctions: \t\t%X\t- \t%d\n",pExportTable->AddressOfFunctions,pExportTable->AddressOfFunctions);
     printf("- AddressOfNameOrdinals: \t%X\t- \t%d\n\n",pExportTable->AddressOfNames,pExportTable->AddressOfNames);
    
     DWORD * addressOfFunctionsArray = (DWORD *)(((pExportTable->AddressOfFunctions)-exportTableVA) + exportTableOffset);
     DWORD * addressOfNamesArray = (DWORD *)(((pExportTable->AddressOfNames)-exportTableVA) + exportTableOffset);
     WORD * addressOfNameOrdinalsArray = (WORD *)(((pExportTable->AddressOfNameOrdinals)-exportTableVA) + exportTableOffset);
     char * name;
     DWORD functionAddressRVA;
     DWORD functionOrdinal;
     printf("Exported functions with name:\n");
     for (DWORD i = 0; i < pExportTable->NumberOfNames; i++)
     {
     name = (char*)(((addressOfNamesArray[i])-exportTableVA) + exportTableOffset);
     functionAddressRVA = addressOfFunctionsArray[addressOfNameOrdinalsArray[i]];
     functionOrdinal = (addressOfNameOrdinalsArray[i] + pExportTable->Base);
     printf("Function Name: %s - Ordinal: %X - Name Ordinal: %X - Address (RVA): %X\n",name,functionOrdinal,addressOfNameOrdinalsArray[i],functionAddressRVA);
     }
    
     if (pExportTable->NumberOfNames != pExportTable->NumberOfFunctions)
     {
     printf("\nExported functions without name:\n");
     for (DWORD i = 0; i < pExportTable->NumberOfFunctions; i++)
     {
     bool withoutName = true;
     for (DWORD j = 0; j < pExportTable->NumberOfNames; j++)
     {
     if(addressOfNameOrdinalsArray[j] == i)
     {
     withoutName = false;
     break;
     }
     }
     if (withoutName && addressOfFunctionsArray[i] != 0)
     {
     printf("Function Ordinal: %X - Address (RVA): %X\n",(i+pExportTable->Base),addressOfFunctionsArray[i]);
     }
     }
     }
    }
    
    void showImportTable()
    {
     printf("\n########################\nImport table\n########################\n\n");
    
     DWORD importTableVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
     DWORD importTableOffset = findTablesAddress(IMAGE_DIRECTORY_ENTRY_IMPORT);
     pImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(importTableOffset);
    
     int countIID = 0;
     int countImports = 0;
    
     do {
     countIID++;
     printf("\nIMAGE_IMPORT_DESCRIPTOR Number %d:\n",countIID);
     char * pName = (char *)((pImportTable->Name)-importTableVA) + importTableOffset;
     printf("- Name: \t\t\t%s\n",pName);
     printf("- rvaName: \t\t\t%X\t- \t%d\n",pImportTable->Name,pImportTable->Name);
     printf("- FirstThunk (IAT): \t\t%X\t- \t%d\n",pImportTable->FirstThunk,pImportTable->FirstThunk);
     printf("- OriginalFirstThunk (INT): \t%X\t- \t%d\n",pImportTable->OriginalFirstThunk,pImportTable->OriginalFirstThunk);
     printf("- TimeDateStamp: \t\t%X\t- \t%d\n",pImportTable->TimeDateStamp,pImportTable->TimeDateStamp);
     printf("- ForwarderChain: \t\t%X\t- \t%d\n",pImportTable->ForwarderChain,pImportTable->ForwarderChain);
    
     DWORD rvaINT = pImportTable->OriginalFirstThunk;
     DWORD rvaIAT = pImportTable->FirstThunk;
    
     printf("\nIMAGE_THUNK_DATA ARRAY:\n");
    
     if (rvaINT != 0 && rvaINT != rvaIAT)
     {
     printf("rvaINT and rvaIAT are different! rvaINT: %X rvaIAT: %X\n",rvaINT,rvaIAT);
     }
    
     pIAT = (PIMAGE_THUNK_DATA32)((rvaIAT-importTableVA) + importTableOffset);
    
     if (pIAT->u1.Ordinal) //maybe no imports from dll
     {
     do 
     {
     countImports++;
     if (IMAGE_SNAP_BY_ORDINAL32(pIAT->u1.Ordinal))
     {
     //by ordinal
     printf("- Ordinal: %X\n",IMAGE_ORDINAL32(pIAT->u1.Ordinal));
     //printf("- API Address: %X\n",GetProcAddress(GetModuleHandle(pName), (char *)IMAGE_ORDINAL32(pIAT->u1.Ordinal)));
     //GetProcAddress(GetModuleHandle(pName), (char *)IMAGE_ORDINAL32(pIAT->u1.Ordinal));
     } else {
     //by name
     pImportName = (PIMAGE_IMPORT_BY_NAME)(((pIAT->u1.AddressOfData)-importTableVA) + importTableOffset);
     printf("- Name: %s",pImportName->Name);
     printf("\t Hint: %X\n",pImportName->Hint);
     }
    
     pIAT++;
     } while (pIAT->u1.AddressOfData != 0);
     }
    
     pImportTable++;
     } while (pImportTable->Name);
    
     printf("\nDLL Count: %d \t Import Count: %d\n",countIID,countImports);
    }
    
    DWORD findTablesAddress(int entry)
    {
     DWORD tableVA = pNTHeader->OptionalHeader.DataDirectory[entry].VirtualAddress;
     pSectionHeader = (PIMAGE_SECTION_HEADER)(BaseOfImage + pDosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
    
     for (WORD i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++)
     {
     DWORD sectionVA = pSectionHeader->VirtualAddress;
     DWORD sectionSize = pSectionHeader->Misc.VirtualSize;
    
     if ((sectionVA <= tableVA) && (tableVA < (sectionVA+sectionSize)))
     {
     return (DWORD)(BaseOfImage + pSectionHeader->PointerToRawData + (tableVA-sectionVA));
     break;
     }
     pSectionHeader++;
     }
     return 0;
    }
    
    BOOL readFileMemory()
    {
     HANDLE hFile = CreateFile(file,GENERIC_READ,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
    
     if (hFile == INVALID_HANDLE_VALUE)
     return FALSE;
    
     DWORD fileSize = GetFileSize(hFile,0);
     BaseOfImage = new BYTE[fileSize];
     DWORD lpNumberOfBytesRead;
     if (!ReadFile(hFile,BaseOfImage,fileSize,&lpNumberOfBytesRead,0))
     {
     CloseHandle(hFile);
     MessageBox(0,"Cannot read file.","Error",MB_OK);
     return FALSE;
     }
     CloseHandle(hFile);
     return TRUE;
    }
    
    BOOL getFile()
    {
     OPENFILENAME ofn = {0};
     ofn.lStructSize = sizeof(OPENFILENAMEA);
     ofn.hwndOwner = 0;
     ofn.lpstrFilter = "Exe file (*.exe)\0*.exe\0Dynamic Link Library (*.dll)\0*.dll\00";
     ofn.lpstrCustomFilter = 0;
     ofn.nFilterIndex = 1;
     ofn.lpstrFile = file;
     ofn.nMaxFile = sizeof(file);
     ofn.lpstrFileTitle = 0;
     ofn.nMaxFileTitle = 0;
     ofn.lpstrInitialDir = 0;
     ofn.lpstrTitle = "PEInfo";
     ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ENABLESIZING;
     ofn.lpstrDefExt = 0;
    
     if(GetOpenFileNameA(&ofn)) {
     strcpy_s(directory, MAX_PATH, file);
    
     for (size_t i = strlen(file);i > 0; i--) {
     if(directory[i] == '\\') {
     directory[i+1] = NULL;
     }
     }
     if (SetCurrentDirectoryA(directory)) {
     return TRUE;
     } else {
     return FALSE;
     }
     } else {
     return FALSE;
     }
     
  2. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.