2011-04-03 24 views

回答

1

棘手的問題。簡單的答案是,你不能。

然而,如果你瞭解組裝您可以使用工具,如objdump的GDB和其他人拆卸應用。並且從程序員可以重新編寫應用程序,從程序員熟練的。這並非易事,取決於目標應用程序的複雜程度而變得更加困難。

事實上,發行版本不是(或不應該)與-g一起編譯。

+0

發佈版本應在編譯後_stripped_(它從所得到的二進制文件中刪除名稱,註釋和_debugging info_);這並不意味着'-g'將永遠不得不被刪除發佈版本,雖然。 – 2011-04-04 10:44:27

+0

@karlphillip:如果我需要[C僞代碼](http://softwarerecs.stackexchange.com/q/26830/2341)會怎麼樣? – user2284570 2015-11-29 21:33:01

0

否。調試信息只包含有關符號的信息,即變量和函數,但不包含代碼本身。

2

如果你的意思是反編譯,請看反編譯器(IDA Pro,例如);調試信息可以幫助很大,特別是如果您對完整源代碼不感興趣。

您可以使用調試符號來識別您感興趣的過程的起點。使用好的反向工程工具(如IDA或非常優秀的OllyDbg)可以爲這些部件獲得註釋反彙編。 OllyDbg和IDA能夠在一定程度上從反彙編生成C代碼。

有符號,但有幫助,但沒有魔藥

10

答案是:這取決於 - 不僅是編譯選項必要-g,而且最終創建的可執行/共享libary可能無法在構建過程中去除。與-g創建

目標文件做含有一種源代碼的 - 如果你對這樣的文件使用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.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> 

多大的幫助這個「源代碼」的存在將被保留爲在這一點上對讀者的練習;-)

+0

+1這有幫助,謝謝:) – nc3b 2011-04-04 12:49:52

+0

我嘗試使用_gfortran_而不是_gcc_,並且令人驚訝的是,所有的源代碼都在那裏,一行一行,甚至包括頭文件和註釋,所以可能取決於編譯器? – siritinga 2013-09-11 09:14:02

+0

@siritinga:您在由gcc的C/C++編譯器部分創建的程序集中看到的「源代碼」是完整的_preprocessed_代碼。與「正常來源」('* .c' /'* .C'輸入文件)相比,這種龐大的容量可能會讓人分心。這就是爲什麼我一直在說「這對讀者有多大的幫助......」。 Fortran在預處理過程中做的這種修改較少,我並不感到驚訝,因爲它將更好的可讀/更接近編譯的輸入代碼嵌入到調試信息中。 – 2013-09-11 14:39:06