#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; } + Multi-Zitat Zitieren