Reverse USB-SATA Adapter (Verlauf eines Praktikanten)

Hintergrund


Praktikum ist der Prozess des Wissens- und Erfahrungserwerbs. Unser Raccoon Security-Team ist der Ansicht, dass eine Verbesserung der Informationssicherheit von Geräten und Software in unserer Umgebung nicht möglich ist, ohne dieses Wissen und diese Erfahrung an zukünftige Generationen von Spezialisten weiterzugeben. Deshalb organisieren wir seit vielen Jahren individuelle Praktika für talentierte Studenten und Absolventen.


Sicherheitsforschung ist eine Fähigkeit, die an der Universität nicht gelehrt wird. Sie können es anhand konkreter Beispiele und unter Anleitung erfahrener Mentoren lernen. Jedes Jahr lösen unsere Praktikanten komplexe technische Probleme, erreichen ihre Ziele und gehen weiter, erweitern ihren beruflichen Horizont und machen die Welt ein wenig sicherer. Jeder von ihnen hat seine eigene Geschichte, Spezialist zu werden, und das unter dem Strich - der Anfang von einem von ihnen.



Einleitung


Im Oktober letzten Jahres war ich für ein technisches Praktikum bei der Firma NTC Vulkan. Mein Interesse galt dem Bereich Reverse Engineering. Ich wusste, was es war, ich hatte bereits versucht, Crackme unter x86 unabhängig zu erforschen, aber ich verstand, dass das Interessanteste genau an der Schnittstelle von Software und Hardware liegt. Ich hatte keine Erfahrung in diesem Bereich, aber ich hatte den Wunsch, meine Hand zu versuchen.


Ich hatte keine besonderen Erwartungen an diese Veranstaltung - Freunde und Bekannte sprechen oft über technische Praktika bei verschiedenen namhaften Unternehmen. Und als mir angeboten wurde, mich in der Erforschung eines USB-SATA-Adapters zu versuchen, freute ich mich einfach über die neue Gelegenheit, etwas zu lernen. Die gesammelten Erfahrungen und die erzielten Ergebnisse haben es ermöglicht, die Richtigkeit der Wahl des Praktikumsortes und des zukünftigen Berufes zu überprüfen.


Die Studie begann mit der Anschaffung eines regulären USB-SATA-Adapters. Hier ist, was ich als nächstes getan habe.


Visuelle Schaltungsanalyse


Zuerst müssen Sie die Adapterplatine überprüfen und die Grundelemente des Geräts bestimmen. In den folgenden Abbildungen sind die für den Betrieb des Geräts wichtigen Hauptblöcke der Komponenten gekennzeichnet. Nach Recherchen aufgenommene Fotos:



USB zu SATA Adapter. Blick von oben



USB zu SATA Adapter. Ansicht von unten


Nachdem ich einige Zeit bei Google verbracht hatte, stellte ich fest, dass sich zwei Spannungswandler auf der Platine befinden: einer mit 3,3 V und der andere mit 1,2 V. Der auf der Platine installierte Flash-Speicher ist ebenfalls sehr einfach zu bestimmen. Das ROM funktioniert mit der SPI-Schnittstelle und die Speicherkapazität beträgt 512 Kbit / s.


Es scheint, dass die Phase der Schaltungsintelligenz fast abgeschlossen ist, aber eine schnelle Suche im Internet brachte auf Anfrage von „ASM1051“ keine Ergebnisse. Für den auf der Platine installierten Chip wurden keine Dokumente gefunden. Richtig, es ist immer noch gelungen, Software zu finden, mit der Sie sie aktualisieren können. Zusätzlich gibt es ein kleines Datenblatt für das ältere Modell ASM1053 .


USB


Bei Anschluss an einen Computer wird der Adapter als USB-Speichergerät angezeigt. Ich entschied, dass ein tieferes Wissen über USB wahrscheinlich für meine Forschung nützlich sein würde, also verbrachte ich die nächsten Stunden damit, die Schnittstelle zu studieren.
Im Allgemeinen können USB-Geräte je nach Funktionalität unterschiedlichen Klassen angehören. Beispielsweise sind Flash-Laufwerke das Massenspeichergerät und Tastaturen und Mäuse das Human Interface Device (HID) . Und da mein Adapter im Geräte-Manager als Speichergerät angezeigt wird, bedeutet dies, dass er als Massenspeicher definiert ist und mit SCSI-Befehlen arbeiten sollte.



