Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Hardware Hacking Cheatsheet — Hardware-Hacking-Spickzettel | Kitploit
Tools/GitLabGitLab/myasnik/hardware-hacking-cheatsheet
Embedded-System-SicherheitIoT-SicherheitHardware-SicherheitLernen & BildungKuratierte RessourcenFirmware-Analyse
GitLabmyasnik/hardware-hacking-cheatsheet

Hardware Hacking Cheatsheet

Hardware-Hacking-Spickzettel

Repository anzeigen
23vor 5 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Hardware Hacking Spickzettel

[[TOC]]

Haftungsausschluss

  • Ich bin ein Noob, der versucht, diese Art von Dingen zu lernen, also könnte etwas nicht 100% korrekt sein
  • Entschuldigung für das schlechte Englisch

Hinweise

  • Befolge die Methode des einfachsten Weges zuerst
  • Manchmal musst du löten; hier eine schnelle und einfache Anleitung
    • Du musst möglicherweise Drähte direkt auf PCB-Vias löten (video)
      1. Kratze die Oberfläche der Platine mit einem Cutter an, bis du das Glitzern unter der Lötmaske siehst
      2. Kratze die Oberfläche noch einmal mit einem Glasfaserstift
      3. Reinige die Oberfläche mit etwas Isopropylalkohol und einem Wattestäbchen
      4. Trage ein wenig Flussmittel auf
      5. Verzinne den Draht und löte
    • Hinweise
      • Verzinne immer die Lötspitze
      • Temperatur: 250-350 C
      • Berühre die Platine nicht mit den Händen

Informationssammlung und erste Interaktion

  1. Sieh dir das Etikett auf der Rückseite des Geräts an und finde
    • Modellname
    • Seriennummer
    • Die Firma, die das Gerät gebrandet hat (kann nicht die sein, die es gebaut hat)
  2. Suche im Internet mit den gerade gesammelten Informationen
    • Beste Websites mit Informationen
      • TechInfoDepot
      • OpenWRT
    • Suche nach ..., das führt normalerweise zu vielen Informationen
      • FCC ID (reference website)
      • SOC-Name
      • Flash-Chip-Name und -Menge
      • RAM-Chip-Name und -Menge
      • Andere mögliche Informationsquellen
  3. Öffne das Gerät
    • Suche nach Anleitungen zum Öffnen des Geräts
    • Einige Geräte könnten geklebt sein, um das Öffnen zu verhindern, sei vorsichtig
    • Manchmal haben wir Kühlkörper, die Teile der Schaltung bedecken, entferne sie wenn möglich
  4. Identifiziere Komponenten
    • Um Schaltungsbezeichnungen lesbarer zu machen
      • Verwende Watte + Alkohol, wenn der Alkohol getrocknet ist, bedecke die Schaltung mit Kreide, dann reinige sie; jetzt sollte die Schaltungsbezeichnung lesbar sein
      • Verwende eine Lupe
    • Suche im Internet nach Informationen und Datenblättern über diese Komponenten; falls nichts gefunden wird, versuche es mit chinesischen Suchmaschinen
      • Baidu
      • Sogou
      • Haosou
    • WICHTIG: Das Finden einer Komponente, die VCC und GND gut zugänglich hat, ist sehr nützlich
  5. Finde die UART-Schnittstelle: mehr oder weniger ein TTY
    • Suche im Internet
    • Suche auf der Platine nach GND, oder , oder und

TODO SPI-DUMP

TODO GDB ANHÄNGEN????

Reverse Engineering

  1. Init-Prozess-Typ und Konfigurationsdateien
    • Typen
      • BSD-Stil
        • Startet Skripte in
          • /etc/rc
          • /etc/rc.local
        • Neuer
          • Siehe /etc/rc.conf für Informationen
          • Führt /etc/rc.d/ aus
      • System V (am weitesten verbreitet)
        • BusyBox wird gestartet
        • Konfigurationsdateien in /etc/inittab
          • runlevel
            • 1: Einzelbenutzermodus, Root-Shell, kein Passwort, kein Daemon läuft
            • 3: textbasierter Mehrbenutzermodus, Login-Prompt
            • 5: grafischer Login
          • Dann gibt es eine Liste von Aktionen beim Init
        • Führt /etc/init.d/ aus
      • Systemd (nicht in eingebetteten Systemen verwendet)
    • Identifikation
      • Beim Booten ausgegeben
      • /sbin/init analysieren, um nach obigen Informationen zu suchen, die den Typ identifizieren

