Skip to content

Commit d93565f

Browse files
committed
Fix get_breakpoint_condition not finding conditions for absolute addresses (new fallback to address comparison and VA comparisons)
1 parent 0fc8275 commit d93565f

4 files changed

Lines changed: 57 additions & 24 deletions

File tree

core/debuggercontroller.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ DebuggerController::DebuggerController(BinaryViewRef data): BinaryDataNotificati
3232
m_data = data;
3333
m_data->RegisterNotification(this);
3434
m_viewStart = m_data->GetStart();
35+
m_originalFileBase = m_data->GetStart();
3536

3637
m_state = new DebuggerState(data, this);
3738
m_adapter = nullptr;

core/debuggercontroller.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ namespace BinaryNinjaDebugger {
8585
// this does not change even if we add the debugger memory region. In the future, this should be provided by
8686
// the binary view -- we will no longer need to track it ourselves
8787
uint64_t m_viewStart;
88+
// Original file base address before any rebasing - used for file address lookups
89+
uint64_t m_originalFileBase;
8890

8991
// inline static std::vector<DbgRef<DebuggerController>> g_debuggerControllers;
9092
static DbgRef<DebuggerController>* g_debuggerControllers;
@@ -393,6 +395,7 @@ namespace BinaryNinjaDebugger {
393395
bool ReAddDebuggerMemoryRegion();
394396

395397
uint64_t GetViewFileSegmentsStart() { return m_viewStart; }
398+
uint64_t GetOriginalFileBase() { return m_originalFileBase; }
396399

397400
bool ComputeExprValueAPI(const LowLevelILInstruction& instr, intx::uint512& value);
398401
bool ComputeExprValue(const LowLevelILInstruction& instr, intx::uint512& value);

core/debuggerstate.cpp

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ limitations under the License.
1818
#include <thread>
1919
#include <utility>
2020
#include <filesystem>
21+
#include <optional>
2122
#include "lowlevelilinstruction.h"
2223
#include "mediumlevelilinstruction.h"
2324
#include "highlevelilinstruction.h"
@@ -26,6 +27,8 @@ limitations under the License.
2627
#include "debugadapter.h"
2728
#include "debuggercontroller.h"
2829

30+
#include <ranges>
31+
2932
using namespace BinaryNinja;
3033
using namespace std;
3134
using namespace BinaryNinjaDebugger;
@@ -736,6 +739,42 @@ bool DebuggerBreakpoints::SetConditionOffset(const ModuleNameAndOffset& address,
736739
}
737740

738741

742+
std::optional<ModuleNameAndOffset> DebuggerBreakpoints::FindConditionKey(const ModuleNameAndOffset& address)
743+
{
744+
if (m_conditions.contains(address))
745+
return address;
746+
747+
// absolute address comparison (handles module name differences)
748+
// assumes conditions are stored with valid, resolvable module names
749+
const uint64_t targetAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(address);
750+
for (const auto& key : m_conditions | views::keys)
751+
{
752+
if (const uint64_t conditionAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(key);
753+
conditionAbsolute == targetAbsolute)
754+
return key;
755+
}
756+
757+
// if the address has empty module name, it might be a file virtual address?
758+
// try converting to an offset by subtracting the original file base.
759+
if (address.module.empty())
760+
{
761+
if (const uint64_t originalBase = m_state->GetController()->GetOriginalFileBase();
762+
address.offset >= originalBase)
763+
{
764+
const uint64_t fileOffset = address.offset - originalBase;
765+
const std::string& mainFile = m_state->GetController()->GetData()->GetFile()->GetOriginalFilename();
766+
for (const auto& key : m_conditions | views::keys)
767+
{
768+
if (key.offset == fileOffset && DebugModule::IsSameBaseModule(mainFile, key.module))
769+
return key;
770+
}
771+
}
772+
}
773+
774+
return std::nullopt;
775+
}
776+
777+
739778
std::string DebuggerBreakpoints::GetConditionAbsolute(const uint64_t address)
740779
{
741780
const ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(address);
@@ -745,17 +784,8 @@ std::string DebuggerBreakpoints::GetConditionAbsolute(const uint64_t address)
745784

746785
std::string DebuggerBreakpoints::GetConditionOffset(const ModuleNameAndOffset& address)
747786
{
748-
if (const auto iter = m_conditions.find(address); iter != m_conditions.end())
749-
return iter->second;
750-
751-
// fall back to absolute address comparison (handles module name differences)
752-
const uint64_t targetAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(address);
753-
for (const auto& [key, val] : m_conditions)
754-
{
755-
if (const uint64_t conditionAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(key);
756-
conditionAbsolute == targetAbsolute)
757-
return val;
758-
}
787+
if (const auto key = FindConditionKey(address))
788+
return m_conditions[*key];
759789
return "";
760790
}
761791

@@ -769,17 +799,8 @@ bool DebuggerBreakpoints::HasConditionAbsolute(const uint64_t address)
769799

770800
bool DebuggerBreakpoints::HasConditionOffset(const ModuleNameAndOffset& address)
771801
{
772-
if (const auto iter = m_conditions.find(address); iter != m_conditions.end())
773-
return !iter->second.empty();
774-
775-
// fall back to absolute address comparison (handles module name differences)
776-
const uint64_t targetAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(address);
777-
for (const auto& [key, val] : m_conditions)
778-
{
779-
if (const uint64_t conditionAbsolute = m_state->GetModules()->RelativeAddressToAbsolute(key);
780-
conditionAbsolute == targetAbsolute && !val.empty())
781-
return true;
782-
}
802+
if (const auto key = FindConditionKey(address))
803+
return !m_conditions[*key].empty();
783804
return false;
784805
}
785806

@@ -793,8 +814,11 @@ void DebuggerBreakpoints::ClearConditionAbsolute(const uint64_t address)
793814

794815
void DebuggerBreakpoints::ClearConditionOffset(const ModuleNameAndOffset& address)
795816
{
796-
m_conditions.erase(address);
797-
SerializeMetadata();
817+
if (const auto key = FindConditionKey(address))
818+
{
819+
m_conditions.erase(*key);
820+
SerializeMetadata();
821+
}
798822
}
799823

800824

core/debuggerstate.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ namespace BinaryNinjaDebugger {
113113
bool HasConditionOffset(const ModuleNameAndOffset& address);
114114
void ClearConditionAbsolute(uint64_t address);
115115
void ClearConditionOffset(const ModuleNameAndOffset& address);
116+
117+
private:
118+
// Helper to find the actual key in m_conditions matching the given address,
119+
// handling module name differences and file address fallback
120+
std::optional<ModuleNameAndOffset> FindConditionKey(const ModuleNameAndOffset& address);
116121
};
117122

118123

0 commit comments

Comments
 (0)