Trovare posizioni nel codice macchina (gcc / objdump -d)
-
08-07-2019 - |
Domanda
Se hai in mente una particolare riga di codice C da esaminare nell'output della macchina, come lo localizzeresti nell'output objdump. Ecco un esempio
if (cond)
foo;
bar();
e voglio vedere se la barra è stata incorporata come mi piacerebbe. O useresti uno strumento alternativo invece di objdump?
Soluzione
Puoi avviare objdump usando l'opzione -S
(come " objdump -Sd a.out "
). Verrà visualizzato il codice sorgente mischiato con il codice assembler, se sono disponibili i file sorgente da cui è stato compilato il codice.
In alternativa, puoi utilizzare il seguente modo:
int main(void) {
int a = 0;
asm("#");
return a;
}
diventa
.file "a.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $16, %esp
movl <*>, -8(%ebp)
#APP
# 3 "a.c" 1
#
# 0 "" 2
#NO_APP
movl -8(%ebp), %eax
addl $16, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.3.2"
.section .note.GNU-stack,"",@progbits
Altri suggerimenti
Il debugger dovrebbe anche farti vedere il codice sorgente e l'assembly corrispondente se hai compilato con i simboli di debug. Questa è l'opzione gcc -g e gdb disass command.
Se stai compilando con gcc, puoi usare -S per generare direttamente un file assembly. Questo file di solito contiene alcune informazioni utili, inclusi nomi di funzioni e talvolta numeri di riga per il codice (a seconda delle opzioni di compilazione utilizzate).
Le chiamate di funzione vengono rilevate nell'assembly dal prologo di funzione comune.
Con i386 è
55 push %ebp
89 e5 mov %esp, %ebp
...
c9 leave # optional
c3 ret
con amd64 / x86_64 è simile (solo il prefisso quad 48
):
55 push %rbp
48 89 e5 mov %rsp,%rbp
..
c9 leaveq # optional
c3 retq
Quindi quando lo rilevi nel tuo objdump -S bla.o
o
gcc bla.c -g -fsave-temps -fverbose-asm
output della tua funzione principale
e anche per la barra, la barra non è inline. Anche quando principale ha una chiamata o un salto
per escluderlo non è incorporato.
Nel tuo caso potresti vedere se la barra ha var locali, che ha bisogno di spazio
lo stack locale. Se la barra è in linea, lo stack si regola (ad es. sub $ 0x8,% esp
)
viene eseguito subito dopo il prologo principale, principale potrebbe accedere a quel var.
Altrimenti è privato da escludere.