Skip to content

Commit 1c53ee1

Browse files
Copilotxusheng6
andcommitted
Add core enable/disable breakpoint functionality
Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com>
1 parent 7b6cc2f commit 1c53ee1

9 files changed

Lines changed: 225 additions & 1 deletion

api/debuggerapi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,10 @@ namespace BinaryNinjaDebuggerAPI {
719719
void DeleteBreakpoint(const ModuleNameAndOffset& breakpoint);
720720
void AddBreakpoint(uint64_t address);
721721
void AddBreakpoint(const ModuleNameAndOffset& breakpoint);
722+
void EnableBreakpoint(uint64_t address);
723+
void EnableBreakpoint(const ModuleNameAndOffset& breakpoint);
724+
void DisableBreakpoint(uint64_t address);
725+
void DisableBreakpoint(const ModuleNameAndOffset& breakpoint);
722726
bool ContainsBreakpoint(uint64_t address);
723727
bool ContainsBreakpoint(const ModuleNameAndOffset& breakpoint);
724728

api/debuggercontroller.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,30 @@ void DebuggerController::AddBreakpoint(const ModuleNameAndOffset& breakpoint)
760760
}
761761

762762

763+
void DebuggerController::EnableBreakpoint(uint64_t address)
764+
{
765+
BNDebuggerEnableAbsoluteBreakpoint(m_object, address);
766+
}
767+
768+
769+
void DebuggerController::EnableBreakpoint(const ModuleNameAndOffset& breakpoint)
770+
{
771+
BNDebuggerEnableRelativeBreakpoint(m_object, breakpoint.module.c_str(), breakpoint.offset);
772+
}
773+
774+
775+
void DebuggerController::DisableBreakpoint(uint64_t address)
776+
{
777+
BNDebuggerDisableAbsoluteBreakpoint(m_object, address);
778+
}
779+
780+
781+
void DebuggerController::DisableBreakpoint(const ModuleNameAndOffset& breakpoint)
782+
{
783+
BNDebuggerDisableRelativeBreakpoint(m_object, breakpoint.module.c_str(), breakpoint.offset);
784+
}
785+
786+
763787
bool DebuggerController::ContainsBreakpoint(uint64_t address)
764788
{
765789
return BNDebuggerContainsAbsoluteBreakpoint(m_object, address);

api/ffi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,10 @@ extern "C"
252252
RelativeBreakpointAddedEvent,
253253
AbsoluteBreakpointRemovedEvent,
254254
RelativeBreakpointRemovedEvent,
255+
AbsoluteBreakpointEnabledEvent,
256+
RelativeBreakpointEnabledEvent,
257+
AbsoluteBreakpointDisabledEvent,
258+
RelativeBreakpointDisabledEvent,
255259

256260
ActiveThreadChangedEvent,
257261

@@ -583,6 +587,12 @@ extern "C"
583587
DEBUGGER_FFI_API void BNDebuggerAddAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
584588
DEBUGGER_FFI_API void BNDebuggerAddRelativeBreakpoint(
585589
BNDebuggerController* controller, const char* module, uint64_t offset);
590+
DEBUGGER_FFI_API void BNDebuggerEnableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
591+
DEBUGGER_FFI_API void BNDebuggerEnableRelativeBreakpoint(
592+
BNDebuggerController* controller, const char* module, uint64_t offset);
593+
DEBUGGER_FFI_API void BNDebuggerDisableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
594+
DEBUGGER_FFI_API void BNDebuggerDisableRelativeBreakpoint(
595+
BNDebuggerController* controller, const char* module, uint64_t offset);
586596
DEBUGGER_FFI_API bool BNDebuggerContainsAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
587597
DEBUGGER_FFI_API bool BNDebuggerContainsRelativeBreakpoint(
588598
BNDebuggerController* controller, const char* module, uint64_t offset);

core/debugadapter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,14 @@ namespace BinaryNinjaDebugger {
264264

265265
virtual bool RemoveBreakpoint(const ModuleNameAndOffset& address) { return false; }
266266

267+
virtual bool EnableBreakpoint(const std::uintptr_t address) { return false; }
268+
269+
virtual bool EnableBreakpoint(const ModuleNameAndOffset& address) { return false; }
270+
271+
virtual bool DisableBreakpoint(const std::uintptr_t address) { return false; }
272+
273+
virtual bool DisableBreakpoint(const ModuleNameAndOffset& address) { return false; }
274+
267275
virtual std::vector<DebugBreakpoint> GetBreakpointList() const = 0;
268276

269277
virtual std::unordered_map<std::string, DebugRegister> ReadAllRegisters() = 0;

core/debuggercontroller.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,46 @@ void DebuggerController::DeleteBreakpoint(const ModuleNameAndOffset& address)
100100
}
101101

102102

103+
void DebuggerController::EnableBreakpoint(uint64_t address)
104+
{
105+
m_state->EnableBreakpoint(address);
106+
DebuggerEvent event;
107+
event.type = AbsoluteBreakpointEnabledEvent;
108+
event.data.absoluteAddress = address;
109+
PostDebuggerEvent(event);
110+
}
111+
112+
113+
void DebuggerController::EnableBreakpoint(const ModuleNameAndOffset& address)
114+
{
115+
m_state->EnableBreakpoint(address);
116+
DebuggerEvent event;
117+
event.type = RelativeBreakpointEnabledEvent;
118+
event.data.relativeAddress = address;
119+
PostDebuggerEvent(event);
120+
}
121+
122+
123+
void DebuggerController::DisableBreakpoint(uint64_t address)
124+
{
125+
m_state->DisableBreakpoint(address);
126+
DebuggerEvent event;
127+
event.type = AbsoluteBreakpointDisabledEvent;
128+
event.data.absoluteAddress = address;
129+
PostDebuggerEvent(event);
130+
}
131+
132+
133+
void DebuggerController::DisableBreakpoint(const ModuleNameAndOffset& address)
134+
{
135+
m_state->DisableBreakpoint(address);
136+
DebuggerEvent event;
137+
event.type = RelativeBreakpointDisabledEvent;
138+
event.data.relativeAddress = address;
139+
PostDebuggerEvent(event);
140+
}
141+
142+
103143
bool DebuggerController::SetIP(uint64_t address)
104144
{
105145
std::string ipRegisterName;

core/debuggercontroller.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ namespace BinaryNinjaDebugger {
227227
void AddBreakpoint(const ModuleNameAndOffset& address);
228228
void DeleteBreakpoint(uint64_t address);
229229
void DeleteBreakpoint(const ModuleNameAndOffset& address);
230+
void EnableBreakpoint(uint64_t address);
231+
void EnableBreakpoint(const ModuleNameAndOffset& address);
232+
void DisableBreakpoint(uint64_t address);
233+
void DisableBreakpoint(const ModuleNameAndOffset& address);
230234
DebugBreakpoint GetAllBreakpoints();
231235

232236
// registers

core/debuggerstate.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ bool DebuggerBreakpoints::AddAbsolute(uint64_t remoteAddress)
534534
{
535535
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
536536
m_breakpoints.push_back(info);
537+
m_enabledState[info] = true; // Enable by default
537538
SerializeMetadata();
538539
}
539540

@@ -546,6 +547,7 @@ bool DebuggerBreakpoints::AddOffset(const ModuleNameAndOffset& address)
546547
if (!ContainsOffset(address))
547548
{
548549
m_breakpoints.push_back(address);
550+
m_enabledState[address] = true; // Enable by default
549551
SerializeMetadata();
550552

551553
// If the adapter is already created, we ask it to add the breakpoint.
@@ -574,6 +576,7 @@ bool DebuggerBreakpoints::RemoveAbsolute(uint64_t remoteAddress)
574576
{
575577
m_breakpoints.erase(iter);
576578
}
579+
m_enabledState.erase(info); // Remove enabled state
577580
SerializeMetadata();
578581
m_state->GetAdapter()->RemoveBreakpoint(remoteAddress);
579582
return true;
@@ -589,6 +592,7 @@ bool DebuggerBreakpoints::RemoveOffset(const ModuleNameAndOffset& address)
589592
if (auto iter = std::find(m_breakpoints.begin(), m_breakpoints.end(), address); iter != m_breakpoints.end())
590593
m_breakpoints.erase(iter);
591594

595+
m_enabledState.erase(address); // Remove enabled state
592596
SerializeMetadata();
593597

594598
if (m_state->GetAdapter() && m_state->IsConnected())
@@ -603,6 +607,76 @@ bool DebuggerBreakpoints::RemoveOffset(const ModuleNameAndOffset& address)
603607
}
604608

605609

610+
bool DebuggerBreakpoints::EnableAbsolute(uint64_t remoteAddress)
611+
{
612+
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
613+
return EnableOffset(info);
614+
}
615+
616+
617+
bool DebuggerBreakpoints::EnableOffset(const ModuleNameAndOffset& address)
618+
{
619+
if (!ContainsOffset(address))
620+
return false;
621+
622+
m_enabledState[address] = true;
623+
SerializeMetadata();
624+
625+
// If connected, make sure the breakpoint is active in the target
626+
if (m_state->GetAdapter() && m_state->IsConnected())
627+
{
628+
uint64_t remoteAddress = m_state->GetModules()->RelativeAddressToAbsolute(address);
629+
m_state->GetAdapter()->AddBreakpoint(remoteAddress);
630+
return true;
631+
}
632+
return true;
633+
}
634+
635+
636+
bool DebuggerBreakpoints::DisableAbsolute(uint64_t remoteAddress)
637+
{
638+
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
639+
return DisableOffset(info);
640+
}
641+
642+
643+
bool DebuggerBreakpoints::DisableOffset(const ModuleNameAndOffset& address)
644+
{
645+
if (!ContainsOffset(address))
646+
return false;
647+
648+
m_enabledState[address] = false;
649+
SerializeMetadata();
650+
651+
// If connected, remove the breakpoint from the target but keep it in our list
652+
if (m_state->GetAdapter() && m_state->IsConnected())
653+
{
654+
uint64_t remoteAddress = m_state->GetModules()->RelativeAddressToAbsolute(address);
655+
m_state->GetAdapter()->RemoveBreakpoint(remoteAddress);
656+
return true;
657+
}
658+
return true;
659+
}
660+
661+
662+
bool DebuggerBreakpoints::IsEnabledAbsolute(uint64_t address)
663+
{
664+
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(address);
665+
return IsEnabledOffset(info);
666+
}
667+
668+
669+
bool DebuggerBreakpoints::IsEnabledOffset(const ModuleNameAndOffset& address)
670+
{
671+
auto iter = m_enabledState.find(address);
672+
if (iter != m_enabledState.end())
673+
return iter->second;
674+
675+
// Default to enabled if not explicitly set
676+
return true;
677+
}
678+
679+
606680
bool DebuggerBreakpoints::ContainsOffset(const ModuleNameAndOffset& address)
607681
{
608682
// If there is no backend, then only check if the breakpoint is in the list
@@ -980,6 +1054,30 @@ void DebuggerState::DeleteBreakpoint(const ModuleNameAndOffset& address)
9801054
}
9811055

9821056

1057+
void DebuggerState::EnableBreakpoint(uint64_t address)
1058+
{
1059+
m_breakpoints->EnableAbsolute(address);
1060+
}
1061+
1062+
1063+
void DebuggerState::EnableBreakpoint(const ModuleNameAndOffset& address)
1064+
{
1065+
m_breakpoints->EnableOffset(address);
1066+
}
1067+
1068+
1069+
void DebuggerState::DisableBreakpoint(uint64_t address)
1070+
{
1071+
m_breakpoints->DisableAbsolute(address);
1072+
}
1073+
1074+
1075+
void DebuggerState::DisableBreakpoint(const ModuleNameAndOffset& address)
1076+
{
1077+
m_breakpoints->DisableOffset(address);
1078+
}
1079+
1080+
9831081
uint64_t DebuggerState::IP()
9841082
{
9851083
if (!IsConnected())

core/debuggerstate.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616

1717
#pragma once
1818

19+
#include <unordered_map>
1920
#include "binaryninjaapi.h"
2021
#include "ui/uitypes.h"
2122
#include "debugadaptertype.h"
@@ -82,15 +83,22 @@ namespace BinaryNinjaDebugger {
8283
private:
8384
DebuggerState* m_state;
8485
std::vector<ModuleNameAndOffset> m_breakpoints;
86+
std::unordered_map<ModuleNameAndOffset, bool> m_enabledState;
8587

8688
public:
8789
DebuggerBreakpoints(DebuggerState* state, std::vector<ModuleNameAndOffset> initial = {});
8890
bool AddAbsolute(uint64_t remoteAddress);
8991
bool AddOffset(const ModuleNameAndOffset& address);
9092
bool RemoveAbsolute(uint64_t remoteAddress);
9193
bool RemoveOffset(const ModuleNameAndOffset& address);
94+
bool EnableAbsolute(uint64_t remoteAddress);
95+
bool EnableOffset(const ModuleNameAndOffset& address);
96+
bool DisableAbsolute(uint64_t remoteAddress);
97+
bool DisableOffset(const ModuleNameAndOffset& address);
9298
bool ContainsAbsolute(uint64_t address);
9399
bool ContainsOffset(const ModuleNameAndOffset& address);
100+
bool IsEnabledAbsolute(uint64_t address);
101+
bool IsEnabledOffset(const ModuleNameAndOffset& address);
94102
void Apply();
95103
void SerializeMetadata();
96104
void UnserializedMetadata();
@@ -237,6 +245,10 @@ namespace BinaryNinjaDebugger {
237245
void AddBreakpoint(const ModuleNameAndOffset& address);
238246
void DeleteBreakpoint(uint64_t address);
239247
void DeleteBreakpoint(const ModuleNameAndOffset& address);
248+
void EnableBreakpoint(uint64_t address);
249+
void EnableBreakpoint(const ModuleNameAndOffset& address);
250+
void DisableBreakpoint(uint64_t address);
251+
void DisableBreakpoint(const ModuleNameAndOffset& address);
240252

241253
uint64_t IP();
242254
uint64_t StackPointer();

core/ffi.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ BNDebugBreakpoint* BNDebuggerGetBreakpoints(BNDebuggerController* controller, si
813813
for (size_t i = 0; i < breakpoints.size(); i++)
814814
{
815815
uint64_t remoteAddress = state->GetModules()->RelativeAddressToAbsolute(breakpoints[i]);
816-
bool enabled = false;
816+
bool enabled = state->GetBreakpoints()->IsEnabledOffset(breakpoints[i]);
817817
result[i].module = BNDebuggerAllocString(breakpoints[i].module.c_str());
818818
result[i].offset = breakpoints[i].offset;
819819
result[i].address = remoteAddress;
@@ -857,6 +857,30 @@ void BNDebuggerAddRelativeBreakpoint(BNDebuggerController* controller, const cha
857857
}
858858

859859

860+
void BNDebuggerEnableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address)
861+
{
862+
controller->object->EnableBreakpoint(address);
863+
}
864+
865+
866+
void BNDebuggerEnableRelativeBreakpoint(BNDebuggerController* controller, const char* module, uint64_t offset)
867+
{
868+
controller->object->EnableBreakpoint(ModuleNameAndOffset(module, offset));
869+
}
870+
871+
872+
void BNDebuggerDisableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address)
873+
{
874+
controller->object->DisableBreakpoint(address);
875+
}
876+
877+
878+
void BNDebuggerDisableRelativeBreakpoint(BNDebuggerController* controller, const char* module, uint64_t offset)
879+
{
880+
controller->object->DisableBreakpoint(ModuleNameAndOffset(module, offset));
881+
}
882+
883+
860884
uint64_t BNDebuggerGetIP(BNDebuggerController* controller)
861885
{
862886
return controller->object->GetCurrentIP();

0 commit comments

Comments
 (0)