Verhindern Sie PLT-Haltepunkte (Procedure Linkage Table) in GDB

Lesezeit: 4 Minuten

In neueren Versionen von GDB führt das Setzen eines Haltepunkts bei einem Bibliotheksfunktionsaufruf zu mehreren tatsächlichen Haltepunkten:

  1. Aufruf in die Procedure Linkage Table (PLT)
  2. Der eigentliche Funktionsaufruf

Das bedeutet, dass wir beim Aufruf der Bibliotheksfunktion jedes Mal zwei Pausen durchlaufen. In früheren GDB-Versionen wurde nur #2 erstellt und daher erhalten Sie nur eine Unterbrechung.

Die Frage ist also: Kann man einen Haltepunkt für den Aufruf einer Bibliotheksfunktion ohne den entsprechenden PLT-Haltepunkt erstellen? Mir ist bewusst, dass Sie einen regulären Haltepunkt erstellen und dann den PLT explizit deaktivieren können, aber das ist wirklich mühsam.

Ich glaube, ich habe eine Lösung für dieses Problem gefunden. Du kannst den … benutzen

break *address

Syntax von break, aber anstatt eine Hex-Adresse anzugeben, geben Sie den Namen der Funktion an (der als Adresse der Funktion ausgewertet wird). Etwas wie

break *myfunction

Dadurch wird nur für die Hauptfunktion und nicht für eine der PLT-Versionen ein Haltepunkt festgelegt.

  • Leider hat das bei mir nicht funktioniert; der Haltepunkt “break *myfunction” wurde nie erreicht 🙁

    – ChristianB

    15. Mai 2018 um 19:49 Uhr

  • Hat bei mir auch nicht funktioniert. „Kein Symbol XXX im aktuellen Kontext“ erhalten.

    – Kopfbedeckung

    2. Dezember 2020 um 19:42 Uhr

Benutzer-Avatar
Felipe Lema

füge diese Zeilen zu deiner hinzu ~/.gdbinit Datei und Anruf disaplts alle zu deaktivieren @plt Haltepunkte:

define disaplts
  python
import gdb
from StringIO import StringIO
lines=gdb.execute("info break", True, True)
for l in StringIO(lines).readlines():
  if "@plt" in l:
    bp=l.split()[0]
    gdb.execute("disa {0}".format(bp))
    print("disabling {0}".format(bp))
  end
end
# disable on library load
catch load mylibrarywithplt disaplt

Hinweis: Beachten Sie die Abstände im Python-Code. Ich empfehle Ihnen zu verwenden cat um den Inhalt einzufügen. BEARBEITEN: “Ausführen beim Laden der Bibliothek” pro @WallStProg hinzugefügt

  • Nett, danke! Beachten Sie, dass Sie bei ausstehenden Haltepunkten dies ausführen müssen, NACHDEM die Bibliothek geladen wurde – z. B.: catch load <libname> commands disaplts end

    – WallStProg

    15. Oktober 2018 um 15:52 Uhr


  • oooh, schön … hinzugefügt.

    – Felipe Lema

    16. Oktober 2018 um 14:57 Uhr


Benutzer-Avatar
RuchirArya

Ja, es kann getan werden.

Um einfach Haltepunkte für alle Funktionen zu setzen, verwenden Sie den Befehl:

  1. rbreak .*

Dadurch werden also Haltepunkte für alle Funktionen einschließlich PLT gesetzt.

Geben Sie nun ein:

  1. Breakpoints Dateiname speichern

Dadurch wird eine Liste aller Breakpoints in einer Datei namens as gespeichert Dateiname.

  1. Öffnen Sie nun die Datei in einem normalen Texteditor wie geditund Löschen all die PLT Zeilen am Ende der Datei angegeben. Speichern Sie dann die Datei nur mit den erforderlichen Funktionen, für die Sie Haltepunkte setzen möchten.

oder

  1. Entfernen Sie alle @plt aus den Funktionsnamen mit dem Befehl:

sed ‘s/@plt//g’ Dateiname > neuer Dateiname

  1. Danach, gdb verlassen (um gdb von nutzlosen PLT-Haltepunkten zu trennen, die zuvor hinzugefügt wurden) und Führen Sie gdb erneut aus.

Geben Sie nun den Befehl ein:

  1. Quelldateiname

oder

  1. Quelle neuer Dateiname (falls Sie den Befehl sed verwendet haben)

An diesem Punkt setzt gdb Breakpoints nur auf die Funktionen, die in der Datei mit dem Namen “Dateiname” oder “neuer Dateiname” (falls sed verwendet).

Notiz: Filterfunktionen mehr in der Datei “Dateiname”, kann man grep auch entsprechend den Anforderungen verwenden. 🙂

Benutzer-Avatar
Markus Plotnik

Hier ist ein Befehl, rdeletedas ist wie delete genauso das rbreak ist wie break – Es löscht Haltepunkte basierend auf einem Regexp-Argument.

$ cat rdelete.py
import gdb
import re

class RDelete(gdb.Command):
  """Delete breakpoints for all locations matching REGEXP."""

  def __init__(self):
    super (RDelete, self).__init__ ("rdelete", gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_LOCATION)

  def invoke(self, argstr, from_tty):
    bppat = re.compile(argstr)
    for bp in gdb.breakpoints():
      if bppat.search(bp.location):
        print("Deleting breakpoint {} at {}".format(bp.number, bp.location))
        bp.delete()

RDelete()


$ gdb -q hoist
(gdb) rbreak .*
...
(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000000580 in main at hoist.c:6
2       breakpoint     keep y   0x00000000000007a0 in x at hoist.c:4
3       breakpoint     keep y   0x0000000000000530 <_init>
4       breakpoint     keep y   0x0000000000000560 <printf@plt>
5       breakpoint     keep y   0x00000000000007b0 <__libc_csu_init>
6       breakpoint     keep y   0x0000000000000820 <__libc_csu_fini>
7       breakpoint     keep y   0x0000000000000824 <_fini>
(gdb) source rdelete.py
(gdb) rdelete @plt
Deleting breakpoint 4 at printf@plt

1156710cookie-checkVerhindern Sie PLT-Haltepunkte (Procedure Linkage Table) in GDB

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy