How to disassemble one single function using objdump?

后端 未结 7 1086
囚心锁ツ
囚心锁ツ 2020-11-29 17:59

I\'ve got a binary installed on my system, and would like to look at the disassembly of a given function. Preferrably using objdump, but other solutions would b

7条回答
  •  长情又很酷
    2020-11-29 18:37

    gdb disassemble/rs to show source and raw bytes as well

    With this format, it gets really close to objdump -S output:

    gdb -batch -ex "disassemble/rs $FUNCTION" "$EXECUTABLE"
    

    main.c

    #include 
    
    int myfunc(int i) {
        i = i + 2;
        i = i * 2;
        return i;
    }
    
    int main(void) {
        assert(myfunc(1) == 6);
        assert(myfunc(2) == 8);
        return 0;
    }
    

    Compile and disassemble

    gcc -O0 -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
    gdb -batch -ex "disassemble/rs myfunc" main.out
    

    Disassembly:

    Dump of assembler code for function myfunc:
    main.c:
    3       int myfunc(int i) {
       0x0000000000001135 <+0>:     55      push   %rbp
       0x0000000000001136 <+1>:     48 89 e5        mov    %rsp,%rbp
       0x0000000000001139 <+4>:     89 7d fc        mov    %edi,-0x4(%rbp)
    
    4           i = i + 2;
       0x000000000000113c <+7>:     83 45 fc 02     addl   $0x2,-0x4(%rbp)
    
    5           i = i * 2;
       0x0000000000001140 <+11>:    d1 65 fc        shll   -0x4(%rbp)
    
    6           return i;
       0x0000000000001143 <+14>:    8b 45 fc        mov    -0x4(%rbp),%eax
    
    7       }
       0x0000000000001146 <+17>:    5d      pop    %rbp
       0x0000000000001147 <+18>:    c3      retq   
    End of assembler dump.
    

    Tested on Ubuntu 16.04, GDB 7.11.1.

    objdump + awk workarounds

    Print the paragraph as mentioned at: https://unix.stackexchange.com/questions/82944/how-to-grep-for-text-in-a-file-and-display-the-paragraph-that-has-the-text

    objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ /'
    

    e.g.:

    objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ /'
    

    gives just:

    0000000000001135 :
        1135:   55                      push   %rbp
        1136:   48 89 e5                mov    %rsp,%rbp
        1139:   89 7d fc                mov    %edi,-0x4(%rbp)
        113c:   83 45 fc 02             addl   $0x2,-0x4(%rbp)
        1140:   d1 65 fc                shll   -0x4(%rbp)
        1143:   8b 45 fc                mov    -0x4(%rbp),%eax
        1146:   5d                      pop    %rbp
        1147:   c3                      retq   
    

    When using -S, I don't think there is a fail-proof way, as the code comments could contain any possible sequence... But the following works almost all the time:

    objdump -S main.out | awk '/^[[:xdigit:]]+ :$/{flag=1;next}/^[[:xdigit:]]+ <.*>:$/{flag=0}flag'
    

    adapted from: How to select lines between two marker patterns which may occur multiple times with awk/sed

    Mailing list replies

    There is a 2010 thread on the mailing list which says it is not possible: https://sourceware.org/ml/binutils/2010-04/msg00445.html

    Besides the gdb workaround proposed by Tom, they also comment on another (worse) workaround of compiling with -ffunction-section which puts one function per section and then dumping the section.

    Nicolas Clifton gave it a WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html , likely because the GDB workaround covers that use case.

提交回复
热议问题