Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "courgette/disassembler_elf_32.h" | 5 #include "courgette/disassembler_elf_32.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 | 47 |
| 48 if (header_->e_machine != ElfEM()) | 48 if (header_->e_machine != ElfEM()) |
| 49 return Bad("Not a supported architecture"); | 49 return Bad("Not a supported architecture"); |
| 50 | 50 |
| 51 if (header_->e_version != 1) | 51 if (header_->e_version != 1) |
| 52 return Bad("Unknown file version"); | 52 return Bad("Unknown file version"); |
| 53 | 53 |
| 54 if (header_->e_shentsize != sizeof(Elf32_Shdr)) | 54 if (header_->e_shentsize != sizeof(Elf32_Shdr)) |
| 55 return Bad("Unexpected section header size"); | 55 return Bad("Unexpected section header size"); |
| 56 | 56 |
| 57 if (header_->e_shoff >= length()) | 57 if (!IsArrayInBounds(header_->e_shoff, header_->e_shnum, sizeof(Elf32_Shdr))) |
| 58 return Bad("Out of bounds section header table offset"); | 58 return Bad("Out of bounds section header table"); |
| 59 | 59 |
| 60 section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff); | 60 section_header_table_ = (Elf32_Shdr *)OffsetToPointer(header_->e_shoff); |
| 61 section_header_table_size_ = header_->e_shnum; | 61 section_header_table_size_ = header_->e_shnum; |
| 62 | 62 |
| 63 if ((header_->e_shoff + header_->e_shnum ) >= length()) | 63 if (!IsArrayInBounds(header_->e_phoff, header_->e_phnum, sizeof(Elf32_Phdr))) |
| 64 return Bad("Out of bounds section header table"); | 64 return Bad("Out of bounds program header table"); |
| 65 | |
| 66 if (header_->e_phoff >= length()) | |
| 67 return Bad("Out of bounds program header table offset"); | |
| 68 | 65 |
| 69 program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff); | 66 program_header_table_ = (Elf32_Phdr *)OffsetToPointer(header_->e_phoff); |
| 70 program_header_table_size_ = header_->e_phnum; | 67 program_header_table_size_ = header_->e_phnum; |
| 71 | 68 |
| 72 if ((header_->e_phoff + header_->e_phnum) >= length()) | 69 if (header_->e_shstrndx >= header_->e_shnum) |
| 73 return Bad("Out of bounds program header table"); | 70 return Bad("Out of bounds string section index"); |
| 74 | 71 |
| 75 default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx); | 72 default_string_section_ = (const char *)SectionBody((int)header_->e_shstrndx); |
| 76 | 73 |
| 77 ReduceLength(DiscoverLength()); | 74 if (!UpdateLength()) { |
| 75 return Bad("Out of bounds section or segment"); | |
| 76 } | |
| 78 | 77 |
| 79 return Good(); | 78 return Good(); |
| 80 } | 79 } |
| 81 | 80 |
| 82 bool DisassemblerElf32::Disassemble(AssemblyProgram* target) { | 81 bool DisassemblerElf32::Disassemble(AssemblyProgram* target) { |
| 83 if (!ok()) | 82 if (!ok()) |
| 84 return false; | 83 return false; |
| 85 | 84 |
| 86 // The Image Base is always 0 for ELF Executables | 85 // The Image Base is always 0 for ELF Executables |
| 87 target->set_image_base(0); | 86 target->set_image_base(0); |
| 88 | 87 |
| 89 if (!ParseAbs32Relocs()) | 88 if (!ParseAbs32Relocs()) |
| 90 return false; | 89 return false; |
| 91 | 90 |
| 92 if (!ParseRel32RelocsFromSections()) | 91 if (!ParseRel32RelocsFromSections()) |
| 93 return false; | 92 return false; |
| 94 | 93 |
| 95 if (!ParseFile(target)) | 94 if (!ParseFile(target)) |
| 96 return false; | 95 return false; |
| 97 | 96 |
| 98 target->DefaultAssignIndexes(); | 97 target->DefaultAssignIndexes(); |
| 99 | 98 |
| 100 return true; | 99 return true; |
| 101 } | 100 } |
| 102 | 101 |
| 103 uint32 DisassemblerElf32::DiscoverLength() { | 102 bool DisassemblerElf32::UpdateLength() { |
| 104 uint32 result = 0; | 103 uint32 result = 0; |
|
rickyz (no longer on Chrome)
2015/03/23 23:14:50
Mind changing this to an Elf32_Off as well?
halyavin2
2015/03/24 14:35:18
Done.
I just realized there is one more bug to f
| |
| 105 | 104 |
| 106 // Find the end of the last section | 105 // Find the end of the last section |
| 107 for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) { | 106 for (int section_id = 0; section_id < SectionHeaderCount(); section_id++) { |
| 108 const Elf32_Shdr *section_header = SectionHeader(section_id); | 107 const Elf32_Shdr *section_header = SectionHeader(section_id); |
| 109 | 108 |
| 110 if (section_header->sh_type == SHT_NOBITS) | 109 if (section_header->sh_type == SHT_NOBITS) |
| 111 continue; | 110 continue; |
| 112 | 111 |
| 112 if (!IsArrayInBounds(section_header->sh_offset, section_header->sh_size, 1)) | |
| 113 return false; | |
| 114 | |
| 113 uint32 section_end = section_header->sh_offset + section_header->sh_size; | 115 uint32 section_end = section_header->sh_offset + section_header->sh_size; |
| 114 | 116 result = std::max(result, section_end); |
| 115 if (section_end > result) | |
| 116 result = section_end; | |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Find the end of the last segment | 119 // Find the end of the last segment |
| 120 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { | 120 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { |
| 121 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); | 121 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); |
| 122 | 122 |
| 123 if (!IsArrayInBounds(segment_header->p_offset, segment_header->p_filesz, 1)) | |
| 124 return false; | |
| 125 | |
| 123 uint32 segment_end = segment_header->p_offset + segment_header->p_filesz; | 126 uint32 segment_end = segment_header->p_offset + segment_header->p_filesz; |
| 124 | 127 result = std::max(result, segment_end); |
| 125 if (segment_end > result) | |
| 126 result = segment_end; | |
| 127 } | 128 } |
| 128 | 129 |
| 129 uint32 section_table_end = header_->e_shoff + | 130 uint32 section_table_end = header_->e_shoff + |
| 130 (header_->e_shnum * sizeof(Elf32_Shdr)); | 131 (header_->e_shnum * sizeof(Elf32_Shdr)); |
| 131 if (section_table_end > result) | 132 result = std::max(result, section_table_end); |
| 132 result = section_table_end; | |
| 133 | 133 |
| 134 uint32 segment_table_end = header_->e_phoff + | 134 uint32 segment_table_end = header_->e_phoff + |
| 135 (header_->e_phnum * sizeof(Elf32_Phdr)); | 135 (header_->e_phnum * sizeof(Elf32_Phdr)); |
| 136 if (segment_table_end > result) | 136 result = std::max(result, segment_table_end); |
| 137 result = segment_table_end; | |
| 138 | 137 |
| 139 return result; | 138 ReduceLength(result); |
| 139 return true; | |
| 140 } | 140 } |
| 141 | 141 |
| 142 CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const { | 142 CheckBool DisassemblerElf32::IsValidRVA(RVA rva) const { |
| 143 | 143 |
| 144 // It's valid if it's contained in any program segment | 144 // It's valid if it's contained in any program segment |
| 145 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { | 145 for (int i = 0; i < ProgramSegmentHeaderCount(); i++) { |
| 146 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); | 146 const Elf32_Phdr *segment_header = ProgramSegmentHeader(i); |
| 147 | 147 |
| 148 if (segment_header->p_type != PT_LOAD) | 148 if (segment_header->p_type != PT_LOAD) |
| 149 continue; | 149 continue; |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 return false; | 494 return false; |
| 495 } | 495 } |
| 496 | 496 |
| 497 std::sort(rel32_locations_.begin(), | 497 std::sort(rel32_locations_.begin(), |
| 498 rel32_locations_.end(), | 498 rel32_locations_.end(), |
| 499 TypedRVA::IsLessThan); | 499 TypedRVA::IsLessThan); |
| 500 return true; | 500 return true; |
| 501 } | 501 } |
| 502 | 502 |
| 503 } // namespace courgette | 503 } // namespace courgette |
| OLD | NEW |