Получить источник, используя символы отладки - PullRequest
3 голосов
/ 04 апреля 2011

Можно ли получить источник совместно используемой библиотеки linux (.so), которая была скомпилирована с отладочной информацией (gcc .. -g)?Спасибо за ваше время.

Ответы [ 4 ]

10 голосов
/ 04 апреля 2011

Ответ таков: это зависит - не только необходим параметр компиляции -g, но и окончательно созданный исполняемый / разделяемый библиотека не может быть удален во время процесса сборки.

Объектные файлы, созданные с помощью -g do , содержат своего рода исходный код - просто не исходный код, как вам нравится ...
Если вы используете objdump -S для такого файла, он будет вкраплятьдизассемблирование со строками исходного кода.

Но это показывает фактический скомпилированный исходный код - после любой операции, выполняемой препроцессором, и после любой вставки, выполняемой компилятором.

Это означает, что вы можете получить удивительный результат от него;если ничего больше, его многословие может немного походить на источники Кобола.Начните с:

#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.C, а затем objdump -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>

Насколько полезно присутствие этого "исходного кода"На этом этапе читателю предлагается быть упражнением; -)

2 голосов
/ 04 апреля 2011

Если вы имеете в виду декомпиляцию, посмотрите на декомпиляторы (например, IDA Pro);Наличие отладочной информации может очень помочь, особенно если вас не интересует полный исходный код.

Вы можете использовать символы отладки для определения начальных точек интересующих вас процедур. Использование хорошего инструмента обратного проектирования (например, IDA или отличную OllyDbg ), вы можете получить разборку с примечаниями для этих частей.OllyDbg и IDA могут в определенной степени генерировать C-код из разборки.

Наличие символов, опять же, помогает, но не волшебная таблетка

1 голос
/ 04 апреля 2011

Хитрый вопрос.Простой ответ: Нет , вы не можете.

Однако , если вы понимаете сборка , вы можете использовать такие инструменты, как objdump, gdb и другие, чтобы разобрать приложение.А из сборки опытный программист может переписать приложение.Это непростая задача, и она усложняется в зависимости от сложности целевого приложения.

Дело в том, что версии выпуска не (или не должны) компилироваться с -g.

0 голосов
/ 04 апреля 2011

Нет.Отладочная информация просто содержит информацию о символах, то есть переменных и функциях, но не содержит сам код.

...