Emulationsumgebung

  • Anforderungen
    • CPU-Architektur der Binärdatei kennen
      • Einfach mit dem file-Befehl
    • QEMU muss diese Architektur unterstützen
  • QEMU-Emulation (Modi)
    • Systemmodus: emuliert das gesamte System
      • Vorgehen
        1. QEMU-Ausführungsformat finden: qemu-system-$PROCESSOR$ARCHITECTURE

          • Beispiel: qemu-system-mipsel
        2. Wenn die Prozessorfamilie bekannt ist, kann sie angegeben werden, um QEMU eine bessere Emulation zu ermöglichen

          • Liste der unterstützten Familien: $QEMUBIN -cpu help
          • Es ist besser, mit einer allgemeinen CPU-Familie zu beginnen; wenn etwas nicht funktioniert, tiefer graben und spezifische CPU-Familien verwenden
        3. Wir benötigen Kernel und Root-Dateisystem

          • Hinweise
            • Geräte-Kernel ist aufgrund fehlender Treiber nicht geeignet
            • Es gibt keine Standardisierung in der IoT-Welt
              • Kernel Device Tree verwenden: Textdatei, die Board-Treiber definiert
                • Kernel lädt diese Datei beim Booten und passt generische Treiber an das verwendete Board an
                • Nicht so verbreitet
            • ALSO.. KERNEL UND DATEISYSTEM NEU BAUEN
          1. Kernel-Version, libc-Version und Liste der vom interessierenden ausführbaren Programm verwendeten Bibliotheken finden (readelf -d $EXECUTABLE)

            • Bibliotheksversionsformat: ( ist die Version)

Quellen, Danksagungen und Dank

  • Danke an Valerio Di Giampietro (@valerio) für seinen unglaublichen YouTube-Tutorial-Kanal über Hardware-Hacking. Alles, was hier geschrieben steht, stammt größtenteils aus diesen Videos.
  • Danke an Luca Bongiorni (@LucaBongiorni) für seine wertvollen Ratschläge und Hardware-Werkzeuge.
  • Danke an mightyohm.com für die Lötcomics
  • Danke an die Reddit-hardwarehacking-Community für ihre Hilfe
    • [Noob] Direct PCB soldering (maybe?)
  • Danke an Andrew Paul für das Tutorial zum Löten von Vias
  • Buildroot manual
  • JTAG explained
  • OpenOCD - Flash commands
  • OpenOCD + JTAG information
  • Hardware hacking cheatheet - Little PDF
  • OpenOCD
