首页
社区
课程
招聘
[翻译]自己动手编写一个Linux调试器系列之5 源码和信号 by lantie@15PB
发表于: 2017-10-20 23:30 5903

[翻译]自己动手编写一个Linux调试器系列之5 源码和信号 by lantie@15PB

2017-10-20 23:30
5903

在上一部分中,我们了解了DWARF格式的信息以及如何使用它来读取变量,并将高级语言的源代码与正在执行的机器码关联起来。在这一部分中,我们将通过在调试器中使用DWARF原型。我们还将利用这个机会让我们的调试器在遇到断点时打印当前源上下文。

还记得在本系列的开始我提到了的libelfin吗,我们将在本节使用libelfin来处理我们的DWARF信息。 你可以去看下第一篇,但如果不想去或是记不得了,请现在这样做,下载libelfin库并确保你使用我修改过的fbreg分支(github上的代码)

一旦你编译好了libelfin,就可以立即添加到我们的调试器里。第一步先解析我们给出的ELF可执行文件,并从中提取DWARF格式信息。这对libelfin来说非常简单,只需对调试器进行这些更改即可:

使用open来代替std::ifstream,因为ELF加载器需要一个Unix文件描述符来传递给mmap,以便它可以将文件映射到内存中,而不是一次读取它。

接下来,我们可以实现一些函数,从PC值获取行条目和函数DIE。 我们从get_function_from_pc开始:

在这里,我采取一种简单的方式,只需迭代编译单元,直到找到包含程序计数器的代码,然后遍历子函数,直到找到相关函数(DW_TAG_subprogram)。 如上一篇文章所述,您可以处理像成员函数这样的内容,如果需要,可以在这里进行内联。

下一个是get_line_entry_from_pc:

再次,我们只是找到正确的编译单元,然后从debugline表来获取相关条目。

当我们点击一个断点或者绕过我们的代码时,我们会想知道我们最终的来源,我们可以打印源码。

现在我们可以打印出来源码,我们需要把它挂接到我们的调试器中。 一个好的做法是调试器从断点或(最终)单步获取信号。 在我们这样做的时候,我们可能会想要为我们的调试器添加更好的信号处理。

我们想知道什么信号被发送到进程,但是我们也想知道它是如何生成的。 例如,我们想要能够告诉我们是否有一个SIGTRAP,因为我们打破了一个断点,或者是因为一个步骤完成,或者一个新的线程产生等等。幸运的是,ptrace再次来到我们的救援。 ptrace可能的命令之一是PTRACE_GETSIGINFO,它将为您提供有关进程发送的最后一个信号的信息。 我们这样使用它:

这给我们一个siginfo_t对象,它提供以下信息:

我只需要使用si_signo来计算出哪个信号被发送,并且si_code来获取关于信号的更多信息。 放这个代码的最好的地方在我们的wait_for_signal函数中:

现在来处理SIGTRAP。 只要有一个断点被触发,就会发送SI_KERNELTRAP_BRKPTTRAP_TRACE将在单步完成时发送:

有一堆不同的信号和风格的信号,你可以处理。 有关更多信息,请参阅man sigaction

由于我们现在在获取SIGTRAP时更正程序计数器,因此我们可以从step_over_breakpoint中删除已编码的代码,现在看起来像:

现在你应该能够在某个地址设置一个断点,运行该程序并查看使用当前执行的标有光标的行打印的源代码。

下次我们将添加设置源码级断点的功能。 在此期间,您可以在此处获取此帖的代码

原文: https://blog.tartanllama.xyz/writing-a-linux-debugger-source-signal/
译文作者: lantie@15PB 15PB信息安全教育 http://www.15pb.com.cn

添加下载的libelfin目录到Clion项目中配置CMakeLists.txt

图片描述

使用调试器调试程序hello15pb,打印源码

图片描述

使用Clion编译的完整工程

 
 
 
 
 
class debugger {
public:
    debugger (std::string prog_name, pid_t pid)
         : m_prog_name{std::move(prog_name)}, m_pid{pid} {
        auto fd = open(m_prog_name.c_str(), O_RDONLY);

        m_elf = elf::elf{elf::create_mmap_loader(fd)};
        m_dwarf = dwarf::dwarf{dwarf::elf::create_loader(m_elf)};
    }
    //...

private:
    //...
    dwarf::dwarf m_dwarf;
    elf::elf m_elf;
};

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 1
支持
分享
最新回复 (5)
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
2017-10-24 09:15
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
薛老师,期待你的原创
2017-11-4 09:41
0
雪    币: 371
活跃值: (94)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
大佬还更新吗???????????
2017-11-17 14:26
0
雪    币: 371
活跃值: (94)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
这节的薛老师给的例子我这里编译出错:
CMakeFiles/MyDebugger.dir/main.cpp.o:  In  function  `dwarf::elf::elf_loader<elf::elf>::load(dwarf::section_type,  unsigned  long*)':
/home/darmao/Desktop/My5/libelfin/dwarf/dwarf++.hh:1509:  undefined  reference  to  `elf::elf::get_section(std::__cxx11::basic_string<char,  std::char_traits<char>,  std::allocator<char>  >  const&)  const'
collect2:  error:  ld  returned  1  exit  status
CMakeFiles/MyDebugger.dir/build.make:200:  recipe  for  target  'MyDebugger'  failed
求薛老师指点
2017-11-17 17:16
0
雪    币: 371
活跃值: (94)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
老师这个函数有点问题,设置一个断点以后,再继续运行还是会回到这个断点,在打印源码的时候改了pc指针,打印完了以后没有改回来
void  debugger::handle_sigtrap(siginfo_t  info)  {
        switch  (info.si_code)  {
        //one  of  these  will  be  set  if  a  breakpoint  was  hit
        case  SI_KERNEL:
        case  TRAP_BRKPT:
        {
                set_pc(get_pc()-1);  //这里将pc指针设置成了当前指令,在打印完了以后,应该修改回来为当前指令的下一条指令
                std::cout  <<  "Hit  breakpoint  at  address  0x"  <<  std::hex  <<  get_pc()  <<  std::endl;
                auto  line_entry  =  get_line_entry_from_pc(get_pc());
                print_source(line_entry->file->path,  line_entry->line);
                //set_pc(get_pc()+1);这里应该加上这么一句
                return;
        }
        //this  will  be  set  if  the  signal  was  sent  by  single  stepping
        case  TRAP_TRACE:
                return;
        default:
                std::cout  <<  "Unknown  SIGTRAP  code  "  <<  info.si_code  <<  std::endl;
                return;
        }
}
2017-11-17 21:22
0
游客
登录 | 注册 方可回帖
返回
//