| 2561 | } |
| 2562 | |
| 2563 | void MachoView::ParseExportTrie(BinaryReader& reader, linkedit_data_command exportTrie) |
| 2564 | { |
| 2565 | try { |
| 2566 | uint32_t endGuard = exportTrie.datasize; |
| 2567 | DataBuffer buffer = GetParentView() |
| 2568 | ->ReadBuffer(m_universalImageOffset + exportTrie.dataoff, exportTrie.datasize); |
| 2569 | |
| 2570 | struct Node |
| 2571 | { |
| 2572 | uint64_t cursor; |
| 2573 | std::string text; |
| 2574 | }; |
| 2575 | std::vector<Node> stack; |
| 2576 | stack.reserve(64); |
| 2577 | stack.push_back({ /* cursor */ 0, /* text */ "" }); |
| 2578 | |
| 2579 | while (!stack.empty()) |
| 2580 | { |
| 2581 | m_logger->LogTrace("Export Trie: Processing node %s with cursor %llu", stack.back().text.c_str(), stack.back().cursor); |
| 2582 | Node node = std::move(stack.back()); |
| 2583 | stack.pop_back(); |
| 2584 | |
| 2585 | uint64_t cursor = node.cursor; |
| 2586 | const std::string currentText = std::move(node.text); |
| 2587 | |
| 2588 | if (cursor > endGuard) |
| 2589 | { |
| 2590 | m_logger->LogError("Export Trie: Cursor left trie during initial bounds check"); |
| 2591 | throw ReadException(); |
| 2592 | } |
| 2593 | |
| 2594 | size_t localCursor = cursor; |
| 2595 | uint64_t terminalSize = readValidULEB128(buffer, localCursor); |
| 2596 | uint64_t childOffset = localCursor + terminalSize; |
| 2597 | |
| 2598 | // If there's terminal data, define the symbol |
| 2599 | if (terminalSize != 0) |
| 2600 | { |
| 2601 | uint64_t flags = readValidULEB128(buffer, localCursor); |
| 2602 | uint64_t imageOffset = readValidULEB128(buffer, localCursor); |
| 2603 | m_logger->LogTrace("Export Trie: Found terminal node %s with flags %llx and image offset %llx", currentText.c_str(), flags, imageOffset); |
| 2604 | |
| 2605 | AddExportTerminalSymbol(currentText, flags, imageOffset); |
| 2606 | } |
| 2607 | |
| 2608 | localCursor = childOffset; |
| 2609 | if (localCursor > endGuard) |
| 2610 | { |
| 2611 | m_logger->LogError("Export Trie: Cursor left trie while moving to child offset"); |
| 2612 | throw ReadException(); |
| 2613 | } |
| 2614 | |
| 2615 | uint8_t childCount = buffer[localCursor++]; |
| 2616 | if (localCursor > endGuard) |
| 2617 | { |
| 2618 | m_logger->LogError("Export Trie: Cursor left trie while reading child count"); |
| 2619 | throw ReadException(); |
| 2620 | } |
nothing calls this directly
no test coverage detected