MCPcopy Create free account
hub / github.com/lief-project/LIEF / parse_resource_node

Method parse_resource_node

src/PE/ResourceNode.cpp:84–205  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

82};
83
84std::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");

Callers

nothing calls this directly

Calls 5

peek_u16string_atMethod · 0.80
insertMethod · 0.45
sizeMethod · 0.45
idMethod · 0.45
nameMethod · 0.45

Tested by

no test coverage detected