debugging 使用调试符号获取源代码

3pmvbmvn  于 2023-03-19  发布在  其他
关注(0)|答案(4)|浏览(136)

是否可以获得用调试信息(gcc .. -g)编译的linux共享库(.so)的源代码?谢谢您的宝贵时间。

qnzebej0

qnzebej01#

答案是:视情况而定-不仅编译选项-g是必需的,而且最终创建的可执行文件/共享库在构建过程中可能不会被剥离。
-gdo 创建的对象文件包含一种源代码-只是不是您喜欢的源代码...
如果您在这样的文件上使用objdump -S,它将在反汇编过程中穿插源代码行。
但它所显示的是实际的 * 编译源 * -经过预处理器所做的任何操作,经过编译器所做的任何内联。
这意味着您可以从中获得令人惊讶的输出;如果没有别的,它的冗长程度看起来有点像Cobol源代码。

#include <algorithm>
#include <functional>
int main(int argc, char **argv)
{
    int array[] = { 1, 123, 1234, 12345, 123456 };
    std::sort(array, array + sizeof(array)/sizeof(*array), std::less<int>());
    return 0;
}

然后运行g++ -O8 -g -o t t.Cobjdump -S t,给予main()的输出,类似于下面的内容(当然,你看到的具体内容取决于你的编译器和/或库):

00000000004005e0 :
#include <algorithm>
#include <functional>

