欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]修正lldb-310及以后版本的Thumb反汇编问题

[原创]修正lldb-310及以后版本的Thumb反汇编问题


此方法仅仅是临时修改方案!
This is just a dirty fix!  

前提
1.ARMv7s程序
2.使用Thumb2指令集
3.无完整符号信息
问题
lldb执行反汇编时需要确定该地址的指令集,lldb会利用FunctionStarts中的地址生成符号信息。这样即使没有完整调试符号,使用lldb也进行基本的汇编级调试。如果某一个地址查询不到任何符号,那么lldb将默认以ARM指令集去处理后续工作。符号解析过程需要主程序的节表中的一些信息,空节表会导致无法正常完成符号解析过程。
跟踪解析符号可以发现其中用到了LINKEDIT段的地址。这一数据就是从节表中查询得来的,如果节表为空,将返回无效地址(-1)。但符号解析相关的代码直接使用了查询结果,并未判断此地址是否有效。
在lldb-310中,由于意外的清空了节表, 导致后续的符号解析过程出错,从而损失了本应存在的符号信息。这就是lldb-310以后没有完整调试符号时无法反汇编及追踪使用Thumb2指令集的代码块的原因。
解决方法
修改源代码
找到Source/Target/Target.cpp
将Target::SetExecutableModule做如下修改

void
Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
    //ClearModules(false);
    ModulesDidUnload (m_images, false);
    //m_section_load_history.Clear();
    m_images.Clear();
    m_scratch_ast_context_ap.reset();
    m_scratch_ast_source_ap.reset();
    m_ast_importer_ap.reset();
    if (executable_sp.get())
    { ... }
}

修改的目的是保留当前主程序的节信息。lldb-310引入了节加载与卸载的历史纪录,这个功能正是由这个SectionHistory对象实现的。修改后此段逻辑与lldb-300同样片段一致,目前看上去不清理SectionHistory不影响后续使用。这个问题应该是lldb-310引入的缺陷. 由于绝大部分使用lldb的场合都有完整符号支持, 所以不会暴露出这个缺陷。
如果不想自己编译lldb, 也可修改文件跳过Target::ClearModules中m_section_load_history.Clear()这条语句即可。一般情况不会有显著的副作用。
稍后将此问题向lldb社区反馈。希望能在未来版本得到修正。正式的修复方案应该会更加严密。
---------------------------------------------------------------------------------------------------
A Short English Version
Fixing Thumb Disassemble Issue of LLDB-310 and Later
Symptoms
The lldb-310 and later revisions couldn't disassemble and trace thumb code block correctly without full debug symbols.
Analyse
It's must be a defect brought by the lldb-310, because the lldb-300 could handle thumb code block correctly without full debug symbols. It's done by utilising the FunctionStarts data embedded in a modern MachO file. the symbol parsing phase needs section list of the executable which maintained by Target:m_section_load_history. An empty section list will leads to misinterpreting some data, one of them is the FunctionStarts data.
Resolution
Modify the code of Target::SetExecutableModule in Source/Target/Target.cpp in LLDB source tree. Do not clear the m_section_load_history.
like this:
void
Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
    //ClearModules(false);
    ModulesDidUnload (m_images, false);
    //m_section_load_history.Clear();
    m_images.Clear();
    m_scratch_ast_context_ap.reset();
    m_scratch_ast_source_ap.reset();
    m_ast_importer_ap.reset();
   
    if (executable_sp.get())
    { ... }
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功