Capovolgere endianness in gdb?

Aug 23 2020

In gdbSono un bix perplesso sul motivo per cui a volte stampa byte da sinistra a destra e talvolta da destra a sinistra. Ecco un esempio in cui nessuna istruzione è stata eseguita tra:

>>> x/4b $rbp-4 0x7fffffffe43c: 0x04 0x00 0x03 0x16 >>> x/2h $rbp-4
0x7fffffffe43c: 0x0004  0x1603

Perché questo viene fatto in gdb? Penso che li stamperebbe sempre come:

04 00 03 16

Risposte

1 PeterCordes Aug 23 2020 at 22:19

GDB utilizza l'endiannes nativo della macchina di destinazione (per impostazione predefinita 1 ) per interpretare blocchi della dimensione richiesta come numeri interi, con indirizzi che aumentano da sinistra a destra tra i blocchi. x86 è little endian.

All'interno di un blocco, 04 00interpretato come un intero little endian a 16 bit è 0x0004 . Questo fa sì che GDB dump un array shortnel modo in cui ti aspetteresti, ad esempio. Hai chiesto a GDB blocchi interi a 16 bit, quindi fa quello che gli hai detto, mostrando il valore intero utilizzando la notazione del valore di posizione standard con la cifra più a sinistra la più significativa. Non sta cercando di stampare i byte separatamente perché hai chiesto mezze parole.

Se vuoi byte in ordine di memoria, usa b. Ecco a cosa serve.


Nota 1 :

Puoi modificare l'impostazione endianness di GDB; show endianmostra l'impostazione corrente. Tuttavia, set endian bigcausa problemi, danneggiando i valori di registro. ad es. quando ci si ferma a _start:

(gdb) p /x $rsp $1 = 0x7fffffffe6d0       # this is normal for x86-64
(gdb) set endian big
The target is assumed to be big endian
(gdb) x /16xw $rsp 0xd0e6ffffff7f0000: Cannot access memory at address 0xd0e6ffffff7f0000 (gdb) p /x $rsp
$2 = 0xd0e6ffffff7f0000   # this is obviously broken, byte-reversed

I registri non hanno un endian e capovolgerli quando si espande il loro valore come indirizzo per un altro comando è completamente rotto.


Duplicati non esatti correlati:

  • GDB interpreta correttamente l'indirizzo di memoria?
  • Perché i dati archiviati in memoria vengono invertiti?
  • Big Endian e Little Endian poca confusione
samuelbrody1249 Aug 23 2020 at 23:30

Peter ha la risposta corretta e accettata, ma inserirò anche una breve spiegazione che ha aiutato la mia comprensione.


Quindi supponiamo di voler memorizzare il numero 22( 0x16in esadecimale) come valore a due byte in memoria.

Poiché x86 è little-endian (memorizza il byte più significativo all'indirizzo di memoria più alto), lo memorizzeremo in questo modo:

0xAA1: 0x16                       (LSB)
0xAA2: 0x00                       (MSB)

Ora, se lo stampiamo byte per byte in ordine crescente di indirizzo di memoria, ovviamente ha questo aspetto:

0xAA1:  0x16 0x00                (2 bytes, byte by byte in increasing memory address)

Ma poi se vogliamo il valore originale di 22back dobbiamo interpretare il valore a due byte come little-endian in modo che restituisca il valore corretto:

0xAA1:  0x0016 # 22 in decimal  (bytes flipped back to interpret it properly in program