是否可以获得用调试信息(gcc .. -g)编译的linux共享库(.so)的源代码?谢谢您的宝贵时间。
gcc .. -g
.so
qnzebej01#
答案是:视情况而定-不仅编译选项-g是必需的,而且最终创建的可执行文件/共享库在构建过程中可能不会被剥离。用-gdo 创建的对象文件包含一种源代码-只是不是您喜欢的源代码...如果您在这样的文件上使用objdump -S,它将在反汇编过程中穿插源代码行。但它所显示的是实际的 * 编译源 * -经过预处理器所做的任何操作,经过编译器所做的任何内联。这意味着您可以从中获得令人惊讶的输出;如果没有别的,它的冗长程度看起来有点像Cobol源代码。
-g
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()的输出,类似于下面的内容(当然,你看到的具体内容取决于你的编译器和/或库):
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>
这个“源代码”的存在会有多大帮助,这一点留给读者作为练习;- )
nqwrtyyt2#
棘手的问题。简单的答案是不,你不能。
但是,如果你了解 * 汇编 *,你可以使用 objdump、gdb 和其他工具来反汇编应用程序。从汇编中,一个熟练的程序员可以重写应用程序。这不是一件容易的事情,根据目标应用程序的复杂程度,它会变得更加困难。
事实上,发行版本没有(或不应该)使用-g编译。
ugmeyewa3#
如果你指的是反编译,看看反编译器(IDAPro,例如);拥有调试信息会有很大帮助,特别是如果您对完整的源代码不感兴趣的话。你可以使用调试符号来识别你感兴趣的过程的起点。使用一个好的逆向工程工具(比如IDA或者非常优秀的OllyDbg)你可以得到这些部分的注解反汇编。OllyDbg和IDA在一定程度上能够从反汇编生成C代码。拥有这些符号,同样,有帮助,但不是灵丹妙药
zpjtge224#
不可以。调试信息只包含有关符号的信息,即变量和函数,但不包含代码本身。
4条答案
按热度按时间qnzebej01#
答案是:视情况而定-不仅编译选项
-g
是必需的,而且最终创建的可执行文件/共享库在构建过程中可能不会被剥离。用
-g
do 创建的对象文件包含一种源代码-只是不是您喜欢的源代码...如果您在这样的文件上使用
objdump -S
,它将在反汇编过程中穿插源代码行。但它所显示的是实际的 * 编译源 * -经过预处理器所做的任何操作,经过编译器所做的任何内联。
这意味着您可以从中获得令人惊讶的输出;如果没有别的,它的冗长程度看起来有点像Cobol源代码。
然后运行
g++ -O8 -g -o t t.C
和objdump -S t
,给予main()
的输出,类似于下面的内容(当然,你看到的具体内容取决于你的编译器和/或库):这个“源代码”的存在会有多大帮助,这一点留给读者作为练习;- )
nqwrtyyt2#
棘手的问题。简单的答案是不,你不能。
但是,如果你了解 * 汇编 *,你可以使用 objdump、gdb 和其他工具来反汇编应用程序。从汇编中,一个熟练的程序员可以重写应用程序。这不是一件容易的事情,根据目标应用程序的复杂程度,它会变得更加困难。
事实上,发行版本没有(或不应该)使用
-g
编译。ugmeyewa3#
如果你指的是反编译,看看反编译器(IDAPro,例如);拥有调试信息会有很大帮助,特别是如果您对完整的源代码不感兴趣的话。
你可以使用调试符号来识别你感兴趣的过程的起点。使用一个好的逆向工程工具(比如IDA或者非常优秀的OllyDbg)你可以得到这些部分的注解反汇编。OllyDbg和IDA在一定程度上能够从反汇编生成C代码。
拥有这些符号,同样,有帮助,但不是灵丹妙药
zpjtge224#
不可以。调试信息只包含有关符号的信息,即变量和函数,但不包含代码本身。