Speicher aus dem ROM lesen


Da über den auf der Karte installierten ASM1051 nichts bekannt ist, wurde der Speicher aus dem ROM als die offensichtlichste Aktion angesehen. Ich bin ins Labor gezogen. Trennte den Flash-Speicherchip mit einem Lötfön und verband ihn mit dem USB-Programmiergerät ChipProg-48. Es gab keine Probleme beim Lesen und ich hatte eine Binärdatei in der Hand. Zu diesem Zeitpunkt konnte ich nicht sagen, was sich auf dem Flash-Laufwerk befand, und begann, die Daten zu analysieren.


Analyse von Binärdateien


Zunächst habe ich mit WinHex einen Speicherauszug aus dem ROM geöffnet, aber Sie können einen beliebigen HEX-Editor verwenden. Begann die Bytes zu betrachten:



Start eines Speicherauszugs, der aus dem ROM gelesen wird


Der Screenshot oben ist ein Screenshot aus dem Editor. Die Zeile ASMT1051 , die mit der Adresse 0x44 beginnt, ist sofort ersichtlich. Sie können die Zeile auch als asmedia von der Adresse 0x18 aus sehen. Für die erste Datenanalyse habe ich das Frequenzanalysetool verwendet, das in WinHex verfügbar ist.



Histogramm der Frequenzanalyse des ROM-Speichers


Das Histogramm zeigt die Bytes, die sich am häufigsten in der Datei befinden. Zusätzlich zu den Heap-Werten 0x00 und 0xFF (die äußersten Spalten des Histogramms) befinden sich häufig die folgenden Bytes im Speicher:


  • 0x02;
  • 0x74;
  • 0x90;
  • 0xA3;
  • 0xE0;
  • 0xF0.

Es wäre möglich, meine Annahme zu bestätigen, dass sich Firmware im ROM befindet. Ein einfacher Weg, dies zu tun, besteht darin, zu versuchen, die Operationscodes verschiedener für Mikrocontroller geeigneter Architekturen (im Folgenden - MC) mit Bytes zu vergleichen, die sich häufig im Speicher befinden.


Wenn grob geschätzt, sollten sehr oft in einem Code in Assembler solche Befehle wie:


  • mov;
  • jmp;
  • anrufen;
  • ret.

Natürlich können diese Befehle in verschiedenen Architekturen unterschiedliche Variationen aufweisen, aber es gibt einen gesunden Menschenverstand.


Ich musste mehrere Anweisungen für verschiedene Kernel durchgehen, bevor ich die richtigen fand. Ein Vergleich mit der Architektur von Intel 8051 ergab ein sehr plausibles Ergebnis. Die Opcodes einiger Befehle stimmen mit gängigen Bytes aus einer Datei überein, zum Beispiel:


  • 0x02 - LJMP addr16;
  • 0x74 - MOV A, #immed;
  • 0x90 - MOV DPTR, #immed;
  • 0xA3 - INC DPTR;
  • 0xE0 - MOVX A, @DPTR;
  • 0xF0 - MOVX @DPTR, A.

Es sieht wirklich so aus, als ob sich Firmware für MK im ROM befindet. Man konnte die Binärdatei sofort in den IDA Pro- Disassembler laden, aber beim Mittagessen fragte einer der Kollegen:


"Sind Sie sicher, dass der Code im Speicher genau mit der Nulladresse beginnt?"

Und wirklich, müssen Sie berücksichtigen, dass einige "Müll" oder Daten von der Adresse 0x00 im Speicher sein können.