Tool herunterladen
IN
RX
OUT
TX
VCC
  • Suche nach 3/4 Pins auf der Platine
    1. Finde eine Referenz zu GND
      • Mit zuvor gefundenen Komponenten
      • Normalerweise sind Metallplatten auf GND
    2. Finde eine Referenz zu VCC
      • Mit zuvor gefundenen Komponenten
      • Suche nach Kondensatoren, sie haben normalerweise einen Punkt auf VCC
    3. Teste UART-Kandidaten-Pins, indem du die folgende Tabelle ausfüllst (die Aufzählungspunkte entsprechen jeweils den Spalten der Tabelle)
      1. Teste den Widerstand der UART-Pins gegen GND (Multimeter auf Widerstandsmessung, normalerweise 200k)
      2. Teste den Widerstand der UART-Pins gegen VCC (Multimeter auf Widerstandsmessung, normalerweise 200kOhm)
      3. Schalte das Gerät ein und teste die Spannung der UART-Pins gegen GND (Multimeter auf Spannungsmessung, normalerweise 20V)
      4. Schalte das Gerät ein und WÄHREND DES BOOTVORGANGS teste die vermutete TX-UART-Pin-Spannung gegen GND (Multimeter auf Spannungsmessung, normalerweise 20V); wenn die Spannung oszilliert, ist dieser Pin wahrscheinlich TX (weil er Daten sendet)
      5. Schalte das Gerät ein und WÄHREND DES BOOTVORGANGS teste die vermutete RX-UART-Pin-Spannung gegen GND (Multimeter auf Spannungsmessung, normalerweise 20V); wenn die Spannung bei 0 bleibt, ist dieser Pin wahrscheinlich RX (weil er auf den Empfang von Daten wartet)
      • Tabelle

  • Verwende Jtagulator
    1. Verbinde es mit dem Computer (Baudrate: 115200)
    2. WICHTIG: H ist die Hilfe-Funktion, verwende sie überall
    3. Verbinde Board GND mit Jtagulator GND, Board-Pins 1,2,3 mit Jtagulator-Kanälen 1,2,3
    4. V: Stelle Betriebsspannung ein
    5. U: Rufe das UART-Identifikationsmenü auf
    6. U: Starte Identifikation
    7. Text string to output: Standard
    8. Starting channel: Kanal, auf dem wir den Pin 1 des Boards platziert haben
    9. Ending channel: Kanal, auf dem wir den Pin 3 des Boards platziert haben
    10. Ignore non-printable characters: Ja
    11. Fertig!
  • TODO: - Verwende BurtleinaBoard + Busside
  • Verbinde über UART: Verwende einen seriellen Adapter (UART -> USB), um das Board mit einem Computer zu verbinden
    • Gewählter serieller Adapter: FT232H + Focaccia Board
    1. Wähle die passende Spannung (3.3V oder 5V), sonst werden das Board oder der serielle Adapter beschädigt
    2. Verbinde Board RX mit Adapter TX und Board TX mit Adapter RX
      • HINWEIS: Normalerweise ist das Verbinden des VCC-Pins nicht erforderlich
    3. Verbinde Adapter mit dem Computer
      1. sudo lsusb um den Adapter zu finden
      2. ls -lart /dev um alle Gerätedateien zu finden; unsere sollte eine der letzten sein, normalerweise ttyUSB0
      3. Um auf dieses Gerät zuzugreifen, müssen wir Mitglied der dialout-Gruppe sein (oder root), um unsere Gruppen zu überprüfen: groups $USER
      4. screen /dev/ttyUSB0 $BAUDRATE um sich mit dem TTY zu verbinden
        • $BAUDRATE kann einer der hier gefundenen sein
        • Häufigste $BAUDRATE
          • 115200
          • 9600
          • 57600
          • 38400
          • 19200
        • WICHTIG: Wenn wir $BAUDRATE vermasseln, sehen wir möglicherweise Kauderwelsch oder auch GAR NICHTS
        • ctrl + a -> k -> y: Bildschirm schließen
    • Wenn der RX-Pin nicht zu funktionieren scheint (du tippst und drückst die Eingabetaste, aber nichts passiert), könnte es sein, dass der "Eingabe"-Wert falsch ist: \r\n oder \n?
      • Um dies zu lösen, verwende pyserial, die Python-Bibliothek für serielle Kommunikation, Beispiel:
        root@kitploit:~
        #!/usr/bin/env python3
        
        import serial
        
        ser = serial.Serial('/dev/ttyUSB0', 115200, tmieout = 0.1)
        ser.write(b"HELLO\r\n")
        ser.write(b"HELLO\n")
        
      • Wenn das Problem weiterhin besteht, verwende einen Logikanalysator (hier ein günstiger)
  • Finde die JTAG-Schnittstelle
    • Was ist JTAG: Die JTAG-Schnittstelle bietet Herstellern eine Möglichkeit, die physischen Verbindungen zwischen Pins auf einem Chip zu testen. Wenn Elektroingenieure über die Verwendung von JTAG zum "Debuggen" eines Chips sprechen, meinen sie etwas ganz anderes als traditionelles Software-Debugging. Sie sprechen davon, sicherzustellen, dass Pin A auf Chip A physisch mit Pin B auf Chip B verbunden ist und dass alle diese Pins korrekt funktionieren. Da JTAG direkten Hardwarezugriff auf ein Gerät bietet, ist es auch ein fantastisches Werkzeug für die Sicherheitsforschung.
    • JTAG-Eigenschaften
      • Steuerbarkeit: Setze interne Bits auf 0 oder 1
      • Beobachtbarkeit: Überprüfe den Wert interner Bits
      • ...also Lese-/Schreibzugriff auf EEPROM
      • In-Circuit-Debugging: Debugge Code auf der Schaltung (z.B. mit OpenOCD und GDB)
    • Suche im Internet
    • Suche auf der Platine nach TCK, TDI, TDO, TMS und TRST (optional)
      • TCK (Test Clock): Der Taktgeber oder Metronom, das die Geschwindigkeit des Controllers vorgibt. Die Spannung auf diesem Pin pulsiert einfach in einem rhythmischen, gleichmäßigen Takt auf und ab. Bei jedem "Takt" des Controllers führt dieser eine einzelne Aktion aus.
      • TMS (Test Mode Select): Spannungen auf dem Mode-Select-Pin steuern, welche Aktion JTAG ausführt. Durch Manipulation der Spannung auf diesem Pin sagst du JTAG, was es tun soll.
      • TDI (Test Data-In): Der Pin, der Daten in den Chip einspeist. Der JTAG-Standard definiert keine Protokolle für die Kommunikation über diesen Pin. Das bleibt dem Hersteller überlassen. JTAG betrachtet diesen Pin lediglich als Eintrittsmethode für 1en und 0en in den Chip. Was der Chip damit macht, ist für JTAG irrelevant.
      • TDO (Test Data-Out): Der Pin für Daten, die den Chip verlassen. Wie beim Data-In-Pin sind Kommunikationsprotokolle nicht durch JTAG definiert.
      • TRST (Test Reset, optional): Dieses Signal wird verwendet, um JTAG in einen bekannten guten Zustand zurückzusetzen.
    • Suche nach einer Reihe von 5/6 Pins oder einer doppelten Reihe von 10, 12, 14, 20 Pins auf der Platine
      1. Finde eine Referenz zu GND
        • Mit zuvor gefundenen Komponenten
        • Normalerweise sind Metallplatten auf GND
      2. Finde eine Referenz zu VCC
        • Mit zuvor gefundenen Komponenten
        • Suche nach Kondensatoren, sie haben normalerweise einen Punkt auf VCC
      3. Teste JTAG-Kandidaten-Pins, indem du die folgende Tabelle ausfüllst (die Aufzählungspunkte entsprechen jeweils den Spalten der Tabelle)
        1. Teste den Widerstand der JTAG-Pins gegen GND (Multimeter auf Widerstandsmessung, normalerweise 200k)
        2. Teste den Widerstand der JTAG-Pins gegen VCC (Multimeter auf Widerstandsmessung, normalerweise )
    • Jtagulator verwenden
      1. An Computer anschließen (Baudrate: 115200)
      2. WICHTIG: H ist die Druckhilfefunktion, überall verwenden
      3. Board GND mit Jtagulator GND verbinden, Board-Pins 1,2,3... mit Jtagulator-Kanälen 1,2,3...
      4. V: Betriebsspannung einstellen
      5. J: JTAG-Identifikationsmenü aufrufen
      6. Dort gibt es zwei Optionen
        • I: Identifikation mit IDCODE-Scan, findet TDI nicht (schnell), besser bei vielen zu identifizierenden Pins
        • B: Identifikation mit BYPASS-Scan, findet TDI (langsam), besser bei wenigen zu identifizierenden Pins
    • TODO: - BurtleinaBoard + Busside verwenden
    • WICHTIG
      • JTAG könnte deaktiviert sein (Hardware, Entfernen eines Widerstands), daher ist es möglich, dass die Ergebnisse mit Multimeter und Jtagulator nicht konsistent sind; dies kann durch Einfügen eines Widerstands von ca. 300Ohm oder 1kOhm zwischen diesem Pin und VCC behoben werden
      • JTAG könnte deaktiviert sein (Hardware, Entfernen eines Widerstands); dieses Problem kann durch Wiedereinsetzen des Widerstands oder durch direkte Kurzschlussverbindung der Widerstandspads behoben werden
      • JTAG könnte deaktiviert sein (Software, Setzen bestimmter Werte)
      • JTAG könnte deaktiviert sein (Hardware, Durchbrennen einer Sicherung... in diesem Fall gibt es keine Hoffnung)
  • Verbindung über JTAG: einen „Seriell-Adapter“ (JTAG -> USB) verwenden, um das Board über einen Computer zu verbinden
    • Gewählter „Seriell-Adapter“: FT232H + Focaccia Board
    1. Geeignete Spannung wählen (3,3V oder 5V), sonst werden Board oder Seriell-Adapter beschädigt
    2. Mit dem zuvor gefundenen JTAG-Pinout alles miteinander verbinden
    3. UART-Verbindung offen halten (wie zuvor erklärt), um mit dem Gerät zu interagieren und sein Verhalten zu beobachten
    4. OpenOCD ausführen
      • Erstes Fenster (OpenOCD „Server“): openocd -f $FT232HCONFIGFILE -f $BOARDCONFIGFILE
        • $FT232HCONFIGFILE: Focaccia-Board-Referenz
        • $BOARDCONFIGFILE: die Konfigurationsdatei des Boards, das gehackt wird (nützlich, aber vielleicht nicht vorhanden, optional)
          • Hinweise
            • Konfigurationsdateien befinden sich in /usr/local, vielleicht findet man dort nützliche $BOARDCONFIGFILE
            • Sonst im Internet suchen
            • Sonst selbst schreiben
            • TODO (selbst schreiben)
      • Zweites Fenster (OpenOCD „Client“): telnet localhost 4444
        • Nützliche Befehle
          • halt: CPU anhalten (wie einfrieren)
            • MUSS VOR JEDEM DEBUGGING-VORGANG AUSGEFÜHRT WERDEN
          • reset: CPU zurücksetzen
          • reg: CPU-Register auslesen
          • flash info bank $BANKID oder flash info $BANKID: Informationen über Flash-Speicherbank $BANKID anzeigen (ich denke, Banken = Speicherabschnitte)
          • flash list: eine Liste assoziativer Arrays für jedes Gerät abrufen, das mit flash bank deklariert wurde (in $BOARDCONFIGFILE), nummeriert ab Null
          • flash banks: eine einzeilige Zusammenfassung jedes Geräts ausgeben, das mit flash bank deklariert wurde (in $BOARDCONFIGFILE), nummeriert ab Null
          • : Flash-Speicher beschreiben
  • Firmware und Dateisystem beschaffen
    • Möglichkeiten (Firmware und Dateisystem könnten verschlüsselt sein)
      • Von der Herstellerwebsite herunterladen
      • Wenn nur das Gerät die Firmware herunterladen kann (über ein Update), das Netzwerk mit Wireshark überwachen, um Informationen zu sammeln
      • EEPROM direkt mit einem Flash-Chip-Programmierer und einer Testklemme auslesen
      • Bootloader-Dump-Befehl
        1. Boot-Log-Ausgabe auf der UART-Schnittstelle analysieren
          • Informationen, die ausgegeben werden könnten und für uns interessant sind (Werte sind Beispiele, aber erklärend für das, was wir suchen)
            • Allgemeine Bootloader-Informationen
              • Nach Bootloader-Name und -Version suchen (z.B. U-Boot 1.1.3)
            • SOC-Informationen
              • Zusätzliche Board-Informationen (WLAN, Ethernet...), diese könnten einen eigenen Bootloader haben
              • SOC-Modell (z.B. ASIC MT7621A...)
              • CPU-Frequenz
            • RAM-Informationen
              • mtd->writesize=2048: Seitengröße (Bytes)
              • mtd->oobsize=64: Daten für Fehlerkorrektur (Bytes)
              • devinfo.iowidth=8: Daten pro Schreib-/Lesevorgang (Bytes)
              • RAM-Größe
            • EEPROM-Informationen
              • mtd->erasesize=131072: Verbleibende Schreibvorgänge des EEPROM? (mehr oder weniger)
            • OS-Kernel-Informationen
              • Nach Bootloader-Ladeinformationen suchen, hier findet man Informationen über das Dateisystem
              • Nach Buildroot-Version suchen, dies hilft bei der Emulation der Schaltung und verschiedenen Tests
            • Dateisystem-Informationen
              • Nach Bootloader-Ladeinformationen und OS-Startprozess suchen, hier findet man Informationen über das Dateisystem
            • EEPROM-Partitionen
              • Nach OS-Startprozess suchen, hier findet man Informationen über Partitionen des EEPROM, ihre Namen, Einhängepunkte und Größe im RAM
              • Wenn Partitionen dupliziert sind, dient dies wahrscheinlich Firmware-Upgrades, der Grund lässt sich erahnen
            • Init-Prozess-Informationen
              • Nach init started oder ähnlichem suchen, dies wird wahrscheinlich in der Nähe von BusyBox oder ähnlichem sein
            • Bootloader mit CLI?
              • Nach Bootloader-Menü suchen, hier findet sich wahrscheinlich die Antwort auf diese Frage
        2. Versuchen, eine Bootloader-Shell zu erhalten (automatisch oder über ein Menü per UART)
        3. Die Bootloader-Shell erkunden
          • help-Befehl ist dein Freund
          • Versuchen, eine Möglichkeit zum Auslesen des Speicherinhalts zu finden, Python ist dein Freund
          • OOB-Daten (Fehlerkorrektur) sind nicht so nützlich zum Auslesen
        4. Analyse der ausgelesenen Daten
          • binwalk, file und hexdump -C verwenden, um zu prüfen, ob die ausgelesene Datei in Ordnung ist und ob sie komprimiert oder verschlüsselt ist
            • Mit binwalk -E die Entropie der Datei analysieren
              • Entropie NAHE 1: zufällige, komprimierte oder verschlüsselte Datei
              • Entropie UNTER 1: normale ausführbare Datei oder Datei
          • binwalk -e verwenden, um identifizierbare Segmente der Datei zu extrahieren
        5. Wenn binwalk das ausgelesene Image nicht vollständig versteht, könnte die EEPROM-Partitionstabelle (falls zuvor gefunden) verwendet werden, um das Image manuell in mehrere nützliche Images aufzuteilen
          • dd if=$IN_DUMPED_IMAGE of=$OUT_FILE bs=1024 skip=$BYTES_TO_SKIP_FROM_THE_START count=$HOW_MANY_BYTES_TO_WRITE
          • sha1sum, md5sum oder binwalk -W -i zum Vergleichen von Images (wenn wir z.B. denken, sie könnten identisch sein)
        6. Der letzte Vorgang könnte je nach Inhalt des ausgelesenen Images mehrmals ausgeführt werden; wenn wir z.B. das Kernel-Image haben, könnten wir seine Komponenten erneut mit binwalk (oder dd, wenn wir online finden, wie unser spezifisches Kernel-Image strukturiert ist) extrahieren, um das Root-Dateisystem zu lesen
        7. Dateisystem extrahieren
          • Beispielbefehl (abhängig vom Dateisystemtyp): fakeroot -s fakeroot.dat usquashfs -d squashfs-root u04-sqfs.dat
            • fakeroot: eine gefälschte Root-Umgebung erstellen, nützlich zum Emulieren von Dateiberechtigungen, Gerätedateien...
              • -s fakeroot.dat: gefälschte Root-Umgebung speichern, um sie später mit fakeroot -i fakeroot.dat bash wiederherzustellen
            • usquashfs: squashfs-Dateisystem extrahieren (könnte in Ihrem Fall anders sein)
              • -d squashfs-root: Zielordner
              • u04-sqfs.dat: zu extrahierendes Dateisystem-Image
  • Interessante Binärdateien und Skripte
    • Nach interessanten Dateien suchen, die vom Init-Prozess gestartet werden, und sich nicht nur auf Namen verlassen, sondern tiefgehend analysieren, welche Binärdatei ausgeführt wird; die nicht standardmäßigen sind am interessantesten
    • Nach factory mode-Zeichenfolge suchen; wenn es gelingt, das Gerät in den Werksmodus zu versetzen (falls vorhanden), ist das Hacken viel einfacher
    • Nützliche Befehle
      • Texteditor
      • grep
      • find
      • xargs
      • strings
  • libfoo.X.Y.Z
    X.Y.Z
    • X: inkompatibles ABI
    • Y: abwärtskompatibles ABI
    • Z: keine ABI-Änderungen
  • Wir benötigen also X.Y gleich der Originalbibliothek
    • Akzeptabel: gleiches X, höheres Y
  • Mit einem Build-System bauen (Features auswählen und Abhängigkeiten automatisch verfolgen)

    • Beste Build-System-Optionen
      • Das Yocto-Projekt
      • Buildroot (am besten)
      • OpenWRT-Build-System
  • Emulation starten

    • QEMU-Emulationsskript
      root@kitploit:~
      #!/bin/bash
      # Dieses Skript erstellt eine Umgebung ohne Passwort für Benutzer root
      export QEMU_AUDIO_DRV="none" # Audio-Treiber ignorieren
      
      qemu-system-${PROCESSOR}${ARCHITECTURE} -M $CPUFAMILY \ # Siehe Punkt 2
                                              -m $RAMSIZE \
                                              -kernel $KERNELPATH \
                                              -nographic \ # Keine GUI
                                              -hda $FILESYSTEM \
                                              -net nic,model=$NETCARDMODEL \ # Netzwerkkartenmodell, Treiber muss im Kernel enthalten sein
                                              -net user, hostfw=tcp::2222-:22, hostfw=tcp::9000-:9000 \ # 2222 für SSH und 9000 für GDB-Server
                                              -no-reboot \ # Maschine beim Herunterfahren beenden
                                              -append "root=/dev/hda console=uart0" # Root-Dateisystem und Konsole festlegen
      
      • Wenn beim Ausführen einer Binärdatei ein Fehler wegen fehlender Bibliotheken ausgegeben wird, dann LD_LIBRARY_PATH wie folgt setzen (innerhalb der Maschine): export LD_LIBRARY_PATH=/lib:/usr/lib:$PATHTOORIGINALFILESYSTEMLIBFOLDER
    • Wir könnten auch das NAND-EEPROM emulieren
      root@kitploit:~
      #!/bin/bash
      
      # Teil 1: Bytes für Kernelmodul identifizieren
      modprobe nandsim first_id_byte=$FIRSTBYTE \
                          second_id_byte=$SECONDBYTE \
                          third_id_byte=$THIRDBYTE \
                          fourth_id_byte=$FOURTHBYTE \
                          cache_file=/root/nandsim.bin \
                          parts=x,y,z,... # Partitionsgröße in Anzahl der Löschblöcke definieren; die Anzahl der Partitionen hängt vom Gerät ab, Partitionen werden normalerweise beim Booten ausgegeben
      
      # Teil 2: Erstellte Partitionen löschen (EEPROM-Partitionen analysieren)
      flash_erase /dev/mtd0 0 8 
      flash_erase /dev/mtd1 0 20
      # ...
      
      # Teil 3: Vom Gerät ausgelesene Partitionen in die gerade erstellten laden
      nandwrite /dev/mtd0 part0.bin
      nandwrite /dev/mtd1 part1.bin
      # ...
      
      # Teil 4: Einhängepunkt für Dateisystem erstellen und anhängen (falls UBIFS)
      mkdir /mnt/filesystem
      ubiattach -O $N -m $MTDDVENUM -d $UBIDEVNUM# Teil 5: Mount
      mount -tubifs /dev/ubi${UBIDEVNUM}_0 /mnt/filesystem
      
      1. Identifiziere Bytes für das Kernelmodul
        • Während des Bootvorgangs werden normalerweise Informationen über NAND ausgegeben, schau sie dir an (oben genannte Schritte) und suche nach NAND ID, die ausgegebenen Bytes sind in der Reihenfolge erstes, zweites und viertes Byte
        • Wir können diese Informationen auch durch Suchen im Datenblatt des EEPROM finden
        • Wir können auch writesize, oobsize, erasesize, iowidth verwenden, um hier den richtigen Befehl zu finden
        • Ansonsten, Versuch und Irrtum
      2. Analysiere die beim Booten ausgegebenen EEPROM-Partitionen, um ihre Größen und Namen zu finden. Die letzte Zahl im flash_erase-Befehl ist ihre Größe in Relation zur erasesize (gleich wie parts=x,y,z,...)
      3. Lade die vom Gerät gesicherten Partitionen in die gerade erstellten
      4. Erstelle einen Mountpunkt für das Dateisystem und hänge es an
        • -O: Gibt den Volume-ID-Header-Offset an. Bei falscher Angabe sollte das System trotzdem den richtigen Wert anzeigen; du kannst verschiedene Werte wie 512, 1024, 2048 ausprobieren (Versuch und Irrtum)
        • -m: mtd-Gerätenummer (siehe Punkt 3)
  • Benutzermodus: wie wine, führe nur eine Binärdatei aus und "übersetze" sie in unsere Architektur
    • Hinweise
      • Nicht sehr stabil
      • Kann seltsame Ergebnisse liefern
    • Wie es geht
      1. Finde das QEMU-Ausführungsformat: qemu-$PROCESSOR$ARCHITECTURE
        • Beispiel: qemu-mips64
      2. Wenn QEMU sich über einen fehlenden Interpreter beschwert, übergib den Pfad des ORDNERS, DER DIESEN INTERPRETER ENTHÄLT mit -L (oder siehe man)
        • Um herauszufinden, welcher Interpreter von einer ausführbaren Datei verwendet wird, benutze readelf -l $EXECUTABLE
  • Virtualisierungsmodus: für uns nicht interessant
  • Erstellen des Kernels und des Root-Dateisystems mit Buildroot und Docker
    • Unser gebauter Kernel sollte (in Bezug auf den Original-Kernel) Folgendes haben
      • Gleiche Kernelversion
      • Gleiche libc-Version (uClibc, uClibc-ng, musl, dietlibc...)
      • Gleiche Bibliotheksversionen (der für uns relevanten ausführbaren Datei)
    1. Suche die Buildroot-Version, die den Versionen unseres Geräts am nächsten kommt
      • Manchmal können wir beim Booten/Durchsuchen des ausgelesenen Speichers die verwendete Buildroot-Version finden (wenn das Gerät mit Buildroot gebaut wurde)
    2. Finde eine Linux-Version, die mit der gefundenen Buildroot-Version kompatibel ist, und erstelle einen Docker-Container. Hier ein Beispiel-Dockerfile (Pakete sind wichtig zum Ausführen von Buildroot)
    3. Lade die ausgewählte Buildroot-Version von hier herunter und lege sie in den gemeinsam genutzten Ordner des Docker-Containers
    4. Führe den Docker-Container aus und wechsle zu ihm
    5. Entpacke Buildroot und führe make manual aus, um das Buildroot-Handbuch zu erstellen
    6. Mit make help zeigt Buildroot alle unterstützten Geräte (Boards) an; make $YOURBOARDNAME erstellt eine Buildroot-Konfigurationsdatei für dein Board
    7. Mit make menuconfig (textbasiert) oder make xconfig (GUI) wählen wir Kernelmodule aus, die zu unserem Build hinzugefügt werden sollen. Wir verwenden make xconfig
      • Hier gibt es ein Beispiel/eine Richtlinie, aber du musst selbst herausfinden, welche Module du konkret benötigst, um deine Anwendungen auszuführen
      • Trick: Edit->Find zum Suchen von Modulen
      • Optionen
        • Target options
          • Aktiviere Show options and packages that are deprecated or obsolete
          • Aktiviere Build packages with debugging symbols mit höchster debug level
          • Setze Strip command for binaries on target auf None
          • Setze GCC optimization level auf 0
        • Toolchain
          • Setze Toolchain type auf Buildroot toolchain
    8. Um die gerade definierte Konfiguration dauerhaft zu speichern, verwende make savedconfig
    9. Konfiguriere den Kernel mit make linux-menuconfig (textbasiert) oder make linux-xconfig (GUI), hier verwenden wir die CLI-Version
      • Hier gibt es ein Beispiel/eine Richtlinie, aber du musst selbst herausfinden, welche Module du konkret benötigst, um deine Anwendungen auszuführen
      • Optionen
        • Kernel type -> Preemption model (Preemptible Kernel (Low-Latency Desktop)) -> Preemptible Kernel (Low-Latency Desktop)
        • Kernel type -> Device drivers -> Memory technology device (MTD) support -> NAND device support -> Support for NAND flash simulator
        • Kernel type -> Device drivers -> -> ->
    10. Konfiguriere uClibc (oder deine C-Bibliothek) mit uclibc-menuconfig (wie immer)
      • Debugging aktivieren: Development/Debugging options -> Enable debugging symbols, falls dies nicht funktioniert (Kompilierungsfehler), dann Development/Debugging options -> (Wall) compiler warnings -> füge -Wall -ggdb -g3 hinzu
        • -ggdb: stellt Debug-Informationen für die Verwendung mit GDB bereit
        • -g3: stellt zusätzliche Debug-Informationen bereit
      • Save
      • Aktiviere Funktionen wie in unserem Gerät (Versuch und Irrtum; bei Fehlern untersuche und baue dann mit den benötigten Funktionen neu)
    11. make, bei Problemen gehe zurück zu früheren Schritten
      • Mögliche Kompilierungsfehler
        • Need to use -fPIC
          • Füge --enable-shared in den Kernelmodulen (Punkt 7) unter Toolchain -> Additional gcc options hinzu oder patche Buildroot
    • Speichern der Konfigurationsdateien für Buildroot mit Git
      • Externer Baum-Konfiguration (Baumansicht der Dateien, die von Buildroot verstanden werden sollen) (br2)
        root@kitploit:~
        +-- board/
        |   +-- <company>/ (not always used)
        |       +-- <boardname>/
        |           +-- linux.config
        |           +-- busybox.config
        |           +-- kernel-defconfig (kernel config file)
        |           +-- <other configuration files>
        |           +-- post_build.sh (executed just before building the image, useful to copy root filesystem into the image)
        |           +-- post_image.sh
        |           +-- rootfs_overlay/ (everythin here will be copied in the final image)
        |           |   +-- etc/
        |           |   +-- <some file>
        |           +-- patches/
        |               +-- foo/
        |               |   +-- <some patch>
        |               +-- libbar/
        |                   +-- <some other patches>
        |
        +-- configs/
        |   +-- <boardname>_defconfig (buildroot config for our board)
        |   +-- uClibc.config (optional)
        +-- patches/
        |   +-- (here patches to be applied)
        |
        +-- Config.in (if using a br2-external tree)
        +-- external.mk (if using a br2-external tree)
        +-- external.desc (if using a br2-external tree)
        
      • Um einen externen Baum zu verwenden, rufe Buildroot wie folgt auf: make BR2_EXTERNAL=$PATHTOEXTTREE $COMMAND
      • Um die Buildroot-Konfiguration in unserem externen Baum zu speichern: make BR2_EXTERNAL=$PATHTOEXTTREE savedefconfig
  • PINGND-WiderstandVCC-WiderstandVAnmerkungen
    1
    2
    3
    4
    • Beispiel

      PINGND-WiderstandVCC-WiderstandVAnmerkungen
      130kOhm0Ohm3.3VVCC
      24.7kOhm34kOhm3.3V1.6-3.3V beim Boot - TX
      3INFOhm (Multimeter 1)INFOhm (Multimeter 1)3.3V0V beim Boot - RX
      40Ohm30kOhm0VGND
    200kOhm
  • Schalte das Gerät ein und teste die Spannung der JTAG-Pins gegen GND (Multimeter auf Spannungsmessung, normalerweise 20V)
    • Tabelle

      PINGND-WiderstandVCC-WiderstandVAnmerkungen
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      ...
      • Beispiel

  • Gefundene Werte mit den häufig verwendeten JTAG-Pinouts vergleichen, verfügbar unter jtagtest
  • Starting channel: Kanal, an dem Pin 1 des Boards angeschlossen ist
  • Ending channel: Kanal, an dem Pin n des Boards angeschlossen ist
  • Already known pins: Nein, könnte den Prozess aber beschleunigen, falls bereits einige Pins bekannt sind
  • Starten und warten.. Fertig!
  • flash write_image erase "$BINTOWRITE" $ADDRTOSTART
    • $BINTOWRITE: kann bin (Binär), ihex (Intel Hex), elf (ELF-Datei), s19 (Motorola s19), mem... sein
    • $ADDRTOSTART: Startadresse (ich denke, Standard ist 0)
  • flash dump_image $OUTFILE $ADDRTOSTART $SIZETODUMP: Speicher auslesen
    • $OUTFILE: Ausgabedatei für den Dump
    • $ADDRTOSTART: Startadresse (ich denke, Standard ist 0)
    • $SIZETODUMP: Anzahl der auszulesenden Bytes
  • Mehr hier:
    • OpenOCD PDF
    • OpenOCD HTML
  • TODO
  • -d: UBI-Gerätenummer (siehe Punkt 5)
  • Mount
  • Setze Kernel headers auf Manually specified linux version
  • Setze Custom kernel headers series auf $DEVICEKERNELVERSION
  • Setze Linux version auf $DEVICEKERNELVERSION
  • Setze C library auf $DEVICECLIBRARY
  • Setze $DEVICECLIBRARY version auf $DEVICECLIBRARY $DEVICELIBRARYVERSION
  • Aktiviere Enable large files
  • Aktiviere Enable IPv6
  • Aktiviere Enable RPC
  • Aktiviere Enable WCHAR
  • Setze Thread library implementation auf linuxthreads
  • Aktiviere Thread library debugging
  • Aktiviere Build cross gdb for the host
  • Aktiviere TUI support
  • Aktiviere Python support
  • Setze GDB debugger version auf $LATESTGDBVERSION
  • System configuration
    • Setze Passwords encoding auf MD5
    • Setze Init system auf $DEVICEINITSYSTEM (oder BusyBox)
    • Setze /dev management auf Dynamic using devtmpfs only
    • Setze /bin/sh auf Busybox default shell
    • Aktiviere Install timezone info
  • Kernel
    • Setze Kernel version auf $DEVICEKERNELVERSION
    • Setze Kernel binary format auf vmlinux
  • Target packages
    • Compressors and decompressors
      • bzip2 and xz-utils
    • Debugging profiling and benchmark
      • Aktiviere gdb und full debugger
    • Development tools
      • Was du benötigst
    • Filesystem and flash utilities
      • mtd, jffs2 and ubi/ubifs tools (oder was du benötigst)
    • Libraries
      • Im Allgemeinen, was du benötigst (Vorschläge unten)
      • Crypto
        • libsha1
        • libssh2
        • openssl
      • JSON/XML
        • expat
        • json-c
  • Networking applications
    • rsync und was du benötigst
  • Shell and utilities
    • file
  • Filesystem images
    • ext2
  • Host utilities (nicht über das Zielgerät, hier sprechen wir über das Hostgerät)
    • host mtd, jffs2 and ubi/ubifs tools
    • host util-linux
  • Denke daran zu SPEICHERN
  • Memory technology device (MTD) support
    UBI - Unsorted block images
    Enable UBI
  • File systems -> Miscellaneous filesystem -> JFFS2 support
  • File systems -> Miscellaneous filesystem -> UBIFS filesystem support
  • Save
  • Um die Kernel-Konfiguration in unserem externen Baum zu speichern: make BR2_EXTERNAL=$PATHTOEXTTREE linux-update-defconfig
  • Um die uClibc-Konfiguration in unserem externen Baum zu speichern: make BR2_EXTERNAL=$PATHTOEXTTREE BR2_UCLIBC_CONFIG=$PATHWHERETOSAVEUCLIBCCONFIG uclibc-update-defconfig
  • PINGND-WiderstandVCC-WiderstandVAnmerkungen
    11kOhm1kOhm0V
    20Ohm90Ohm0VGND
    3INFOhm (Multimeter 1)INFOhm (Multimeter 1)2.1VHochimpedant, TDO?
    490Ohm0Ohm3.3VVCC
    54.7kOhm4.7kOhm3.3V
    6INFOhm (Multimeter 1)INFOhm (Multimeter 1)0VNicht verbunden?
    75.7kOhm5.7kOhm3.3V
    8INFOhm (Multimeter 1)INFOhm (Multimeter 1)0VNicht verbunden?
    94.7kOhm4.7kOhm3.3V
    100Ohm90Ohm0VGND
    • Kompatibler JTAG-Test-Site-Pinout gefunden: Altera Byteblaster