Skip to content

Commit

Permalink
Fix LLDB launch failure when an ELF binary has no dynamic loader. Fix V…
Browse files Browse the repository at this point in the history
  • Loading branch information
xusheng6 committed Dec 26, 2022
1 parent 07722c6 commit 7598c42
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
18 changes: 17 additions & 1 deletion core/adapters/lldbadapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ LldbAdapter::LldbAdapter(BinaryView* data) : DebugAdapter(data)
if (!m_debugger.IsValid())
LogWarn("Invalid debugger");

m_isElFWithoutDynamicLoader = IsELFWithoutDynamicLoader(data);

// Set auto-confirm to true so operations that ask for confirmation will proceed automatically.
// Otherwise, the confirmation prompt will be sent to the terminal that BN is launched from, which is a very
// confusing behavior.
Expand Down Expand Up @@ -132,6 +134,20 @@ void LldbAdapter::ApplyBreakpoints()
}


bool LldbAdapter::IsELFWithoutDynamicLoader(BinaryView* data)
{
if (!data)
return false;

auto name = data->GetTypeName();
if (name != "ELF")
return false;

auto syms = data->GetSymbolsByName("__elf_interp");
return syms.empty();
}


bool LldbAdapter::Execute(const std::string& path, const LaunchConfigurations& configs)
{
return ExecuteWithArgs(path, "", "", configs);
Expand Down Expand Up @@ -189,7 +205,7 @@ bool LldbAdapter::ExecuteWithArgs(const std::string& path, const std::string& ar
AddBreakpoint(ModuleNameAndOffset(path, m_entryPoint - m_start));

std::string launchCommand = "process launch";
if (Settings::Instance()->Get<bool>("debugger.stopAtSystemEntryPoint"))
if (Settings::Instance()->Get<bool>("debugger.stopAtSystemEntryPoint") || m_isElFWithoutDynamicLoader)
launchCommand += " --stop-at-entry";

if (configs.requestTerminalEmulator)
Expand Down
5 changes: 5 additions & 0 deletions core/adapters/lldbadapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ namespace BinaryNinjaDebugger {
bool m_targetActive;
std::vector<ModuleNameAndOffset> m_pendingBreakpoints {};

// To launch an ELF without dynamic loader, we must set `debugger.stopAtSystemEntryPoint`.
// Otherwise, the process will run freely on its own and not stop.
bool m_isElFWithoutDynamicLoader = false;
bool IsELFWithoutDynamicLoader(BinaryView* data);

public:
LldbAdapter(BinaryView* data);
virtual ~LldbAdapter();
Expand Down
6 changes: 0 additions & 6 deletions test/debugger_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,7 @@ def test_assembly_code(self):
fpath = name_to_fpath('asmtest', 'x86_64')
bv = BinaryViewType.get_view_of_file(fpath)
dbg = DebuggerController(bv)
if platform.system() == 'Linux':
Settings().set_bool('debugger.stopAtSystemEntryPoint', True)

self.assertTrue(dbg.launch())
if platform.system() == 'Linux':
Settings().set_bool('debugger.stopAtSystemEntryPoint', False)

entry = dbg.live_view.entry_point
self.assertEqual(dbg.ip, entry)

Expand Down

0 comments on commit 7598c42

Please sign in to comment.