Generell stand ich vor der Aufgabe, die Startadresse des Codes zu ermitteln. Um dieses Ziel zu erreichen, ist es am besten, den EM100 SPI-Emulator zu verwenden. Der Emulator ersetzt den Speicherchip auf der Platine, sodass das ROM nicht jedes Mal mit Firmware gelötet werden muss. Außerdem kann der EM100 ein Speicherzugriffsprotokoll aufzeichnen. Da die Firmware aus dem ROM bereits gelesen wurde, können Sie sie jetzt auf den SPI-Emulator herunterladen. Als nächstes müssen Sie den Emulator auf die Adapterplatine löten und ein Protokoll aufzeichnen, wenn Sie den Adapter über USB an einen PC anschließen.



Der SPI-Emulator ist mit der USB-SATA-Adapterplatine verlötet


Ich habe die Verkabelung vom Emulator zu den Pads aus dem Flash-Speicher gelötet und den Emulator mit ein paar Firmware geflasht. Nun bleibt abzuwarten, ob und an welchen Adressen MK den Speicher adressiert.



ROM für den Zugriff auf den ROM-Speicher (mit der SPI-Emulator-Software bezogen)


Die obige Abbildung zeigt, dass der auf der Karte installierte ASM1051-Controller beim Anschließen der Stromversorgung an den Adapter mehrere 0x03-Befehle (Daten lesen) sendet.


Zuerst liest der ASM1051 0x80 Bytes, beginnend mit 0x0000. Es folgen zwei Bytes ab Adresse 0x0080 und zwei weitere Bytes ab Adresse 0x8082. Dann liest es den größten Teil des Speichers aus dem ROM, beginnend mit der Adresse 0x0082.


Wir können davon ausgehen, dass eine große Anzahl von Bytes, die zuletzt aus dem ROM gelesen wurden, beginnend mit der Adresse 0x0082, wahrscheinlich der Code ist. Was und warum vorher abgefragt wird ist noch nicht klar. Es ist nur bekannt, dass das ASM1051 als Antwort auf die erste Anforderung Zeilen aus dem Flash-Speicher empfängt, die in der obigen Abbildung markiert sind. Sie befanden sich nur in den ersten 0x80 Bytes.


Es ist an der Zeit zu prüfen, ob der externe Speicher auf der Karte Firmware für MK mit dem 8051-Kernel enthält und der Code sich unter der Adresse 0x0082 befindet. Öffnen Sie den Speicherauszug in IDA Pro, geben Sie den Prozessortyp Intel 8051 und den Offset für den Code 0x0082 an.



In IDA Pro geöffnete Binärdatei mit Offset 0x82


Es gab keine Probleme beim Öffnen der Binärdatei im Disassembler.


Schlussfolgerungen:


  1. MK ASM1051 hat eine Architektur 8051.
  2. Im ROM gibt es einen Code, der mit der Adresse 0x82 beginnt. Neben dem Code gibt es noch etwas anderes.
  3. Die ersten 0x80 Bytes fallen auf.

Code-Analyse


Nachdem ich sichergestellt habe, dass der Code in der IDA korrekt geladen ist, können Sie ihn analysieren und parallel dazu kommentieren.


Während des Studiums des Codes wurden einfache Funktionen gefunden, wie das Subtrahieren von 32-Bit-Zahlen, verschiedene Handler, ähnlich wie switch () in S. Melkali, und sehr einfache Funktionen, wie das Speichern des Werts aus dem R7-Register in einem Speicher an einer Adresse. Die wichtigsten Funde werde ich im Folgenden beschreiben.


Finde Nr. 1


Interessanterweise erhielt ich als Antwort auf meine Anfrage ( SCSI-Befehl ) eine Antwort mit zwei Zeilen, die wir am Anfang des ROM-Speichers sahen. Natürlich habe ich diese Zeilen sofort im Speicher des Emulators geändert und auf eine Anfrage gewartet, um zu sehen, was ich geschrieben habe. So ein naiver Traum brach schnell zusammen. Als Antwort auf den Befehl sah ich eine weitere Zeile, das ASM1051 forderte nicht den größten Teil des Speichers vom ROM an. MK liest nur die ersten 0x80 Bytes und alle. In der Architektur von 8051 kann Masken- (Hardware-) Firmware verwendet werden, anscheinend hat ASM1051 damit begonnen, von dort zu booten.


So wurde klar, dass die ersten 0x80-Bytes wirklich wichtig sind und das Ändern einfach nicht funktioniert. Ich beschloss, die Anfragen, die MK an SPI stellt, genauer zu untersuchen, bevor ich den Code herunterlade.



SPI-Datenanforderung im ROM


Zwei Anfragen von zwei Bytes schienen interessant. Die Suche in IDA 0x00, 0x80 und 0xEB ergab eine Vielzahl von Ergebnissen, die ich nicht analysierte, aber Byte 0x5A kam seltener vor.



Vergleich mit Byte 0x5A. Prüfsumme zählen-8


Der sechste Klick führte mich buchstäblich zu dem in der obigen Abbildung gezeigten Codeabschnitt. Es ist zu erkennen, dass der Wert aus dem Register mit der Adresse 0x80 7E mit 0x5A verglichen wird. Dann wird die Prüfsumme-8 für Werte von Adresse 0x80 04 bis 0x80 7E gelesen. Als nächstes wird der Wert bei 0x80 7F mit dem zuvor empfangenen Betrag verglichen.



Der Beginn des Speichers im ROM


Solche Offsets ähnelten dem Beginn eines Speicherauszugs aus dem ROM. Die obige Abbildung zeigt, dass die Adresse 0x7E das Byte 0x5A enthält. Und wenn Sie die Prüfsumme 8 für Bytes von der Position 0x04 bis 0x7E zählen, erhalten wir 0xA7, und dieser Wert liegt nur an der Adresse 0x7F.


Auf ähnliche Weise gelang es uns, die Berechnung der Prüfsumme für Bytes von der Adresse 0x0082 bis 0x807F (anscheinend ist dies der gesamte Code) zu finden, die mit dem Byte an der Adresse 0x8083 überprüft wird. Und bei 0x8082 liegt wieder der Wert 0x5A.


Ja, das ist etwas komplizierter als nur die Zeilen im Speicher zu ändern. Ich habe sie auch geändert, aber ich habe auch die Prüfsummen für die neue Datei an den richtigen Stellen berechnet und notiert. Danach sah ich als Antwort auf den Befehl SCSI INQUIRY meine Zeilen.


Schlussfolgerungen:


  1. Während des Startvorgangs versucht der ASM1051, Code aus dem ROM herunterzuladen.
  2. Zunächst vergleicht das ASM1051 das Prüfsummen-8-Byte von Adresse 0x04 bis 0x7E mit dem Wert bei 0x7F.
  3. Wenn der Vergleich der Prüfsumme für die Präambel erfolgreich ist, können wir ihn für den "Code" (Adressen von 0x0082 bis 0x807F) berücksichtigen. ASM1051 vergleicht diesen Wert mit dem Wert an Adresse 0x8083 und überprüft, ob sich Byte 0x5A an Adresse 0x8082 befindet.
  4. Wenn alle Überprüfungen korrekt sind, wird der ASM1051 aus dem ROM geladen, andernfalls wird die Maskenfirmware verwendet.

Finde Nummer 2


Beim Überprüfen und Kommentieren von Funktionen stellte ich fest, dass die PRINTF-Funktion sehr häufig im Code verwendet wird (ich habe es so genannt). Das Interessante daran ist, dass vor dem Aufrufen ein gedrucktes Zeichen in das R7-Register geschrieben wird.



PRINTF-Funktion in IDA Pro


Die Funktion selbst wurde in der obigen Abbildung dargestellt. Lass uns mit ihr umgehen. Zunächst müssen Sie den Wert aus dem Register mit der Adresse 0x7F6 in die Batterie verschieben. Wenn es Null gibt, beenden Sie die Funktion. Das Interessanteste passiert, wenn es nicht Null gibt. Dann wird der Wert des Registers R7 in das Register mit der Adresse 0xC001 verschoben, und, wie wir uns erinnern, wird vor dem Aufruf dieser Funktion ein gedrucktes Zeichen in R7 geschrieben. Überprüfen Sie anschließend, ob der Wert in R7 dem Zeichencode „.“ Entspricht. Wenn nicht, beenden Sie die Funktion. Wenn der Vergleich jedoch erfolgreich war, entnimmt die Funktion den Wert aus dem Register mit der Adresse 0x16A und verschiebt ihn nach 0xC001, was jedoch schwierig ist. Beispielsweise wird die Funktion anstelle von Byte 0x41 (Zeichen "A" in ASCII) zu 0xC001 Byte 0x34 (Zeichen "4" in ASCII) und dann zu 0x31 (Zeichen "1" in ASCII) verschoben. Beenden Sie die Funktion erneut.


Ich habe festgestellt, dass die Prüfung zu Beginn der Funktion nicht bestanden werden kann, da das Register mit der Adresse 0x7F6 auf Null initialisiert ist, dann ändert sich der Code nicht. Das heißt, diese Funktion wird vom Programmierer deaktiviert, obwohl sie kompiliert bleibt. Die Tatsache, dass Bytes nur in das 0xC001-Register geschrieben werden (und manchmal zwei in einer Reihe), legte nahe, dass dies höchstwahrscheinlich ein Hardware-Register ist.


All dies ähnelt UART. Um herauszufinden, ob dies der Fall ist, müssen Sie folgende Schritte ausführen:


  1. Identifizieren Sie die Beine auf dem ASM1051, an denen der UART ausgegeben wird.
  2. Definieren Sie UART-Parameter (Geschwindigkeit, Parität, Anzahl der Stoppbits).
  3. Es wäre schön, UART im Code zu aktivieren (anscheinend ist es deaktiviert).

Alles sieht ganz einfach aus: Sie können abwechselnd mit einem logischen Analysator die Beine berühren und nach dem suchen, auf dem der Moment des Sendens des UART sichtbar wird. Bei Vorhandensein eines Signals kann die Geschwindigkeit durch die Zeit der Impulse bestimmt werden. Mit den restlichen Parametern ist auch alles klar, sehen Sie nur den Moment des Sendens eines Bytes auf dem Analysator.


Um diese Funktion zu "aktivieren", können Sie anstelle der ersten drei Zeilen Nullen schreiben, wobei der Wert im Register mit der Adresse 0x7F6 geprüft wird. Dazu öffne ich nochmal die Firmware in WinHex.



Es werden sechs zurückzusetzende Bytes zugewiesen.


Im Editor ändere ich die gewünschten sechs Bytes in Nullen. Jetzt ist die Firmware fertig und kann auf den ROM-Emulator heruntergeladen werden. Wenn wir annehmen, dass die Funktion zur Ausgabe von Bytes in UART aktiviert ist und ihr Aufruf sehr häufig im gesamten Code enthalten ist, können wir erwarten, dass die Bytes von der UART "fliegen", wenn der Adapter ausgeführt wird. Ich hoffe, einen Tracer zu sehen, der in Bytes im UART anzeigt, wie viel Code ausgeführt wird.


Wie ich oben geschrieben habe, können Sie sich den Logikanalysator einzeln ansehen, um die erforderlichen Rx- und Tx-Zweige zu finden. Ich ging jedoch davon aus, dass sich Rx und Tx des ASM1051 an derselben Stelle befinden wie die ASM1053 - Beine 40 bzw. 41. Ich habe die Analysesonde an Pin 41 (angenommener Tx) angeschlossen und sehe etwas Ähnliches wie das gewünschte Signal:



Zeitdiagramm mit Schenkel 41 - Tx


Um den USB-UART-Konverter anzuschließen und die eingehenden gedruckten Zeichen im Terminal zu beobachten, musste ich zwei dünne Kabel direkt auf die Adapterplatine löten und mit Heißkleber befestigen.



Zwei Kabel an RX und TX angelötet


Ich habe das Diagramm aus der Abbildung „Zeitdiagramm von Abschnitt 41 - Tx“ ein wenig studiert: Die Zeit eines Impulses beträgt anscheinend 1 μs und für sechs Bits 6,3 μs. Nachdem ich den Wert in Baud neu berechnet hatte, erhielt ich ungefähr 950.000 Baud, die nächste Standard-UART-Geschwindigkeit ist 921600 Baud. Ich denke, diese Diskrepanz ergibt sich aus dem Messfehler des logischen Analysators, ich habe nicht das würdigste Gerät genommen, sondern das chinesische „Baby“. Nachdem ich die Parameter im Fenster des Terminal 1.9b-Programms eingestellt hatte, konnte ich eingehende Bytes vom ASM1051 MK während des Betriebs beobachten.



