/// <summary> /// Parse the section headers. /// </summary> private void ParseSectionHdrs() { UInt32 byteSize, wordSize, numBytesInSectionHdr; UInt32 numSections; UInt64 flags; ELF_SectionHeader secHdr; EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); numBytesInSectionHdr = hdr.e_shentsize; numSections = (UInt32)headerRef["numSectionHdrs"]; if (numSections == (UInt32) ELF_SectionIndex.SHN_UNDEF) { // FIXME: Get the actual number of sections from the // sh_size field of the 0th section header table entry secHdr = ReadSectionHeader(0); numSections = (UInt32) secHdr.sh_size; headerRef["numSectionHdrs"] = (UInt32) secHdr.sh_size; } Debug.DebugMSG("Section Header Count: " + (UInt32)headerRef["numSectionHdrs"]); // Get Section Header String Table Section Header Index and Section Header String Table Section Address if (hdr.e_shstrndx == (UInt16) ELF_SectionIndex.SHN_UNDEF) { headerRef["stringTableAddr"] = null; headerRef["stringHeaderTableIndex"] = null; secHdr = new ELF_SectionHeader(); } else if (hdr.e_shstrndx == (UInt16) ELF_SectionIndex.SHN_XINDEX) { secHdr = ReadSectionHeader(0); headerRef["stringHeaderTableIndex"] = (UInt32) secHdr.sh_link; secHdr = ReadSectionHeader((UInt32) headerRef["stringHeaderTableIndex"]); headerRef["stringTableAddr"] = (UInt64) secHdr.sh_addr; } else { headerRef["stringHeaderTableIndex"] = (UInt32) hdr.e_shstrndx; secHdr = ReadSectionHeader((UInt32) headerRef["stringHeaderTableIndex"]); headerRef["stringTableAddr"] = (UInt64) (secHdr.sh_offset); } Debug.DebugMSG("Section Header Table Index for Section Header String Table: " + (UInt32)headerRef["stringHeaderTableIndex"]); Debug.DebugMSG("String Section Start Addr: 0x" + ((UInt64)headerRef["stringTableAddr"]).ToString("X8")); // Verify that the section header string table section is flagged as a string section flags = (UInt64) secHdr.sh_flags; if ( ( flags & ((UInt64) ELF_SectionFlag.SHF_STRINGS) ) == 0 ) { throw new Exception("Section Header String Section is not flagged with SHF_STRINGS."); } if (secHdr.sh_type != ELF_SectionType.SHT_STRTAB) { throw new Exception("Section Header String Section is not of type SHT_STRTAB."); } // Cycle through all sections, collecting info about each (name, type, etc.) sectionRef = new Hashtable[numSections]; for (UInt32 secNum = 0; secNum < numSections; secNum++) { secHdr = ReadSectionHeader((UInt32) secNum); sectionRef[secNum] = new Hashtable(); Debug.DebugMSG("Section Header Number = " + secNum); ebr.BaseStream.Seek((Int64)(secHdr.sh_name + (UInt64)headerRef["stringTableAddr"]), SeekOrigin.Begin); sectionRef[secNum]["name"] = ELF_getStringFromStringTable(); sectionRef[secNum]["type"] = (ELF_SectionType) secHdr.sh_type; sectionRef[secNum]["phyAddr"] = (UInt64) secHdr.sh_addr; sectionRef[secNum]["virAddr"] = (UInt64) secHdr.sh_addr; byteSize = (UInt32) secHdr.sh_size; wordSize = (byteSize + 3) >> 2; byteSize = wordSize << 2; sectionRef[secNum]["byteSize"] = byteSize; sectionRef[secNum]["wordSize"] = wordSize; sectionRef[secNum]["flags"] = (UInt64) secHdr.sh_flags; flags = (UInt64) sectionRef[secNum]["flags"]; // FIXME: Check to see if section should be copied to target sectionRef[secNum]["copyToTarget"] = false; if ( ( ((UInt64) sectionRef[secNum]["phyAddr"]) != 0 ) && ( ((UInt32) sectionRef[secNum]["byteSize"]) != 0 ) && ( ELF_SectionType.SHT_NULL != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_NOBITS != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_SYMTAB != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_DYNSYM != (ELF_SectionType)sectionRef[secNum]["type"] ) && ( ELF_SectionType.SHT_STRTAB != (ELF_SectionType)sectionRef[secNum]["type"] ) ) { if ( ( ELF_SectionType.SHT_PROGBITS == (ELF_SectionType)sectionRef[secNum]["type"] ) && ( (flags | ((UInt64) ELF_SectionFlag.SHF_ALLOC)) != 0x0 ) ) { headerRef["numTargetSections"] = ((UInt32)headerRef["numTargetSections"]) + 1; sectionRef[secNum]["copyToTarget"] = true; } } // If we think this section should be copied to target, make sure it is // in a loadable ELF program segment. If it is, then update physical // and virtual addresses. If not, then mark it as such. if ((Boolean) sectionRef[secNum]["copyToTarget"]) { for (UInt32 segmentNum = 0; segmentNum < (UInt32)hdr.e_phnum; segmentNum++) { ELF_SegmentHeader segmentHdr = ReadSegmentHeader((UInt32) segmentNum); // If the segment is of load type, check to see if the current section resides in it if (segmentHdr.p_type == ELF_SegmentType.PT_LOAD) { // Check if data is in the file, and if so then check if the section // is within this current header if ( ( segmentHdr.p_filesz != 0 ) && ( segmentHdr.p_vaddr <= (UInt64) secHdr.sh_addr) && ( (segmentHdr.p_vaddr + segmentHdr.p_filesz) > (UInt64) secHdr.sh_addr) ) { sectionRef[secNum]["phyAddr"] = (UInt64) segmentHdr.p_paddr; sectionRef[secNum]["virAddr"] = (UInt64) segmentHdr.p_vaddr; } } } } Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"name\"]: " + ((String)sectionRef[secNum]["name"]).ToString()); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"type\"]: " + ((ELF_SectionType)sectionRef[secNum]["type"]).ToString()); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"phyAddr\"]: " + ((UInt64)sectionRef[secNum]["phyAddr"]).ToString("X8")); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"virAddr\"]: " + ((UInt64)sectionRef[secNum]["virAddr"]).ToString("X8")); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"byteSize\"]: " + ((UInt32)sectionRef[secNum]["byteSize"]).ToString("X8")); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"wordSize\"]: " + ((UInt32)sectionRef[secNum]["wordSize"]).ToString("X8")); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"flags\"]: " + ((UInt64)sectionRef[secNum]["flags"]).ToString("X8")); Debug.DebugMSG("sectionRef[" + secNum.ToString() + "][\"copyToTarget\"]: " + (sectionRef[secNum]["copyToTarget"]).ToString()); Debug.DebugMSG(""); } }
/// <summary> /// Read the section header from the section header table /// </summary> private ELF_SectionHeader ReadSectionHeader(UInt32 index) { EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); ELF_SectionHeader sectionHeader = new ELF_SectionHeader(); // Seek to the start of the section header in section header table binFile.Seek((Int64)(hdr.e_shentsize * index + hdr.e_shoff), SeekOrigin.Begin); //Debug.DebugMSG( "Section["+index+"] = \n{"); sectionHeader.sh_name = ebr.ReadUInt32(); sectionHeader.sh_type = (ELF_SectionType) ebr.ReadUInt32(); //Debug.DebugMSG( " Section Name Index : " + sectionHeader.sh_name); //Debug.DebugMSG( " Section Type : " + sectionHeader.sh_type); if (ELF_FileClass.ELFCLASS_32 == hdr.e_ident.fileClass) { sectionHeader.sh_flags = (UInt64) ebr.ReadUInt32(); sectionHeader.sh_addr = (UInt64) ebr.ReadUInt32(); sectionHeader.sh_offset = (UInt64) ebr.ReadUInt32(); sectionHeader.sh_size = (UInt64) ebr.ReadUInt32(); /*Debug.DebugMSG( " Section Flags : 0x" + sectionHeader.sh_flags.ToString("X8")); Debug.DebugMSG( " Section Address : 0x" + sectionHeader.sh_addr.ToString("X8")); Debug.DebugMSG( " Section Offset : 0x" + sectionHeader.sh_offset.ToString("X8")); Debug.DebugMSG( " Section Size : 0x" + sectionHeader.sh_size.ToString("X8"));*/ } else { sectionHeader.sh_flags = ebr.ReadUInt64(); sectionHeader.sh_addr = ebr.ReadUInt64(); sectionHeader.sh_offset = ebr.ReadUInt64(); sectionHeader.sh_size = ebr.ReadUInt64(); /*Debug.DebugMSG( " Section Flags : 0x" + sectionHeader.sh_flags.ToString("X16")); Debug.DebugMSG( " Section Address : 0x" + sectionHeader.sh_addr.ToString("X16")); Debug.DebugMSG( " Section Offset : 0x" + sectionHeader.sh_offset.ToString("X16")); Debug.DebugMSG( " Section Size : 0x" + sectionHeader.sh_size.ToString("X16"));*/ } sectionHeader.sh_link = ebr.ReadUInt32(); sectionHeader.sh_info = ebr.ReadUInt32(); //Debug.DebugMSG( " Section Link Index : 0x" + sectionHeader.sh_flags.ToString("X8")); //Debug.DebugMSG( " Section Info Field : 0x" + sectionHeader.sh_addr.ToString("X8")); if (ELF_FileClass.ELFCLASS_32 == hdr.e_ident.fileClass) { sectionHeader.sh_addralign = (UInt64) ebr.ReadUInt32(); sectionHeader.sh_entsize = (UInt64) ebr.ReadUInt32(); //Debug.DebugMSG( " Section Addr Aligmnent : 0x" + sectionHeader.sh_addralign.ToString("X8")); //Debug.DebugMSG( " Section Entry Size : 0x" + sectionHeader.sh_entsize.ToString("X8")); } else { sectionHeader.sh_addralign = ebr.ReadUInt64(); sectionHeader.sh_entsize = ebr.ReadUInt64(); //Debug.DebugMSG( " Section Addr Aligmnent : 0x" + sectionHeader.sh_addralign.ToString("X16")); //Debug.DebugMSG( " Section Entry Size : 0x" + sectionHeader.sh_entsize.ToString("X16")); } //Debug.DebugMSG("}"); return sectionHeader; }