2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
26 //#define DUMPING_DATA 1
29 #pragma warning (disable:4806)
32 #include "utils/log.h"
33 #define printf(format, ...) CLog::Log(LOGDEBUG, format , ##__VA_ARGS__)
35 const char *DATA_DIR_NAME[16] =
42 "Base Relocation Table",
50 "Delay Import Descriptor",
51 "COM+ Runtime Header",
56 CoffLoader::CoffLoader()
68 SizeOfStringTable = 0;
76 CoffLoader::~CoffLoader()
83 VirtualFree(hModule, 0, MEM_RELEASE);
94 delete [] StringTable;
99 delete [] SectionData;
104 // Has nothing to do with the coff loader itself
105 // it can be used to parse the headers of a dll
106 // already loaded into memory
107 int CoffLoader::ParseHeaders(void* hModule)
109 if (strncmp((char*)hModule, "MZ", 2) != 0)
112 int* Offset = (int*)((char*)hModule+0x3c);
116 if (strncmp((char*)hModule+*Offset, "PE\0\0", 4) != 0)
119 FileHeaderOffset = *Offset + 4;
121 CoffFileHeader = (COFF_FileHeader_t *) ( (char*)hModule + FileHeaderOffset );
122 NumOfSections = CoffFileHeader->NumberOfSections;
124 OptionHeader = (OptionHeader_t *) ( (char*)CoffFileHeader + sizeof(COFF_FileHeader_t) );
125 WindowsHeader = (WindowsHeader_t *) ( (char*)OptionHeader + OPTHDR_SIZE );
126 EntryAddress = OptionHeader->Entry;
127 NumOfDirectories = WindowsHeader->NumDirectories;
129 Directory = (Image_Data_Directory_t *) ( (char*)WindowsHeader + WINHDR_SIZE);
130 SectionHeader = (SectionHeader_t *) ( (char*)Directory + sizeof(Image_Data_Directory_t) * NumOfDirectories);
132 if (CoffFileHeader->MachineType != IMAGE_FILE_MACHINE_I386)
136 PrintFileHeader(CoffFileHeader);
139 if ( CoffFileHeader->SizeOfOptionHeader == 0 ) //not an image file, object file maybe
142 // process Option Header
143 if (OptionHeader->Magic == OPTMAGIC_PE32P)
145 printf("PE32+ not supported\n");
148 else if (OptionHeader->Magic == OPTMAGIC_PE32)
152 PrintOptionHeader(OptionHeader);
153 PrintWindowsHeader(WindowsHeader);
164 for (int DirCount = 0; DirCount < NumOfDirectories; DirCount++)
166 printf("Data Directory %02d: %s\n", DirCount + 1, DATA_DIR_NAME[DirCount]);
167 printf(" RVA: %08X\n", Directory[DirCount].RVA);
168 printf(" Size: %08X\n\n", Directory[DirCount].Size);
176 int CoffLoader::LoadCoffHModule(FILE *fp)
178 //test file signatures
181 memset(Sig, 0, sizeof(Sig));
182 if (!fread(Sig, 1, 2, fp) || strncmp(Sig, "MZ", 2) != 0)
185 if (fseek(fp, 0x3c, SEEK_SET) != 0)
189 if (!fread(&Offset, sizeof(int), 1, fp) || (Offset <= 0))
192 if (fseek(fp, Offset, SEEK_SET) != 0)
195 memset(Sig, 0, sizeof(Sig));
196 if (!fread(Sig, 1, 4, fp) || strncmp(Sig, "PE\0\0", 4) != 0)
200 FileHeaderOffset = Offset;
202 // Load and process Header
203 if (fseek(fp, FileHeaderOffset + sizeof(COFF_FileHeader_t) + OPTHDR_SIZE, SEEK_SET)) //skip to winows headers
206 WindowsHeader_t tempWindowsHeader;
207 size_t readcount = fread(&tempWindowsHeader, 1, WINHDR_SIZE, fp);
208 if (readcount != WINHDR_SIZE) //test file size error
211 // alloc aligned memory
213 hModule = malloc(tempWindowsHeader.SizeOfImage);
215 hModule = VirtualAllocEx(0, (PVOID)tempWindowsHeader.ImageBase, tempWindowsHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
217 hModule = VirtualAlloc(0, tempWindowsHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
220 return 0; //memory allocation fails
223 readcount = fread(hModule, 1, tempWindowsHeader.SizeOfHeaders, fp);
224 if (readcount != tempWindowsHeader.SizeOfHeaders) //file size error
227 CoffFileHeader = (COFF_FileHeader_t *) ( (char*)hModule + FileHeaderOffset );
228 NumOfSections = CoffFileHeader->NumberOfSections;
230 OptionHeader = (OptionHeader_t *) ( (char*)CoffFileHeader + sizeof(COFF_FileHeader_t) );
231 WindowsHeader = (WindowsHeader_t *) ( (char*)OptionHeader + OPTHDR_SIZE );
232 EntryAddress = OptionHeader->Entry;
233 NumOfDirectories = WindowsHeader->NumDirectories;
235 Directory = (Image_Data_Directory_t *) ( (char*)WindowsHeader + WINHDR_SIZE);
236 SectionHeader = (SectionHeader_t *) ( (char*)Directory + sizeof(Image_Data_Directory_t) * NumOfDirectories);
238 if (CoffFileHeader->MachineType != IMAGE_FILE_MACHINE_I386)
242 PrintFileHeader(CoffFileHeader);
245 if ( CoffFileHeader->SizeOfOptionHeader == 0 ) //not an image file, object file maybe
248 // process Option Header
249 if (OptionHeader->Magic == OPTMAGIC_PE32P)
251 printf("PE32+ not supported\n");
254 else if (OptionHeader->Magic == OPTMAGIC_PE32)
258 PrintOptionHeader(OptionHeader);
259 PrintWindowsHeader(WindowsHeader);
270 for (int DirCount = 0; DirCount < NumOfDirectories; DirCount++)
272 printf("Data Directory %02d: %s\n", DirCount + 1, DATA_DIR_NAME[DirCount]);
273 printf(" RVA: %08X\n", Directory[DirCount].RVA);
274 printf(" Size: %08X\n\n", Directory[DirCount].Size);
282 int CoffLoader::LoadSymTable(FILE *fp)
284 int Offset = ftell(fp);
288 if ( CoffFileHeader->PointerToSymbolTable == 0 )
291 if (fseek(fp, CoffFileHeader->PointerToSymbolTable /* + CoffBeginOffset*/, SEEK_SET) != 0)
294 SymbolTable_t *tmp = new SymbolTable_t[CoffFileHeader->NumberOfSymbols];
297 printf("Could not allocate memory for symbol table!\n");
300 if (!fread((void *)tmp, CoffFileHeader->NumberOfSymbols, sizeof(SymbolTable_t), fp))
305 NumberOfSymbols = CoffFileHeader->NumberOfSymbols;
307 if (fseek(fp, Offset, SEEK_SET) != 0)
312 int CoffLoader::LoadStringTable(FILE *fp)
317 int Offset = ftell(fp);
321 if ( CoffFileHeader->PointerToSymbolTable == 0 )
324 if (fseek(fp, CoffFileHeader->PointerToSymbolTable +
325 CoffFileHeader->NumberOfSymbols * sizeof(SymbolTable_t),
329 if (!fread(&StringTableSize, 1, sizeof(int), fp))
331 StringTableSize -= 4;
332 if (StringTableSize != 0)
334 tmp = new char[StringTableSize];
337 printf("Could not allocate memory for string table\n");
340 if (!fread((void *)tmp, StringTableSize, sizeof(char), fp))
346 SizeOfStringTable = StringTableSize;
348 if (fseek(fp, Offset, SEEK_SET) != 0)
353 int CoffLoader::LoadSections(FILE *fp)
355 NumOfSections = CoffFileHeader->NumberOfSections;
357 SectionData = new char * [NumOfSections];
361 // Bobbin007: for debug dlls this check always fails
363 //////check VMA size!!!!!
364 //unsigned long vma_size = 0;
365 //for (int SctnCnt = 0; SctnCnt < NumOfSections; SctnCnt++)
367 // SectionHeader_t *ScnHdr = (SectionHeader_t *)(SectionHeader + SctnCnt);
368 // vma_size = max(vma_size, ScnHdr->VirtualAddress + ScnHdr->SizeOfRawData);
369 // vma_size = max(vma_size, ScnHdr->VirtualAddress + ScnHdr->VirtualSize);
372 //if (WindowsHeader->SizeOfImage < vma_size)
373 // return 0; //something wrong with file
375 for (int SctnCnt = 0; SctnCnt < NumOfSections; SctnCnt++)
377 SectionHeader_t *ScnHdr = (SectionHeader_t *)(SectionHeader + SctnCnt);
378 SectionData[SctnCnt] = ((char*)hModule + ScnHdr->VirtualAddress);
380 if (fseek(fp, ScnHdr->PtrToRawData, SEEK_SET) != 0)
383 if (!fread(SectionData[SctnCnt], 1, ScnHdr->SizeOfRawData, fp))
390 for (int i = 0; i < 8; i++)
391 namebuf[i] = ScnHdr->Name[i];
393 sprintf(szBuf, "Load code Sections %s Memory %p,Length %x\n", namebuf,
394 SectionData[SctnCnt], max(ScnHdr->VirtualSize, ScnHdr->SizeOfRawData));
395 OutputDebugString(szBuf);
398 if ( ScnHdr->SizeOfRawData < ScnHdr->VirtualSize ) //initialize BSS data in the end of section
400 memset((char*)((long)(SectionData[SctnCnt]) + ScnHdr->SizeOfRawData), 0, ScnHdr->VirtualSize - ScnHdr->SizeOfRawData);
403 if (ScnHdr->Characteristics & IMAGE_SCN_CNT_BSS) //initialize whole .BSS section, pure .BSS is obsolete
405 memset(SectionData[SctnCnt], 0, ScnHdr->VirtualSize);
409 PrintSection(SectionHeader + SctnCnt, SectionData[SctnCnt]);
416 //FIXME: Add the Free Resources functions
418 int CoffLoader::RVA2Section(unsigned long RVA)
420 NumOfSections = CoffFileHeader->NumberOfSections;
421 for ( int i = 0; i < NumOfSections; i++)
423 if ( SectionHeader[i].VirtualAddress <= RVA )
425 if ( i + 1 != NumOfSections )
427 if ( RVA < SectionHeader[i + 1].VirtualAddress )
429 if ( SectionHeader[i].VirtualAddress + SectionHeader[i].VirtualSize <= RVA )
430 printf("Warning! Address outside of Section: %lx!\n", RVA);
437 if ( SectionHeader[i].VirtualAddress + SectionHeader[i].VirtualSize <= RVA )
438 printf("Warning! Address outside of Section: %lx!\n", RVA);
444 printf("RVA2Section lookup failure!\n");
448 void* CoffLoader::RVA2Data(unsigned long RVA)
450 int Sctn = RVA2Section(RVA);
452 if( RVA < SectionHeader[Sctn].VirtualAddress
453 || RVA >= SectionHeader[Sctn].VirtualAddress + SectionHeader[Sctn].VirtualSize)
455 // RVA2Section is lying, let's use base address of dll instead, only works if
456 // DLL has been loaded fully into memory, wich we normally do
457 return (void*)(RVA + (unsigned long)hModule);
459 return SectionData[Sctn] + RVA - SectionHeader[Sctn].VirtualAddress;
462 unsigned long CoffLoader::Data2RVA(void* address)
464 for ( int i = 0; i < CoffFileHeader->NumberOfSections; i++)
466 if(address >= SectionData[i] && address < SectionData[i] + SectionHeader[i].VirtualSize)
467 return (unsigned long)address - (unsigned long)SectionData[i] + SectionHeader[i].VirtualAddress;
470 // Section wasn't found, so use relative to main load of dll
471 return (unsigned long)address - (unsigned long)hModule;
474 char *CoffLoader::GetStringTblIndex(int index)
476 char *table = StringTable;
479 table += strlen(table) + 1;
483 char *CoffLoader::GetStringTblOff(int Offset)
485 return StringTable + Offset - 4;
488 char *CoffLoader::GetSymbolName(SymbolTable_t *sym)
490 __int64 index = sym->Name.Offset;
491 int low = (int)(index & 0xFFFFFFFF);
492 int high = (int)((index >> 32) & 0xFFFFFFFF);
496 return GetStringTblOff(high);
500 static char shortname[9];
501 memset(shortname, 0, 9);
502 strncpy(shortname, (char *)sym->Name.ShortName, 8);
507 char *CoffLoader::GetSymbolName(int index)
509 SymbolTable_t *sym = &(SymTable[index]);
510 return GetSymbolName(sym);
513 void CoffLoader::PrintStringTable(void)
515 int size = SizeOfStringTable;
517 char *table = StringTable;
519 printf("\nSTRING TABLE\n");
522 printf("%2d: %s\n", index++, table);
523 size -= strlen(table) + 1;
524 table += strlen(table) + 1;
530 void CoffLoader::PrintSymbolTable(void)
534 printf("COFF SYMBOL TABLE\n");
535 for (SymIndex = 0; SymIndex < NumberOfSymbols; SymIndex++)
537 printf("%03X ", SymIndex);
538 printf("%08lX ", SymTable[SymIndex].Value);
540 if (SymTable[SymIndex].SectionNumber == IMAGE_SYM_ABSOLUTE)
542 else if (SymTable[SymIndex].SectionNumber == IMAGE_SYM_DEBUG)
544 else if (SymTable[SymIndex].SectionNumber == IMAGE_SYM_UNDEFINED)
548 printf("SECT%d ", SymTable[SymIndex].SectionNumber);
549 if (SymTable[SymIndex].SectionNumber < 10)
551 if (SymTable[SymIndex].SectionNumber < 100)
555 if (SymTable[SymIndex].Type == 0)
559 printf("%X ", SymTable[SymIndex].Type);
560 if (SymTable[SymIndex].Type < 0x10)
562 if (SymTable[SymIndex].Type < 0x100)
564 if (SymTable[SymIndex].Type < 0x1000)
568 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_END_OF_FUNCTION)
569 printf("End of Function ");
570 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_NULL)
572 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_AUTOMATIC)
573 printf("Automatic ");
574 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_EXTERNAL)
576 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_STATIC)
578 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_REGISTER)
580 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_EXTERNAL_DEF)
581 printf("External Def ");
582 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_LABEL)
584 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_UNDEFINED_LABEL)
585 printf("Undefined Label ");
586 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_MEMBER_OF_STRUCT)
587 printf("Member Of Struct ");
588 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_ARGUMENT)
590 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_STRUCT_TAG)
591 printf("Struct Tag ");
592 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_MEMBER_OF_UNION)
593 printf("Member Of Union ");
594 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_UNION_TAG)
595 printf("Union Tag ");
596 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_TYPE_DEFINITION)
597 printf("Type Definition ");
598 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_UNDEFINED_STATIC)
599 printf("Undefined Static ");
600 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_ENUM_TAG)
602 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_MEMBER_OF_ENUM)
603 printf("Member Of Enum ");
604 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_REGISTER_PARAM)
605 printf("Register Param ");
606 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_BIT_FIELD)
607 printf("Bit Field ");
608 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_BLOCK)
610 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_FUNCTION)
612 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_END_OF_STRUCT)
613 printf("End Of Struct ");
614 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_FILE)
616 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_SECTION)
618 if (SymTable[SymIndex].StorageClass == IMAGE_SYM_CLASS_WEAK_EXTERNAL)
619 printf("Weak External ");
621 printf("| %s", GetSymbolName(SymIndex));
623 SymIndex += SymTable[SymIndex].NumberOfAuxSymbols;
630 void CoffLoader::PrintFileHeader(COFF_FileHeader_t *FileHeader)
632 printf("COFF Header\n");
633 printf("------------------------------------------\n\n");
635 printf("MachineType: 0x%04X\n", FileHeader->MachineType);
636 printf("NumberOfSections: 0x%04X\n", FileHeader->NumberOfSections);
637 printf("TimeDateStamp: 0x%08lX\n",FileHeader->TimeDateStamp);
638 printf("PointerToSymbolTable: 0x%08lX\n",FileHeader->PointerToSymbolTable);
639 printf("NumberOfSymbols: 0x%08lX\n",FileHeader->NumberOfSymbols);
640 printf("SizeOfOptionHeader: 0x%04X\n", FileHeader->SizeOfOptionHeader);
641 printf("Characteristics: 0x%04X\n", FileHeader->Characteristics);
643 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED)
644 printf(" IMAGE_FILE_RELOCS_STRIPPED\n");
646 if (FileHeader->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
647 printf(" IMAGE_FILE_EXECUTABLE_IMAGE\n");
649 if (FileHeader->Characteristics & IMAGE_FILE_LINE_NUMS_STRIPPED)
650 printf(" IMAGE_FILE_LINE_NUMS_STRIPPED\n");
652 if (FileHeader->Characteristics & IMAGE_FILE_LOCAL_SYMS_STRIPPED)
653 printf(" IMAGE_FILE_LOCAL_SYMS_STRIPPED\n");
655 if (FileHeader->Characteristics & IMAGE_FILE_AGGRESSIVE_WS_TRIM)
656 printf(" IMAGE_FILE_AGGRESSIVE_WS_TRIM\n");
658 if (FileHeader->Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE)
659 printf(" IMAGE_FILE_LARGE_ADDRESS_AWARE\n");
661 if (FileHeader->Characteristics & IMAGE_FILE_16BIT_MACHINE)
662 printf(" IMAGE_FILE_16BIT_MACHINE\n");
664 if (FileHeader->Characteristics & IMAGE_FILE_BYTES_REVERSED_LO)
665 printf(" IMAGE_FILE_BYTES_REVERSED_LO\n");
667 if (FileHeader->Characteristics & IMAGE_FILE_32BIT_MACHINE)
668 printf(" IMAGE_FILE_32BIT_MACHINE\n");
670 if (FileHeader->Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
671 printf(" IMAGE_FILE_DEBUG_STRIPPED\n");
673 if (FileHeader->Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP)
674 printf(" IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP\n");
676 if (FileHeader->Characteristics & IMAGE_FILE_SYSTEM)
677 printf(" IMAGE_FILE_SYSTEM\n");
679 if (FileHeader->Characteristics & IMAGE_FILE_DLL)
680 printf(" IMAGE_FILE_DLL\n");
682 if (FileHeader->Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
683 printf(" IMAGE_FILE_UP_SYSTEM_ONLY\n");
685 if (FileHeader->Characteristics & IMAGE_FILE_BYTES_REVERSED_HI)
686 printf(" IMAGE_FILE_BYTES_REVERSED_HI\n");
691 void CoffLoader::PrintOptionHeader(OptionHeader_t *OptHdr)
693 printf("Option Header\n");
694 printf("------------------------------------------\n\n");
696 printf("Magic: 0x%04X\n", OptHdr->Magic);
697 printf("Linker Major Ver: 0x%02X\n", VERSION_MAJOR(OptHdr->LinkVersion));
698 printf("Linker Minor Ver: 0x%02X\n", VERSION_MINOR(OptHdr->LinkVersion));
699 printf("Code Size: 0x%08lX\n", OptHdr->CodeSize);
700 printf("Data Size: 0x%08lX\n", OptHdr->DataSize);
701 printf("BSS Size: 0x%08lX\n", OptHdr->BssSize);
702 printf("Entry: 0x%08lX\n", OptHdr->Entry);
703 printf("Code Base: 0x%08lX\n", OptHdr->CodeBase);
704 printf("Data Base: 0x%08lX\n", OptHdr->DataBase);
708 void CoffLoader::PrintWindowsHeader(WindowsHeader_t *WinHdr)
710 printf("Windows Specific Option Header\n");
711 printf("------------------------------------------\n\n");
713 printf("Image Base: 0x%08lX\n", WinHdr->ImageBase);
714 printf("Section Alignment: 0x%08lX\n", WinHdr->SectionAlignment);
715 printf("File Alignment: 0x%08lX\n", WinHdr->FileAlignment);
716 printf("OS Version: %d.%08d\n", BIGVERSION_MAJOR(WinHdr->OSVer), BIGVERSION_MINOR(WinHdr->OSVer));
717 printf("Image Version: %d.%08d\n", BIGVERSION_MAJOR(WinHdr->ImgVer), BIGVERSION_MINOR(WinHdr->ImgVer));
718 printf("SubSystem Version: %d.%08d\n", BIGVERSION_MAJOR(WinHdr->SubSysVer), BIGVERSION_MINOR(WinHdr->SubSysVer));
719 printf("Size of Image: 0x%08lX\n", WinHdr->SizeOfImage);
720 printf("Size of Headers: 0x%08lX\n", WinHdr->SizeOfHeaders);
721 printf("Checksum: 0x%08lX\n", WinHdr->CheckSum);
722 printf("Subsystem: 0x%04X\n", WinHdr->Subsystem);
723 printf("DLL Flags: 0x%04X\n", WinHdr->DLLFlags);
724 printf("Sizeof Stack Resv: 0x%08lX\n", WinHdr->SizeOfStackReserve);
725 printf("Sizeof Stack Comm: 0x%08lX\n", WinHdr->SizeOfStackCommit);
726 printf("Sizeof Heap Resv: 0x%08lX\n", WinHdr->SizeOfHeapReserve);
727 printf("Sizeof Heap Comm: 0x%08lX\n", WinHdr->SizeOfHeapCommit);
728 printf("Loader Flags: 0x%08lX\n", WinHdr->LoaderFlags);
729 printf("Num Directories: %ld\n", WinHdr->NumDirectories);
733 void CoffLoader::PrintSection(SectionHeader_t *ScnHdr, char* data)
737 strncpy(SectionName, (char *)ScnHdr->Name, 8);
739 printf("Section: %s\n", SectionName);
740 printf("------------------------------------------\n\n");
742 printf("Virtual Size: 0x%08lX\n", ScnHdr->VirtualSize);
743 printf("Virtual Address: 0x%08lX\n", ScnHdr->VirtualAddress);
744 printf("Sizeof Raw Data: 0x%08lX\n", ScnHdr->SizeOfRawData);
745 printf("Ptr To Raw Data: 0x%08lX\n", ScnHdr->PtrToRawData);
746 printf("Ptr To Relocations: 0x%08lX\n", ScnHdr->PtrToRelocations);
747 printf("Ptr To Line Nums: 0x%08lX\n", ScnHdr->PtrToLineNums);
748 printf("Num Relocations: 0x%04X\n", ScnHdr->NumRelocations);
749 printf("Num Line Numbers: 0x%04X\n", ScnHdr->NumLineNumbers);
750 printf("Characteristics: 0x%08lX\n", ScnHdr->Characteristics);
751 if (ScnHdr->Characteristics & IMAGE_SCN_CNT_CODE)
752 printf(" IMAGE_SCN_CNT_CODE\n");
753 if (ScnHdr->Characteristics & IMAGE_SCN_CNT_DATA)
754 printf(" IMAGE_SCN_CNT_DATA\n");
755 if (ScnHdr->Characteristics & IMAGE_SCN_CNT_BSS)
756 printf(" IMAGE_SCN_CNT_BSS\n");
757 if (ScnHdr->Characteristics & IMAGE_SCN_LNK_INFO)
758 printf(" IMAGE_SCN_LNK_INFO\n");
759 if (ScnHdr->Characteristics & IMAGE_SCN_LNK_REMOVE)
760 printf(" IMAGE_SCN_LNK_REMOVE\n");
761 if (ScnHdr->Characteristics & IMAGE_SCN_LNK_COMDAT)
762 printf(" IMAGE_SCN_LNK_COMDAT\n");
764 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_1BYTES)
765 printf(" IMAGE_SCN_ALIGN_1BYTES\n");
766 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_2BYTES)
767 printf(" IMAGE_SCN_ALIGN_2BYTES\n");
768 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_4BYTES)
769 printf(" IMAGE_SCN_ALIGN_4BYTES\n");
770 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_8BYTES)
771 printf(" IMAGE_SCN_ALIGN_8BYTES\n");
772 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_16BYTES)
773 printf(" IMAGE_SCN_ALIGN_16BYTES\n");
774 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_32BYTES)
775 printf(" IMAGE_SCN_ALIGN_32BYTES\n");
776 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_64BYTES)
777 printf(" IMAGE_SCN_ALIGN_64BYTES\n");
778 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_128BYTES)
779 printf(" IMAGE_SCN_ALIGN_128BYTES\n");
780 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_256BYTES)
781 printf(" IMAGE_SCN_ALIGN_256BYTES\n");
782 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_512BYTES)
783 printf(" IMAGE_SCN_ALIGN_512BYTES\n");
784 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_1024BYTES)
785 printf(" IMAGE_SCN_ALIGN_1024BYTES\n");
786 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_2048BYTES)
787 printf(" IMAGE_SCN_ALIGN_2048BYTES\n");
788 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_4096BYTES)
789 printf(" IMAGE_SCN_ALIGN_4096BYTES\n");
790 if ((ScnHdr->Characteristics & IMAGE_SCN_ALIGN_MASK) == IMAGE_SCN_ALIGN_8192BYTES)
791 printf(" IMAGE_SCN_ALIGN_8192BYTES\n");
793 if (ScnHdr->Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL)
794 printf(" IMAGE_SCN_LNK_NRELOC_OVFL\n");
795 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
796 printf(" IMAGE_SCN_MEM_DISCARDABLE\n");
797 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
798 printf(" IMAGE_SCN_MEM_NOT_CACHED\n");
799 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_NOT_PAGED)
800 printf(" IMAGE_SCN_MEM_NOT_PAGED\n");
801 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_SHARED)
802 printf(" IMAGE_SCN_MEM_SHARED\n");
803 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_EXECUTE)
804 printf(" IMAGE_SCN_MEM_EXECUTE\n");
805 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_READ)
806 printf(" IMAGE_SCN_MEM_READ\n");
807 if (ScnHdr->Characteristics & IMAGE_SCN_MEM_WRITE)
808 printf(" IMAGE_SCN_MEM_WRITE\n");
811 // Read the section Data, Relocations, & Line Nums
814 if (ScnHdr->SizeOfRawData > 0)
817 // Print the Raw Data
819 printf("\nRAW DATA");
820 for (i = 0; i < ScnHdr->VirtualSize; i++)
823 printf("\n %08X: ", i);
825 printf("%02X ", (unsigned int)ch);
832 if (ScnHdr->NumRelocations > 0)
834 // Print Section Relocations
837 fseek(fp, ScnHdr->PtrToRelocations/ * + CoffBeginOffset* /, SEEK_SET);
838 printf("RELOCATIONS\n");
839 printf(" Symbol Symbol\n");
840 printf(" Offset Type Index Name\n");
841 printf(" -------- -------- -------- ------\n");
842 for (int i = 0; i < ScnHdr->NumRelocations; i++)
844 fread(&ObjReloc, 1, sizeof(ObjReloc_t), fp);
845 printf(" %08X ", ObjReloc.VirtualAddress);
847 if (ObjReloc.Type == IMAGE_REL_I386_ABSOLUTE)
849 if (ObjReloc.Type == IMAGE_REL_I386_DIR16)
851 if (ObjReloc.Type == IMAGE_REL_I386_REL16)
853 if (ObjReloc.Type == IMAGE_REL_I386_DIR32)
855 if (ObjReloc.Type == IMAGE_REL_I386_DIR32NB)
857 if (ObjReloc.Type == IMAGE_REL_I386_SEG12)
859 if (ObjReloc.Type == IMAGE_REL_I386_SECTION)
861 if (ObjReloc.Type == IMAGE_REL_I386_SECREL)
863 if (ObjReloc.Type == IMAGE_REL_I386_REL32)
865 printf("%8X ", ObjReloc.SymTableIndex);
866 printf("%s\n", GetSymbolName(ObjReloc.SymTableIndex));
871 if (ScnHdr->NumLineNumbers > 0)
873 // Print The Line Number Info
874 LineNumbers_t LineNumber;
876 int BaseLineNum = -1;
878 fseek(fp, ScnHdr->PtrToLineNums/ * + CoffBeginOffset* /, SEEK_SET);
879 printf("LINE NUMBERS");
880 for (int i = 0; i < ScnHdr->NumLineNumbers; i++)
882 int LNOffset = ftell(fp);
884 fread(&LineNumber, 1, sizeof(LineNumbers_t), fp);
885 if (LineNumber.LineNum == 0)
891 SymIndex = LineNumber.Type.SymbolTableIndex;
892 Sym = &(SymTable[SymIndex]);
893 if (Sym->NumberOfAuxSymbols > 0)
895 Sym = &(SymTable[SymIndex+1]);
896 AuxFuncDef_t *FuncDef = (AuxFuncDef_t *)Sym;
898 if (FuncDef->PtrToLineNumber == LNOffset)
900 Sym = &(SymTable[FuncDef->TagIndex]);
901 if (Sym->NumberOfAuxSymbols > 0)
903 Sym = &(SymTable[FuncDef->TagIndex+1]);
904 AuxBfEf_t *Bf = (AuxBfEf_t *)Sym;
905 BaseLineNum = Bf->LineNumber;
909 printf(" Symbol Index: %8x ", SymIndex);
910 printf(" Base line number: %8d\n", BaseLineNum);
911 printf(" Symbol name = %s", GetSymbolName(SymIndex));
916 if ((LineCnt%4) == 0)
921 printf("%08X(%5d) ", LineNumber.Type.VirtualAddress,
922 LineNumber.LineNum + BaseLineNum);
934 int CoffLoader::ParseCoff(FILE *fp)
936 if ( !LoadCoffHModule(fp) )
938 printf("Failed to load/find COFF hModule header\n");
941 if ( !LoadSymTable(fp) ||
942 !LoadStringTable(fp) ||
955 void CoffLoader::PerformFixups(void)
961 EntryAddress = (unsigned long)RVA2Data(EntryAddress);
963 if( (PVOID)WindowsHeader->ImageBase == hModule )
969 if ( NumOfDirectories <= BASE_RELOCATION_TABLE )
972 if ( !Directory[BASE_RELOCATION_TABLE].Size )
975 FixupDataSize = Directory[BASE_RELOCATION_TABLE].Size;
976 FixupData = (char*)RVA2Data(Directory[BASE_RELOCATION_TABLE].RVA);
977 EndData = FixupData + FixupDataSize;
979 while (FixupData < EndData)
981 // Starting a new Fixup Block
982 unsigned long PageRVA = *((unsigned long*)FixupData);
984 unsigned long BlockSize = *((unsigned long*)FixupData);
988 for (unsigned int i = 0; i < BlockSize / 2; i++)
990 unsigned short Fixup = *((unsigned short*)FixupData);
992 int Type = (Fixup >> 12) & 0x0f;
994 if (Type == IMAGE_REL_BASED_HIGHLOW)
996 unsigned long *Off = (unsigned long*)RVA2Data(Fixup + PageRVA);
997 *Off = (unsigned long)RVA2Data(*Off - WindowsHeader->ImageBase);
999 else if (Type == IMAGE_REL_BASED_ABSOLUTE)
1003 printf("Unsupported fixup type!!\n");