From 7598c4225e619363dfb5277a8f282d55f924d1a2 Mon Sep 17 00:00:00 2001 From: Xusheng Date: Mon, 26 Dec 2022 12:19:05 +0800 Subject: [PATCH] Fix LLDB launch failure when an ELF binary has no dynamic loader. Fix https://github.com/Vector35/debugger/issues/407 --- core/adapters/lldbadapter.cpp | 18 +++++++++++++++++- core/adapters/lldbadapter.h | 5 +++++ test/debugger_test.py | 6 ------ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/core/adapters/lldbadapter.cpp b/core/adapters/lldbadapter.cpp index 37a00ff7..e90cab1c 100644 --- a/core/adapters/lldbadapter.cpp +++ b/core/adapters/lldbadapter.cpp @@ -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. @@ -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); @@ -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("debugger.stopAtSystemEntryPoint")) + if (Settings::Instance()->Get("debugger.stopAtSystemEntryPoint") || m_isElFWithoutDynamicLoader) launchCommand += " --stop-at-entry"; if (configs.requestTerminalEmulator) diff --git a/core/adapters/lldbadapter.h b/core/adapters/lldbadapter.h index fc25248c..a6f54bd9 100644 --- a/core/adapters/lldbadapter.h +++ b/core/adapters/lldbadapter.h @@ -36,6 +36,11 @@ namespace BinaryNinjaDebugger { bool m_targetActive; std::vector 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(); diff --git a/test/debugger_test.py b/test/debugger_test.py index 70a7a946..0bf57f70 100644 --- a/test/debugger_test.py +++ b/test/debugger_test.py @@ -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)