2015-06-24 18 views
5

Nach info registers in gdb ausgeführt wird, erhalten wir eine Ausgabe ähnlich der folgenden:GDB Info-Register-Befehl - Zweite Spalte der Ausgabe

rax   0x1c 28 
rbx   0x0 0 
rcx   0x400a60 4196960 
rdx   0x7fffffffde88 140737488346760 
rsi   0x1 1 
rdi   0x400932 4196658 
rbp   0x0 0x0 
rsp   0x7fffffffde68 0x7fffffffde68 
r8    0x400ad0 4197072 
r9    0x7ffff7dea560 140737351951712 
r10   0x7fffffffdc30 140737488346160 
r11   0x7ffff7732dd0 140737344908752 
r12   0x4007f0 4196336 
r13   0x7fffffffde80 140737488346752 
r14   0x0 0 
r15   0x0 0 
rip   0x7ffff7732dd0 0x7ffff7732dd0 
eflags   0x202 [ IF ] 
cs    0x33 51 
ss    0x2b 43 
ds    0x0 0 
es    0x0 0 
fs    0x0 0 
gs    0x0 0 

Während verstehe ich das für rax, rcx etc wird GDB den Wert Umwandlung zu dezimal für die zweite Spalte scheint dies nicht konsistent. Einige Register, nämlich rsp und zeigen den gleichen Wert in Hex, auch in der zweiten Spalte. eflags zeigt dagegen die Flags in der zweiten Spalte.

Was ist der Grund, dass gdb dies tut? Wenn es die gleichen Informationen zeigt (im Falle von rsp und), ist es nicht redundant? Wie verallgemeinert sich dies auch auf andere Architekturen? (Der obige Ausgang ist für x86-64).

Antwort

4

Mit dem Befehl "info registers" werden Register sowohl im Raw-Format (Hex) als auch im natürlichen Format ausgedruckt.

Das natürliche Format basiert auf dem Typ des Registers, der in den XML-Dateien im Quellcode von gdb deklariert ist. Zum Beispiel i386/64bit-core.xml enthält:

<reg name="rax" bitsize="64" type="int64"/> 
<reg name="rbx" bitsize="64" type="int64"/> 
<reg name="rcx" bitsize="64" type="int64"/> 
<reg name="rdx" bitsize="64" type="int64"/> 
<reg name="rsi" bitsize="64" type="int64"/> 
<reg name="rdi" bitsize="64" type="int64"/> 
<reg name="rbp" bitsize="64" type="data_ptr"/> 
<reg name="rsp" bitsize="64" type="data_ptr"/> 
<reg name="r8" bitsize="64" type="int64"/> 
<reg name="r9" bitsize="64" type="int64"/> 
<reg name="r10" bitsize="64" type="int64"/> 
<reg name="r11" bitsize="64" type="int64"/> 
<reg name="r12" bitsize="64" type="int64"/> 
<reg name="r13" bitsize="64" type="int64"/> 
<reg name="r14" bitsize="64" type="int64"/> 
<reg name="r15" bitsize="64" type="int64"/> 

<reg name="rip" bitsize="64" type="code_ptr"/> 
<reg name="eflags" bitsize="32" type="i386_eflags"/> 
<reg name="cs" bitsize="32" type="int32"/> 
<reg name="ss" bitsize="32" type="int32"/> 
<reg name="ds" bitsize="32" type="int32"/> 
<reg name="es" bitsize="32" type="int32"/> 
<reg name="fs" bitsize="32" type="int32"/> 
<reg name="gs" bitsize="32" type="int32"/> 

Sie können sehen, dass die Register mit type="int64" und type="int32" werden als Dezimalwerte in ihrer natürlichen Ausgabe angezeigt, da sie in der Regel Mehrzweckregister sind und kann sowohl für die Referenzierung Speicher verwendet werden und Zuweisen Wert.

Während Register mit type="data_ptr" und type="code_ptr" hexadezimale Werte in ihrem natürlichen Format haben, da sie normalerweise für die Referenzierung der Speicheradresse verwendet werden.

Bei Registern mit type="i386_eflags" gibt das Flag "true" aus, da für dieses Register für Menschen es sinnvoller ist, wenn man weiß, welches Flag auf 'True' gesetzt ist und nicht die Hex-Werte.

Für andere Architektur hängt es davon ab, wie die Registertypen in ihrem Quellcode definiert sind. Sie können von ARM, auf den Quellcode schauen ARM-64, x86-32bit und viele andere bei binutils-gdb/gdb/features/


EDIT:

Quelle: @MarkPlotnick Antwort auf Why is "info register ebp" in gdb not displaying a decimal number? und @perror Antwort auf https://reverseengineering.stackexchange.com/questions/9221/output-of-gdb-info-registers/9222#9222.

Sorry, ich habe vergessen, die Quelle zu erwähnen.

+0

Ich würde dieses Plagiat nennen ... wie Sie die Frage gestellt haben [http://reverseengineering.stackexchange.com/questions/9221/output-of-gdb-info-registers] und Sie kopierten große Teile davon meine Antwort hier, ohne Ihre Quellen richtig zu zitieren ... Ich lehne diese Vorgehensweise ab! – perror

+0

@perror da drüben habe ich auf diese Frage hingewiesen. Auch habe ich meine Antwort geändert, den Teil Ihrer Antwort entfernend. –

0

In der Tat, in der Montage nur drei Arten von Werten finden:

  1. Numerische Werte;
  2. Speicheradressen;
  3. Anweisungen (Opcodes).

Universalregister, wie rax, rbx, ..., werden zur Speicherung entweder numerische Werte oder Speicheradressen (zu wissen, wo (das wird das Verhalten des Programms auslösen) lesen/schreiben oder zu springen).

Da die meisten Menschen im Dezimalformat für die in Programmen verwendeten Werte verwendet werden, ist es natürlich wichtig, ein Dezimalformat anzuzeigen, wenn das Register solche Werte enthält.

Nun ist es wichtig zu wissen, dass Speicheradressen normalerweise im Hexadezimalformat angegeben werden (hauptsächlich aus Gründen der Kompaktheit). Und Allzweckregister können auch Speicheradressen enthalten. Deshalb zeigen gdb sowohl dezimale als auch hexadezimale Formate an, nur für den Fall, dass das eine oder das andere für den aktuellen Wert am besten geeignet ist.

Die Register rsp, rip (und rbp) sind Sonderfälle, da sie speziell Adressen werden zum Speichern (und nur diese), so würde es nichts nützen, den Inhalt dieser Register in Dezimal-Format zu übersetzen. Deshalb gibt gdb für diese Register nur ein hexadezimales Format an.

Schließlich ist der Fall der rflags/eflags ein bisschen speziell, weil dieses Register eine Bit-pro-Bit-abhängige Bedeutung hat (siehe folgende Abbildung).

EFLAGS bit-per-bit details

daher das Dezimalsystem geben, hexadezimal oder Binär-Format ist nicht wirklich nützlich für den Benutzer (außer wenn Sie die Zahlen auf die Fahnen sofort beziehen können). Aber es ist viel nützlicher, die Liste der Flags anzugeben, die als 'wahr' festgelegt sind (dies ist die [ IF ], die Sie in Ihrem Beispiel sehen). Doch gdb gibt den hexadezimalen Wert des eflags, wie es zugegriffen werden kann und als Wert in Programmen (ich habe dies zur Verschleierung Zweck gesehen).

Verwandte Themen