Programmfenster von Terminal 1.9b während des Adapterbetriebs


Fazit:


Das ASM1051 MK verfügt über ein UART-Hardwaremodul. Das Register zum Senden von Daten hat die Adresse 0xC001. Die Datenrate beträgt 921600 Baud. Es gibt ein Stoppbit. Leg 41 ist Tx und Leg 40 ist Rx (obwohl dies nicht genau ist).


Finde Nummer 3


Durch Scrollen durch den Code im Disassembler und Hinzufügen von Kommentaren können Sie Konstruktionen schwieriger finden, als eine Zahl in ein Register zu schreiben. Also bin ich auf einen interessanten Handler gestoßen, von dem ein Teil in C wie switch () aussah.



Der Befehlshandler aus dem Register mit der Adresse 0x800F


Als ich begriff, dass irgendwo SCSI-Befehle verarbeitet werden müssen, begann ich, nach Bytes zu suchen, mit denen der Inhalt des Registers mit der Adresse 0x800F in der obigen Abbildung verglichen wird. Es stellte sich heraus, dass die ersten vier Zweige die Befehle Lesen (10), Schreiben (10), Lesen (16), Schreiben (16) prüfen. Es besteht kein Zweifel, dass dies ein SCSI-Befehlshandler ist. Als nächstes habe ich mir eine Funktion angesehen, die aufgerufen wird, wenn der eingehende Befehl nicht Read / Write (u_Switch) ist. Es liest abhängig vom Byte im Register mit der Adresse 0x16A (der Wert wird von 0x800F übernommen) die Adresse, zu der wir gelangen, wenn sie diese Funktion verlassen. Dies ähnelt switch () .



SCSI-Befehle wechseln


Da ich bereits das Byte ermittelt habe, mit dem ich den in den Adapter eingegangenen SCSI-Befehl vergleiche, habe ich die Adresszuordnung schnell nach Befehlen geordnet. In der obigen Abbildung ist beispielsweise zu sehen, dass nach dem Verlassen der Funktion u_Switch die Adresse 0x1B85 angegeben wird, wenn das Byte 0x1A im Register mit der Adresse 0x16A enthalten ist. Interessanterweise sind nicht alle Bytes im Vergleich zu u_Switch im SCSI-Standard definiert. Das heißt, der Adapter kann die Bytes 0xE6 oder 0xDF verarbeiten, diese sind jedoch nicht durch den Standard festgelegt.


Wie Sie sehen, kann der Adapter benutzerdefinierte Befehle ausführen, für die es Handlerfunktionen gibt.



Seite 13 der Universal Serial Bus-Massenspeicherklasse


Achten Sie auf den Offset 0x0F zur Adresse 0x8000. Vor dem Prozessor wird der SCSI-Befehl aus dem Register mit der Adresse 0x800F gelesen. Wenn Sie die Tabelle in der obigen Abbildung sorgfältig lesen, können Sie feststellen, dass das CBWCB-Feld im Command Block Wrapper (CBW) auch einen Offset von 0x0F aufweist . Es stellt sich heraus, dass die Adressen des ASM1051-RAM-Speichers, beginnend mit 0x8000, ein USB-Puffer sein können, wie in der folgenden Tabelle gezeigt.


SpeicheradresseBeschreibung
0x8000-0x8003dCBWSignature (USBC - bei Empfang eines Pakets)
0x8004-0x8007dCBWTag
0x8008-0x800BdCBWDataTransferLength
0x800CbmdCBWFlag
0x800DbCBWLUN
0x800EbCBWCBLength
0x800F-0x801FCBWCB - SCSI-Befehl und seine Parameter

