objdump를 사용하여 하나의 단일 함수를 분해하는 방법은 무엇입니까?
내 시스템에 바이너리가 설치되어 있으며 주어진 함수의 분해를보고 싶습니다. 을 사용하는 objdump
것이 좋지만 다른 솔루션도 사용할 수 있습니다.
에서 이 질문에 나는 단지 경계 주소를 알고 있다면 내가 코드의 분해 부분 수있을 것을 배웠다. 이 답변 에서 분할 디버그 기호를 단일 파일로 다시 바꾸는 방법을 배웠습니다.
그러나 해당 단일 파일에서 작동하고 모든 코드를 분해하더라도 (즉, 시작 또는 중지 주소없이 일반 -d
매개 변수를으로 objdump
) 여전히 해당 기호를 볼 수 없습니다. 문제의 함수가 정적이므로 내 보내지 않는 한 의미가 있습니다. 그럼에도 불구하고 valgrind
함수 이름을보고하므로 어딘가에 저장해야합니다.
디버그 섹션의 세부 사항을 살펴보면 섹션에서 언급 한 이름을 찾았 .debug_str
지만이를 주소 범위로 바꿀 수있는 도구를 모릅니다.
가장 간단한 방법으로 gdb를 사용하는 것이 좋습니다. 다음과 같이 한 줄로 할 수도 있습니다.
gdb -batch -ex 'file /bin/ls' -ex 'disassemble main'
disassemble/rs
소스 및 원시 바이트도 표시하는 gdb
이 형식을 사용하면 objdump -S
출력에 매우 가깝습니다 .
gdb -batch -ex "disassemble/rs $FUNCTION" "$EXECUTABLE"
main.c
#include <assert.h>
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;
}
컴파일 및 분해
gcc -O0 -ggdb3 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
gdb -batch -ex "disassemble/rs myfunc" main.out
분해 :
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.
Ubuntu 16.04, GDB 7.11.1에서 테스트되었습니다.
objdump + awk 해결 방법
https://unix.stackexchange.com/questions/82944/how-to-grep-for-text-in-a-file-and-display-the-paragraph-that-has-the에 언급 된대로 단락을 인쇄합니다. -본문
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <FUNCTION>/'
예 :
objdump -d main.out | awk -v RS= '/^[[:xdigit:]]+ <myfunc>/'
다음을 제공합니다.
0000000000001135 <myfunc>:
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
를 사용할 때 -S
코드 주석에 가능한 시퀀스가 포함될 수 있으므로 오류 방지 방법이 없다고 생각합니다.하지만 다음은 거의 항상 작동합니다.
objdump -S main.out | awk '/^[[:xdigit:]]+ <FUNCTION>:$/{flag=1;next}/^[[:xdigit:]]+ <.*>:$/{flag=0}flag'
적응 : awk / sed로 여러 번 발생할 수있는 두 마커 패턴 사이의 선을 선택하는 방법
메일 링리스트 답장
메일 링리스트에 불가능하다고 말하는 2010 스레드가 있습니다 : https://sourceware.org/ml/binutils/2010-04/msg00445.html
gdb
Tom이 제안한 해결 방법 외에도 -ffunction-section
섹션 당 하나의 함수를 넣은 다음 섹션을 덤프하는 컴파일의 또 다른 (더 나쁜) 해결 방법에 대해서도 설명 합니다.
Nicolas Clifton이 WONTFIX https://sourceware.org/ml/binutils/2015-07/msg00004.html을 주었습니다 . 아마도 GDB 해결 방법이 해당 사용 사례를 다루기 때문일 것입니다.
Objdump를 사용하여 하나의 단일 함수 분해
두 가지 해결책이 있습니다.
1. 명령 줄 기반
이 방법은 완벽하게 작동하며 매우 짧습니다. -d 옵션과 함께 objdump 를 사용 하고 awk로 파이프 합니다 . 분해 된 출력은 다음과 같습니다.
000000000000068a <main>:
68a: 55 push %rbp
68b: 48 89 e5 mov %rsp,%rbp
68e: 48 83 ec 20 sub $0x20,%rsp
A section or function is seperated by an empty line. Hence changing the FS (Field Seperator) to newline and the RS (Record Seperator) to twice newline let you easily search for your recommended function, since it is simply to find within the $1 field!
objdump -d name_of_your_obj_file | awk -F"\n" -v RS="\n\n" '$1 ~ /main/'
Of course you can replace main to any function you want to be output.
2. Bash Script
I have written a small bash script for this issue. Simply copy it and save it as e.g. dasm file.
#!/bin/bash
# Author: abu
# Description: puts disassembled objectfile to std-out
if [ $# = 2 ]; then
sstrg="^[[:xdigit:]]{2,}+.*<$2>:$"
objdump -d $1 | awk -F"\n" -v RS="\n\n" '$1 ~ /'"$sstrg"'/'
elif [ $# = 1 ]; then
objdump -d $1 | awk -F"\n" -v RS="\n\n" '{ print $1 }'
else
echo "You have to add argument(s)"
echo "Usage: "$0 " arg1 arg2"
echo "Description: print disassembled label to std-out"
echo " arg1: name of object file"
echo " arg2: name of function to be disassembled"
echo " "$0 " arg1 ... print labels and their rel. addresses"
fi
Change the x-access and invoke it with e.g.:
chmod +x dasm
./dasm test main
This is much faster than invoking gdb with a script. Beside the way using objdump will not load the libraries into memory and is therefore safer!
Vitaly Fadeev programmed the autocompletion to this script, which is really a nice feature and speeds up typing.
The script can be found here.
This works just like the gdb solution (in that that it shifts the offsets towards zero) except that it's not laggy (gets the job done in about 5ms on my PC whereas the gdb solution takes about 150ms):
objdump_func:
#!/bin/sh
# $1 -- function name; rest -- object files
fn=$1; shift 1
exec objdump -d "$@" |
awk " /^[[:xdigit:]].*<$fn>/,/^\$/ { print \$0 }" |
awk -F: -F' ' 'NR==1 { offset=strtonum("0x"$1); print $0; }
NR!=1 { split($0,a,":"); rhs=a[2]; n=strtonum("0x"$1); $1=sprintf("%x", n-offset); printf "%4s:%s\n", $1,rhs }'
To simplify the usage of awk for parsing objdump's output relative to other answers:
objdump -d filename | sed '/<functionName>:/,/^$/!d'
Bash completion for ./dasm
Complete symbol names to this solution (D lang version):
- By typing
dasm test
and then pressing TabTab, you will get a list of all functions. - By typing
dasm test m
and then pressing TabTab all functions starting with m will be shown, or in case only one function exists, it will be autocompleted.
File /etc/bash_completion.d/dasm
:
# bash completion for dasm
_dasm()
{
local cur=${COMP_WORDS[COMP_CWORD]}
if [[ $COMP_CWORD -eq 1 ]] ; then
# files
COMPREPLY=( $( command ls *.o -F 2>/dev/null | grep "^$cur" ) )
elif [[ $COMP_CWORD -eq 2 ]] ; then
# functions
OBJFILE=${COMP_WORDS[COMP_CWORD-1]}
COMPREPLY=( $( command nm --demangle=dlang $OBJFILE | grep " W " | cut -d " " -f 3 | tr "()" " " | grep "$cur" ) )
else
COMPREPLY=($(compgen -W "" -- "$cur"));
fi
}
complete -F _dasm dasm
참고URL : https://stackoverflow.com/questions/22769246/how-to-disassemble-one-single-function-using-objdump
'code' 카테고리의 다른 글
트위터 부트 스트랩-테두리 (0) | 2020.11.05 |
---|---|
Go에서 중첩 된 함수 선언 (함수 내부 함수)을 허용하지 않는 이유는 무엇입니까? (0) | 2020.11.05 |
C ++ 14의 Lambda-Over-Lambda (0) | 2020.11.05 |
목록에서 두 번째 요소를 어떻게 얻을 수 있습니까? (0) | 2020.11.05 |
다양한 RAISERROR 심각도 수준은 무엇을 의미합니까? (0) | 2020.11.05 |