| 75 | } |
| 76 | |
| 77 | bool AnalyzerBase::apply_relocation(const Relocation& R) { |
| 78 | // As of Binary Ninja version 5.2.8133 (2025-08-DD), the |
| 79 | // `BinaryView::DefineRelocation` method does not effectively apply a new |
| 80 | // relocation to an existing binary view. |
| 81 | // |
| 82 | // To work around this limitation, we manually write the resolved relocation |
| 83 | // value at the specified address. |
| 84 | // |
| 85 | // However, this approach has a drawback: any subsequent (re)rebase operations |
| 86 | // may not be consistent with the changes made. |
| 87 | assert(R.size() != -1); |
| 88 | auto resolved = R.resolve(bv_.GetImageBase()); |
| 89 | if (!resolved) { |
| 90 | return false; |
| 91 | } |
| 92 | |
| 93 | const size_t reloc_bytes_size = R.size() / 8; |
| 94 | uint64_t taddr = translate_addr(R.address()); |
| 95 | uint64_t content = 0; // for implicit addend |
| 96 | bv_.Read(&content, taddr, reloc_bytes_size); |
| 97 | uint64_t value = *resolved + content; |
| 98 | |
| 99 | // Ensure that the resolved address is in the memory range of the program. |
| 100 | // This check also prevent from running twice relocation on the same address. |
| 101 | if ((R.is_rela() || R.is_android_packed()) && content > 0) { |
| 102 | BN_INFO("Relocation 0x{:010x} already processed", taddr); |
| 103 | return true; |
| 104 | } |
| 105 | |
| 106 | bv_.Write(taddr, &value, reloc_bytes_size); |
| 107 | define_relocated_type(R, value); |
| 108 | return true; |
| 109 | } |
| 110 | |
| 111 | void AnalyzerBase::define_relocated_type(const Relocation& R, uint64_t ttarget) { |
| 112 | uint64_t taddr = translate_addr(R.address()); |