Die folgende Abbildung zeigt den Codeabschnitt, in dem der Vergleich mit der USBC-Zeichenfolge erfolgt (dies sollte die Signatur dCBWSignature sein) und die vorgeschlagene Signatur von der Adresse 0x8000 stammt. Ich denke, dies reicht aus, um sicherzustellen, dass sich der USB-Puffer ab 0x8000 im RAM-Speicher befindet.



Überprüfen Sie das Feld dCBWSignature auf Übereinstimmung mit der USBC-Zeichenfolge


Schlussfolgerungen:


  1. MK ASM1051 kann nicht nur SCSI-Befehle verarbeiten, die im Standard beschrieben sind.
  2. Die Startadresse des USB-Puffers ist 0x8000. Der SCSI-Befehl befindet sich im Register mit der Adresse 0x800F, was bedeutet, dass weitere Daten / Argumente der Befehle vorhanden sind.

Finde Nummer 4


Da ich wusste, dass MK nicht standardmäßige Teams verarbeiten kann, wollte ich wissen, was sie tun. Die meisten von ihnen gehorchten mir schnell. Ich werde das Studium des Codes dieser Befehle nicht zitieren, da dies lange dauern kann und für einen separaten Artikel mit dem Titel „Assembler ist einfach“ von Bedeutung sein kann. Die Ergebnisse werde ich in der folgenden Tabelle beschreiben.


SCSI-BefehlTeambeschreibung
0xE0Ermöglicht das Lesen der ersten 0x80-Bytes aus dem ROM. In Zukunft werde ich diesen Teil des Speichers als Präambel bezeichnen (ja, dieselben 0x80-Bytes, in denen sich die Zeilen asmedia und ASM1051 ).
0xE1Schreibt die ersten 0x80-Bytes in das ROM
0xE3Schreibt eine beliebige Anzahl von Bytes von 0x80-Adressen in den ROM-Speicher. Das Argument (wie sich herausstellte) ist die Größe des Pakets
0xE4Liest den Byteblock des ASM1051 RAM. Nimmt als Argument die Startadresse und die Anzahl der gelesenen Bytes
0xE5Schreibt ein Byte in den RAM um
0xE7Liest das zuletzt empfangene Paket in den ATA-Puffer.
0xE8Startet das Gerät neu

Ich gebe zu, dass ich nicht alle Befehle durch Lesen von Funktionen in der IDA herausgefunden habe. Nachdem ich während der Recherche gegen die Wand gestoßen war, fiel mir ein, dass ich Software und viele Firmware für das ASM1051 gesehen hatte, als ich nach Dokumentation suchte. Mit der gefundenen Software können Sie die Firmware aktualisieren und das Gerät neu starten. Daher entschied ich, dass es Zeit war, Device Monitoring Studio zu verwenden und zu sehen, was den PC während des Updates an den Adapter sendet.


Auf diese Weise konnte nachvollzogen werden, wie die Aktualisierung der Firmware abläuft: Zuerst wird die Präambel gesendet (mit dem Befehl 0xE1), dann wird der Code mit dem Befehl 0xE3 geschrieben und anschließend durch einen Neustart (Befehl 0xE8) poliert. Für ein schnelles und bequemes Update habe ich ein Python-Skript geschrieben, das die erforderlichen Zeilen in die Präambel einfügt, dann die Prüfsummen liest und das Gerät aktualisiert. Jetzt brauche ich keinen Emulator mehr, ich hatte die Möglichkeit, Firmware über USB auf das ASM1051 hochzuladen, Sie können das native ROM auf die Karte zurückschicken.


Schlussfolgerungen


Um die Firmware zu aktualisieren, müssen drei SCSI-Befehle nacheinander ausgeführt werden: 0xE1, 0xE3 und 0xE8.


Finde Nummer 5


Neben den undokumentierten Befehlen war es interessant, die Handler von Standardbefehlen zu betrachten.



Verschieben des dritten Bits vom Register 0xC884 zum siebten Bit des Registers 0x8002


Es gibt einen interessanten Test im Handler des SCSI-Befehls MODE SENSE (10). Die obige Abbildung zeigt einen Teil des Funktionscodes. Es ist zu sehen, dass das dritte Bit aus dem 0xC884- Register gelesen wird. Dann wird der Wert dieses Bits im Register auf 0x8002 gesetzt.


