| 82 | }; |
| 83 | |
| 84 | std::unique_ptr<ResourceNode> TreeParser::parse_resource_node( |
| 85 | const details::pe_resource_directory_table& directory_table, |
| 86 | uint32_t base_offset, uint32_t current_offset, uint32_t depth) |
| 87 | { |
| 88 | const uint32_t numberof_ID_entries = directory_table.NumberOfIDEntries; |
| 89 | const uint32_t numberof_name_entries = directory_table.NumberOfNameEntries; |
| 90 | |
| 91 | size_t directory_array_offset = current_offset + sizeof(details::pe_resource_directory_table); |
| 92 | details::pe_resource_directory_entries entries_array; |
| 93 | |
| 94 | if (auto res_entries_array = stream_.peek<details::pe_resource_directory_entries>(directory_array_offset)) { |
| 95 | entries_array = *res_entries_array; |
| 96 | } else { |
| 97 | return nullptr; |
| 98 | } |
| 99 | |
| 100 | auto directory = std::make_unique<ResourceDirectory>(directory_table); |
| 101 | directory->set_depth(depth); |
| 102 | |
| 103 | // Iterate over the childs |
| 104 | for (size_t idx = 0; idx < (numberof_name_entries + numberof_ID_entries); ++idx) { |
| 105 | |
| 106 | uint32_t data_rva = entries_array.RVA; |
| 107 | uint32_t id = entries_array.NameID.IntegerID; |
| 108 | |
| 109 | directory_array_offset += sizeof(details::pe_resource_directory_entries); |
| 110 | if (auto res_entries_array = stream_.peek<details::pe_resource_directory_entries>(directory_array_offset)) { |
| 111 | entries_array = *res_entries_array; |
| 112 | } else { |
| 113 | break; |
| 114 | } |
| 115 | |
| 116 | result<std::u16string> name; |
| 117 | |
| 118 | // Get the resource name |
| 119 | if ((id & 0x80000000) != 0u) { |
| 120 | uint32_t offset = id & (~ 0x80000000); |
| 121 | uint32_t string_offset = base_offset + offset; |
| 122 | LIEF_DEBUG("base_offset=0x{:04x}, string_offset=0x{:04x}", |
| 123 | base_offset, string_offset); |
| 124 | |
| 125 | auto res_length = stream_.peek<uint16_t>(string_offset); |
| 126 | if (res_length && *res_length <= 100) { |
| 127 | name = stream_.peek_u16string_at(string_offset + sizeof(uint16_t), *res_length); |
| 128 | if (!name) { |
| 129 | LIEF_ERR("Node's name for the node id: {} is corrupted", id); |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | if ((0x80000000 & data_rva) == 0) { // We are on a leaf |
| 135 | uint32_t offset = base_offset + data_rva; |
| 136 | details::pe_resource_data_entry data_entry; |
| 137 | |
| 138 | if (!visited_.insert(offset).second) { |
| 139 | if (visited_.size() == 1) { |
| 140 | // Only print once |
| 141 | LIEF_WARN("Infinite loop detected on resources"); |
nothing calls this directly
no test coverage detected