Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/debuggerapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,10 @@ namespace BinaryNinjaDebuggerAPI {
void DeleteBreakpoint(const ModuleNameAndOffset& breakpoint);
void AddBreakpoint(uint64_t address);
void AddBreakpoint(const ModuleNameAndOffset& breakpoint);
void EnableBreakpoint(uint64_t address);
void EnableBreakpoint(const ModuleNameAndOffset& breakpoint);
void DisableBreakpoint(uint64_t address);
void DisableBreakpoint(const ModuleNameAndOffset& breakpoint);
bool ContainsBreakpoint(uint64_t address);
bool ContainsBreakpoint(const ModuleNameAndOffset& breakpoint);

Expand Down
24 changes: 24 additions & 0 deletions api/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,30 @@ void DebuggerController::AddBreakpoint(const ModuleNameAndOffset& breakpoint)
}


void DebuggerController::EnableBreakpoint(uint64_t address)
{
BNDebuggerEnableAbsoluteBreakpoint(m_object, address);
}


void DebuggerController::EnableBreakpoint(const ModuleNameAndOffset& breakpoint)
{
BNDebuggerEnableRelativeBreakpoint(m_object, breakpoint.module.c_str(), breakpoint.offset);
}


void DebuggerController::DisableBreakpoint(uint64_t address)
{
BNDebuggerDisableAbsoluteBreakpoint(m_object, address);
}


void DebuggerController::DisableBreakpoint(const ModuleNameAndOffset& breakpoint)
{
BNDebuggerDisableRelativeBreakpoint(m_object, breakpoint.module.c_str(), breakpoint.offset);
}


bool DebuggerController::ContainsBreakpoint(uint64_t address)
{
return BNDebuggerContainsAbsoluteBreakpoint(m_object, address);
Expand Down
10 changes: 10 additions & 0 deletions api/ffi.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ extern "C"
RelativeBreakpointAddedEvent,
AbsoluteBreakpointRemovedEvent,
RelativeBreakpointRemovedEvent,
AbsoluteBreakpointEnabledEvent,
RelativeBreakpointEnabledEvent,
AbsoluteBreakpointDisabledEvent,
RelativeBreakpointDisabledEvent,

ActiveThreadChangedEvent,

Expand Down Expand Up @@ -468,6 +472,12 @@ extern "C"
DEBUGGER_FFI_API void BNDebuggerAddAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
DEBUGGER_FFI_API void BNDebuggerAddRelativeBreakpoint(
BNDebuggerController* controller, const char* module, uint64_t offset);
DEBUGGER_FFI_API void BNDebuggerEnableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
DEBUGGER_FFI_API void BNDebuggerEnableRelativeBreakpoint(
BNDebuggerController* controller, const char* module, uint64_t offset);
DEBUGGER_FFI_API void BNDebuggerDisableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
DEBUGGER_FFI_API void BNDebuggerDisableRelativeBreakpoint(
BNDebuggerController* controller, const char* module, uint64_t offset);
DEBUGGER_FFI_API bool BNDebuggerContainsAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address);
DEBUGGER_FFI_API bool BNDebuggerContainsRelativeBreakpoint(
BNDebuggerController* controller, const char* module, uint64_t offset);
Expand Down
8 changes: 8 additions & 0 deletions core/debugadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ namespace BinaryNinjaDebugger {

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

virtual bool EnableBreakpoint(const std::uintptr_t address) { return false; }

virtual bool EnableBreakpoint(const ModuleNameAndOffset& address) { return false; }

virtual bool DisableBreakpoint(const std::uintptr_t address) { return false; }

virtual bool DisableBreakpoint(const ModuleNameAndOffset& address) { return false; }

virtual std::vector<DebugBreakpoint> GetBreakpointList() const = 0;

virtual std::unordered_map<std::string, DebugRegister> ReadAllRegisters() = 0;
Expand Down
40 changes: 40 additions & 0 deletions core/debuggercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,46 @@ void DebuggerController::DeleteBreakpoint(const ModuleNameAndOffset& address)
}


void DebuggerController::EnableBreakpoint(uint64_t address)
{
m_state->EnableBreakpoint(address);
DebuggerEvent event;
event.type = AbsoluteBreakpointEnabledEvent;
event.data.absoluteAddress = address;
PostDebuggerEvent(event);
}