Interessant ist hier, dass das 0xC884- Register an keiner Stelle im Code initialisiert ist, was bedeutet, dass es sich höchstwahrscheinlich um Hardware handelt.



Tabelle 362 des SCSI-Befehlsreferenzhandbuchs


Wenn Sie sich die Dokumentation zum 0x5A- SCSI-Befehl (MODE SENSE) ansehen, wird außerdem klar, dass der USB-SATA-Adapter auf die MODE SENSE-Anforderung reagieren sollte. Das dritte Byte der Antwort enthält das siebte Bit von WP (Schreibschutz - Schreibschutz). Übrigens habe ich bereits das siebte Bit in 0x8002 gesehen, und der Versatz vom Anfang des USB-Puffers (0x8000) beträgt hier genau 3 .


Fazit:


Der getestete USB-SATA-Adapter liest das dritte Bit aus dem Hardwareregister bei 0xC884 und sendet es als WP-Bit an den USB-Host.


Suchen Sie die Nummer 6


Das Hardware-Register, das bei der Untersuchung des SCSI-Befehlshandlers MODE SENSE gefunden wurde, ist dem GPIO sehr ähnlich. Um dies zu bestätigen, entschloss ich mich, die ASM1051-Beine mit einem aktiven Widerstand zu berühren und den Registerwert (SCSI-Befehl 0xE4) mit der Adresse 0xC884 auszulesen . Dazu habe ich ein Python-Skript mit benutzerdefinierten SCSI-Befehlen geschrieben, das den Wert im 0xC884- Register überwacht und auf dem PC anzeigt.


Bits 0xC88476543210
Bein ASM1051--37-9104544

Nach einem solchen Experiment habe ich eine Tabelle zusammengestellt, in der ich angezeigt habe, welche Bits im 0xC884- Register sich geändert haben, als der ASM1051-Widerstand die Beine berührt hat. Es stellt sich heraus, dass das untersuchte Register eng mit dem GPIO verbunden ist, der Versuch, darauf zu schreiben (mit dem SCSI-Befehl 0xE5), jedoch fehlgeschlagen ist - der Wert hat sich nicht geändert.


Dann habe ich entschieden, dass dieses Register entweder schreibgeschützt ist oder dass das Schreiben in dieses Register auf Hardwareebene verboten ist. Wenn zum Beispiel die MK-Beine ursprünglich nur zum Lesen eingerichtet waren, ist das Schreiben in das 0xC884- Register möglicherweise nicht verfügbar.


Um die dem GPIO zugeordneten Register zu finden, habe ich im Allgemeinen den Initialisierungscode MK durchgesehen. Ich habe alle Register aufgeschrieben, deren Adressen in der Nähe von 0xC884 liegen . Ich habe ungefähr 10 von ihnen. Ich erinnere Sie daran, dass der zehnte Zweig des MK mit der LED auf der Platine verbunden ist, es entspricht dem zweiten Bit im Register 0xC884 . – 0880 , (, ). , , 0880 (/), 0884 , - .


0880 , 0884 . 0884 . ASM1051.


:


GPIO ASM1051. 0880 / I/O. 0884 I/O.


№ 5.


GPIO- , 45- 0884 . WP , USB. 45- , HDD, , .



HDD, 45-


. GND 45- , HDD. .


Fazit


45- ASM1051 HDD.



USB-SATA-. ASM1051. , - , . , GPIO. – ASM1051 , HDD. , , (« »), , , USB-SATA- ASM1051.


, footprint ASM1051, datasheet ASM1053. , ASM1051 .



ASM1051


, 3D- , .



3D-


WP . GPIO ASM1051 , UART. , SATA, HDD. USB 3.0 Micro-B Type-C. HDD USB, HDD 3.5" +12 , 12 21 . .




Fazit


, .


-, , . « «», . , .


, (, ) embedded-. , , . , , , , .


, datasheets, , . , !



Raccoon Security – «» , , , .
, , . .

Source: https://habr.com/ru/post/de485966/


All Articles