int main(int argc, char **argv)
{
  4005e0:       41 57                   push   %r15
                                  _ValueType<)
      __glibcxx_requires_valid_range(__first, __last);

      if (__first != __last)
        {
          std::__introsort_loop(__first, __last,
  4005e2:       ba 04 00 00 00          mov    $0x4,%edx
  4005e7:       41 56                   push   %r14
  4005e9:       41 55                   push   %r13
  4005eb:       41 54                   push   %r12
  4005ed:       41 bc 04 00 00 00       mov    $0x4,%r12d
  4005f3:       55                      push   %rbp
  4005f4:       53                      push   %rbx
  4005f5:       48 83 ec 38             sub    $0x38,%rsp
  4005f9:       4c 8d 74 24 10          lea    0x10(%rsp),%r14
        int array[] = { 1, 123, 1234, 12345, 123456 };
  4005fe:       c7 44 24 10 01 00 00    movl   $0x1,0x10(%rsp)
  400605:       00 
  400606:       c7 44 24 14 7b 00 00    movl   $0x7b,0x14(%rsp)
  40060d:       00 
  40060e:       c7 44 24 18 d2 04 00    movl   $0x4d2,0x18(%rsp)
  400615:       00 
  400616:       c7 44 24 1c 39 30 00    movl   $0x3039,0x1c(%rsp)
  40061d:       00 
  40061e:       4d 8d 7e 14             lea    0x14(%r14),%r15
  400622:       49 8d 6e 08             lea    0x8(%r14),%rbp
  400626:       4c 89 f7                mov    %r14,%rdi
  400629:       c7 44 24 20 40 e2 01    movl   $0x1e240,0x20(%rsp)
  400630:       00 
  400631:       c6 04 24 00             movb   $0x0,(%rsp)
  400635:       4c 89 fe                mov    %r15,%rsi
  400638:       e8 73 01 00 00          callq  4007b0 <_ZSt16__introsort_loopIPilSt4lessIiEEvT_S3_T0_T1_>
  40063d:       eb 01                   jmp    400640 <main+0x60>
  40063f:       90                      nop
      if (__first == __last) return;

      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
        {
          typename iterator_traits<_RandomAccessIterator>::value_type
            __val = *__i;
  400640:       8b 5d fc                mov    -0x4(%rbp),%ebx
          if (__comp(__val, *__first))
  400643:       3b 5c 24 10             cmp    0x10(%rsp),%ebx
                                  _ValueType>)
      __glibcxx_requires_valid_range(__first, __last);

      if (__first != __last)
        {
          std::__introsort_loop(__first, __last,
  400647:       4b 8d 0c 34             lea    (%r12,%r14,1),%rcx

      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
        {
          typename iterator_traits<_RandomAccessIterator>::value_type
            __val = *__i;
          if (__comp(__val, *__first))
  40064b:       7c 53                   jl     4006a0 <main+0xc0>
  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
  40064d:       8b 55 f8                mov    -0x8(%rbp),%edx
            {
              std::copy_backward(__first, __i, __i + 1);
              *__first = __val;
  400650:       48 8d 45 f8             lea    -0x8(%rbp),%rax
    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val,
                              _Compare __comp)
    {
      _RandomAccessIterator __next = __last;
      --__next;
      while (__comp(__val, *__next))
  400654:       39 d3                   cmp    %edx,%ebx
  400656:       7c 0e                   jl     400666 <main+0x86>
  400658:       eb 1c                   jmp    400676 <main+0x96>
  40065a:       eb 04                   jmp    400660 <main+0x80>
  40065c:       90                      nop
  40065d:       90                      nop
  40065e:       90                      nop
  40065f:       90                      nop
  400660:       48 89 c1                mov    %rax,%rcx
  400663:       48 89 f0                mov    %rsi,%rax
        {
          *__last = *__next;
  400666:       89 11                   mov    %edx,(%rcx)
  400668:       8b 50 fc                mov    -0x4(%rax),%edx
          __last = __next;
          --__next;
  40066b:       48 8d 70 fc             lea    -0x4(%rax),%rsi
    __unguarded_linear_insert(_RandomAccessIterator __last, _Tp __val,
                              _Compare __comp)
    {
      _RandomAccessIterator __next = __last;
      --__next;
      while (__comp(__val, *__next))
  40066f:       39 d3                   cmp    %edx,%ebx
  400671:       7c ed                   jl     400660 <main+0x80>
  400673:       48 89 c1                mov    %rax,%rcx
        {
          *__last = *__next;
          __last = __next;
          --__next;
        }
      *__last = __val;
  400676:       89 19                   mov    %ebx,(%rcx)
  400678:       49 89 ed                mov    %rbp,%r13
  40067b:       48 83 c5 04             add    $0x4,%rbp
  40067f:       49 83 c4 04             add    $0x4,%r12
    __insertion_sort(_RandomAccessIterator __first,
                     _RandomAccessIterator __last, _Compare __comp)
    {
      if (__first == __last) return;

      for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
  400683:       4d 39 ef                cmp    %r13,%r15
  400686:       75 b8                   jne    400640 <main+0x60>
        std::sort(array, array + sizeof(array)/sizeof(*array), std::less<int>());

        return 0;
}
  400688:       48 83 c4 38             add    $0x38,%rsp
  40068c:       31 c0                   xor    %eax,%eax
  40068e:       5b                      pop    %rbx
  40068f:       5d                      pop    %rbp
  400690:       41 5c                   pop    %r12
  400692:       41 5d                   pop    %r13
  400694:       41 5e                   pop    %r14
  400696:       41 5f                   pop    %r15
  400698:       c3                      retq   
  400699:       eb 05                   jmp    4006a0 <main+0xc0>

这个“源代码”的存在会有多大帮助,这一点留给读者作为练习;- )

nqwrtyyt

nqwrtyyt2#

棘手的问题。简单的答案是,你不能。

但是,如果你了解 * 汇编 *,你可以使用 objdumpgdb 和其他工具来反汇编应用程序。从汇编中,一个熟练的程序员可以重写应用程序。这不是一件容易的事情,根据目标应用程序的复杂程度,它会变得更加困难。

事实上,发行版本没有(或不应该)使用-g编译。

ugmeyewa

ugmeyewa3#

如果你指的是反编译,看看反编译器(IDAPro,例如);拥有调试信息会有很大帮助,特别是如果您对完整的源代码不感兴趣的话。
你可以使用调试符号来识别你感兴趣的过程的起点。使用一个好的逆向工程工具(比如IDA或者非常优秀的OllyDbg)你可以得到这些部分的注解反汇编。OllyDbg和IDA在一定程度上能够从反汇编生成C代码。
拥有这些符号,同样,有帮助,但不是灵丹妙药

zpjtge22

zpjtge224#

不可以。调试信息只包含有关符号的信息,即变量和函数,但不包含代码本身。

相关问题