void DebuggerController::EnableBreakpoint(const ModuleNameAndOffset& address)
{
m_state->EnableBreakpoint(address);
DebuggerEvent event;
event.type = RelativeBreakpointEnabledEvent;
event.data.relativeAddress = address;
PostDebuggerEvent(event);
}


void DebuggerController::DisableBreakpoint(uint64_t address)
{
m_state->DisableBreakpoint(address);
DebuggerEvent event;
event.type = AbsoluteBreakpointDisabledEvent;
event.data.absoluteAddress = address;
PostDebuggerEvent(event);
}


void DebuggerController::DisableBreakpoint(const ModuleNameAndOffset& address)
{
m_state->DisableBreakpoint(address);
DebuggerEvent event;
event.type = RelativeBreakpointDisabledEvent;
event.data.relativeAddress = address;
PostDebuggerEvent(event);
}


bool DebuggerController::SetIP(uint64_t address)
{
std::string ipRegisterName;
Expand Down
4 changes: 4 additions & 0 deletions core/debuggercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ namespace BinaryNinjaDebugger {
void AddBreakpoint(const ModuleNameAndOffset& address);
void DeleteBreakpoint(uint64_t address);
void DeleteBreakpoint(const ModuleNameAndOffset& address);
void EnableBreakpoint(uint64_t address);
void EnableBreakpoint(const ModuleNameAndOffset& address);
void DisableBreakpoint(uint64_t address);
void DisableBreakpoint(const ModuleNameAndOffset& address);
DebugBreakpoint GetAllBreakpoints();

// registers
Expand Down
98 changes: 98 additions & 0 deletions core/debuggerstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ bool DebuggerBreakpoints::AddAbsolute(uint64_t remoteAddress)
{
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
m_breakpoints.push_back(info);
m_enabledState[info] = true; // Enable by default
SerializeMetadata();
}

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

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

m_enabledState.erase(address); // Remove enabled state
SerializeMetadata();

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


bool DebuggerBreakpoints::EnableAbsolute(uint64_t remoteAddress)
{
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
return EnableOffset(info);
}


bool DebuggerBreakpoints::EnableOffset(const ModuleNameAndOffset& address)
{
if (!ContainsOffset(address))
return false;

m_enabledState[address] = true;
SerializeMetadata();

// If connected, make sure the breakpoint is active in the target
if (m_state->GetAdapter() && m_state->IsConnected())
{
uint64_t remoteAddress = m_state->GetModules()->RelativeAddressToAbsolute(address);
m_state->GetAdapter()->AddBreakpoint(remoteAddress);
return true;
}
return true;
}


bool DebuggerBreakpoints::DisableAbsolute(uint64_t remoteAddress)
{
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(remoteAddress);
return DisableOffset(info);
}


bool DebuggerBreakpoints::DisableOffset(const ModuleNameAndOffset& address)
{
if (!ContainsOffset(address))
return false;

m_enabledState[address] = false;
SerializeMetadata();

// If connected, remove the breakpoint from the target but keep it in our list
if (m_state->GetAdapter() && m_state->IsConnected())
{
uint64_t remoteAddress = m_state->GetModules()->RelativeAddressToAbsolute(address);
m_state->GetAdapter()->RemoveBreakpoint(remoteAddress);
return true;
}
return true;
}


bool DebuggerBreakpoints::IsEnabledAbsolute(uint64_t address)
{
ModuleNameAndOffset info = m_state->GetModules()->AbsoluteAddressToRelative(address);
return IsEnabledOffset(info);
}


bool DebuggerBreakpoints::IsEnabledOffset(const ModuleNameAndOffset& address)
{
auto iter = m_enabledState.find(address);
if (iter != m_enabledState.end())
return iter->second;

// Default to enabled if not explicitly set
return true;
}


bool DebuggerBreakpoints::ContainsOffset(const ModuleNameAndOffset& address)
{
// If there is no backend, then only check if the breakpoint is in the list
Expand Down Expand Up @@ -980,6 +1054,30 @@ void DebuggerState::DeleteBreakpoint(const ModuleNameAndOffset& address)
}


void DebuggerState::EnableBreakpoint(uint64_t address)
{
m_breakpoints->EnableAbsolute(address);
}


void DebuggerState::EnableBreakpoint(const ModuleNameAndOffset& address)
{
m_breakpoints->EnableOffset(address);
}


void DebuggerState::DisableBreakpoint(uint64_t address)
{
m_breakpoints->DisableAbsolute(address);
}


void DebuggerState::DisableBreakpoint(const ModuleNameAndOffset& address)
{
m_breakpoints->DisableOffset(address);
}


uint64_t DebuggerState::IP()
{
if (!IsConnected())
Expand Down
12 changes: 12 additions & 0 deletions core/debuggerstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

#pragma once

#include <unordered_map>
#include "binaryninjaapi.h"
#include "ui/uitypes.h"
#include "debugadaptertype.h"
Expand Down Expand Up @@ -82,15 +83,22 @@ namespace BinaryNinjaDebugger {
private:
DebuggerState* m_state;
std::vector<ModuleNameAndOffset> m_breakpoints;
std::unordered_map<ModuleNameAndOffset, bool> m_enabledState;

public:
DebuggerBreakpoints(DebuggerState* state, std::vector<ModuleNameAndOffset> initial = {});
bool AddAbsolute(uint64_t remoteAddress);
bool AddOffset(const ModuleNameAndOffset& address);
bool RemoveAbsolute(uint64_t remoteAddress);
bool RemoveOffset(const ModuleNameAndOffset& address);
bool EnableAbsolute(uint64_t remoteAddress);
bool EnableOffset(const ModuleNameAndOffset& address);
bool DisableAbsolute(uint64_t remoteAddress);
bool DisableOffset(const ModuleNameAndOffset& address);
bool ContainsAbsolute(uint64_t address);
bool ContainsOffset(const ModuleNameAndOffset& address);
bool IsEnabledAbsolute(uint64_t address);
bool IsEnabledOffset(const ModuleNameAndOffset& address);
void Apply();
void SerializeMetadata();
void UnserializedMetadata();
Expand Down Expand Up @@ -237,6 +245,10 @@ namespace BinaryNinjaDebugger {
void AddBreakpoint(const ModuleNameAndOffset& address);
void DeleteBreakpoint(uint64_t address);
void DeleteBreakpoint(const ModuleNameAndOffset& address);
void EnableBreakpoint(uint64_t address);
void EnableBreakpoint(const ModuleNameAndOffset& address);
void DisableBreakpoint(uint64_t address);
void DisableBreakpoint(const ModuleNameAndOffset& address);

uint64_t IP();
uint64_t StackPointer();
Expand Down
26 changes: 25 additions & 1 deletion core/ffi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,7 @@ BNDebugBreakpoint* BNDebuggerGetBreakpoints(BNDebuggerController* controller, si
for (size_t i = 0; i < breakpoints.size(); i++)
{
uint64_t remoteAddress = state->GetModules()->RelativeAddressToAbsolute(breakpoints[i]);
bool enabled = false;
bool enabled = state->GetBreakpoints()->IsEnabledOffset(breakpoints[i]);
result[i].module = BNDebuggerAllocString(breakpoints[i].module.c_str());
result[i].offset = breakpoints[i].offset;
result[i].address = remoteAddress;
Expand Down Expand Up @@ -825,6 +825,30 @@ void BNDebuggerAddRelativeBreakpoint(BNDebuggerController* controller, const cha
}


void BNDebuggerEnableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address)
{
controller->object->EnableBreakpoint(address);
}


void BNDebuggerEnableRelativeBreakpoint(BNDebuggerController* controller, const char* module, uint64_t offset)
{
controller->object->EnableBreakpoint(ModuleNameAndOffset(module, offset));
}


void BNDebuggerDisableAbsoluteBreakpoint(BNDebuggerController* controller, uint64_t address)
{
controller->object->DisableBreakpoint(address);
}


void BNDebuggerDisableRelativeBreakpoint(BNDebuggerController* controller, const char* module, uint64_t offset)
{
controller->object->DisableBreakpoint(ModuleNameAndOffset(module, offset));
}


uint64_t BNDebuggerGetIP(BNDebuggerController* controller)
{
return controller->object->GetCurrentIP();
Expand Down
Loading