Architektur und Programmierung von 8051-MCUs für Reverse Engineering 2
Kapitel 3 : Der 8051-Befehlssatz
Einleitung
Das Schreiben von Mikrocontroller-Programmen besteht hauptsächlich darin, Befehle in einer bestimmten Ausführungsreihenfolge auszugeben, um festgelegte Aufgaben zu erfüllen. Elektronische Hardware kann keine menschenlesbare Logik wie "Wenn der Taster gedrückt wird, schalte das Licht ein" interpretieren. Stattdessen müssen Entwickler eine Reihe einfacher, strikt definierter Befehle verwenden, die vom internen Decoder des MCU erkannt werden. Die vollständige Sammlung dieser gültigen Befehle wird als Befehlssatz bezeichnet. Alle 8051-kompatiblen Mikrocontroller verfügen über insgesamt 255 verschiedene Befehle, d. h. es stehen 255 eindeutige Maschinenwörter für die Programmentwicklung zur Verfügung.
Auf den ersten Blick scheint das Erlernen dieser großen Anzahl symbolischer Opcodes einschüchternd. Die tatsächliche Lernlast ist jedoch viel geringer, als es scheint. Viele Befehle zählen als separate Einträge, obwohl sie identische zugrunde liegende Operationen ausführen, sodass nur 111 funktional eindeutige Befehle übrig bleiben. Beispielsweise führen ADD A,R0, ADD A,R1, ..., ADD A,R7 alle dieselbe Additionsoperation zwischen dem Akkumulator und einem Arbeitsregister durch. Da es acht Arbeitsregister gibt, wird jede Variante als separater Befehlseintrag aufgeführt. Wenn man bedenkt, dass alle Befehle nur 53 Kernoperationen implementieren (Addition, Subtraktion, Datenkopie usw.) und die meisten dieser Operationen in praktischen Projekten selten verwendet werden, müssen Entwickler nur etwa 20 bis 30 Mnemoniken beherrschen – eine sehr überschaubare Menge.
Über die funktionale Programmausführung hinaus bildet der Befehlssatz die erste Verteidigungslinie gegen unbefugten Firmware-Zugriff. Die meisten eingebetteten Systeme verlassen sich auf Lockbit-Mechanismen, um das externe Rücklesen des internen Flash- oder EEPROM-Speichers zu blockieren. Dennoch ist ein gründliches Verständnis des Laufzeitverhaltens jedes Befehls sowohl für das Schreiben sicherer Produktions-Firmware als auch für die Durchführung legitimer Reverse-Engineering zur Wiederherstellung verlorenen Quellcodes unerlässlich. Angreifer nutzen häufig spezifische Befehlshandlungen aus, um den Sperrschutz zu umgehen, indem sie Fehlerinjektion, Timing-Analyse und andere Seitenkanaltechniken einsetzen, um einen Entsperrzustand auszulösen. In vielen Angriffsszenarien ermöglicht die physische Chip-Dekapsulation in Verbindung mit Mikrosondierung das direkte Auslesen der Sicherungsstatusbits, was vollständige Binärdumps der gespeicherten Firmware ermöglicht. Die Fähigkeit, die volle Funktionalität eines Geräts zu replizieren, hängt oft von einer erfolgreichen Firmware-Extraktion über diese Methoden ab, was die Firmware-Wiederherstellung zu einer entscheidenden Fähigkeit in der Sicherheitsforschung für eingebettete Systeme macht.
3.1 Arten von Befehlen
Alle Befehle werden basierend auf den von ihnen ausgeführten Operationen in fünf Kerngruppen eingeteilt:
- Arithmetische Befehle
- Verzweigungsbefehle
- Datenübertragungsbefehle
- Logische Befehle
- Bitorientierte Befehle
Das erste Segment jedes Befehls wird als Mnemonik bezeichnet, die die Kernoperation darstellt, die ausgeführt werden soll (Datenkopie, arithmetische Addition, bitweise Logik usw.). Mnemoniken sind abgekürzte Kurzformen für den vollständigen Namen jeder Hardwareoperation. Beispiele für Definitionen sind unten aufgeführt:
INC R1 – Erhöht den Wert im Register R1 um eins;
LJMP LAB5 – Führt einen langen unbedingten Sprung zur Speicheradresse mit der Bezeichnung LAB5 aus;
JNZ LOOP – Springt zur Adresse mit der Bezeichnung LOOP, wenn der Akkumulatorwert ungleich Null ist;
Das zweite Segment eines Befehls ist der Operand, der durch mindestens ein Leerzeichen vom Mnemonik getrennt ist und die Datenziele definiert, die von der Operation verarbeitet werden. Einige Befehle haben keine Operanden, während andere einen, zwei oder drei Operanden enthalten. Mehrere Operanden innerhalb eines Befehls werden durch Kommas getrennt. Beispiele:
RET – Rückkehr aus einer Unterroutine;
JZ TEMP – Springt zur Adresse TEMP, wenn der Akkumulatorwert Null ist;
ADD A,R3 – Addiert den Wert des Registers R3 zum Akkumulator;
CJNE A,#20,LOOP – Vergleicht den Akkumulator mit der unmittelbaren Konstante 20; springt zu LOOP, wenn die beiden Werte ungleich sind;
Jede Befehlskategorie spielt eine bestimmte Rolle für die allgemeine Sicherheitslage des Geräts. Bitorientierte Befehle manipulieren direkt Lockbits und andere Sicherungskonfigurationen. Datenübertragungsopcodes wie MOVC lesen den Codespeicher, und diese Befehle liefern bei aktivem Lockbit-Schutz verstümmelte ungültige Daten. Reverse-Engineering-Workflows konzentrieren sich häufig darauf, Befehlsequenzen zu identifizieren, die den Sperrzustand überprüfen, und dann zu versuchen, diese Überprüfungszweige durch Taktstörungen oder Programmzähler-Manipulation zu überspringen. In einigen Fällen erfordert die Wiederherstellung eines gebrickten gesperrten MCU das Auffinden versteckter Bootloader-Hintertüren, die bestimmte Verzweigungsbefehle nutzen, um das vollständige Speicherrücklesen zu ermöglichen.
Arithmetische Befehle
Arithmetische Befehle führen grundlegende mathematische Operationen wie Addition, Subtraktion, Multiplikation und Division aus. Nach Abschluss der Berechnung wird der resultierende Wert im ersten angegebenen Operanden gespeichert. Beispiel:
ADD A,R1 – Die Summe aus Akkumulator A und Register R1 wird wieder im Akkumulatorregister gespeichert.
| Arithmetische Befehle |
| Mnemonik |
Beschreibung |
Byte |
Zyklus |
| ADD A,Rn |
Addiere Inhalt des Arbeitsregisters zum Akkumulator |
1 |
1 |
| ADD A,direct |
Addiere direkt adressiertes Byte zum Akkumulator |
2 |
2 |
| ADD A,@Ri |
Addiere indirekt adressiertes internes RAM-Byte zum Akkumulator |
1 |
2 |
| ADD A,#data |
Addiere unmittelbaren Konstantenwert zum Akkumulator |
2 |
2 |
| ADDC A,Rn |
Addiere Register zum Akkumulator mit Übertragsflag-Eingang |
1 |
1 |
| ADDC A,direct |
Addiere direktes Byte zum Akkumulator mit Übertragsflag-Eingang |
2 |
2 |
| ADDC A,@Ri |
Addiere indirektes RAM-Byte zum Akkumulator mit Übertragsflag-Eingang |
1 |
2 |
| ADDC A,#data |
Addiere unmittelbare Konstante zum Akkumulator mit Übertragsflag-Eingang |
2 |
2 |
| SUBB A,Rn |
Subtrahiere Register vom Akkumulator mit Borgen-Flag-Eingang |
1 |
1 |
| SUBB A,direct |
Subtrahiere direktes Byte vom Akkumulator mit Borgen-Flag-Eingang |
2 |
2 |
| SUBB A,@Ri |
Subtrahiere indirektes RAM-Byte vom Akkumulator mit Borgen-Flag-Eingang |
1 |
2 |
| SUBB A,#data |
Subtrahiere unmittelbare Konstante vom Akkumulator mit Borgen-Flag-Eingang |
2 |
2 |
| INC A |
Erhöhe Akkumulatorwert um eins |
1 |
1 |
| INC Rn |
Erhöhe Arbeitsregisterwert um eins |
1 |
2 |
| INC Rx |
Erhöhe direkt adressiertes Byte um eins |
2 |
3 |
| INC @Ri |
Erhöhe indirekt adressiertes RAM-Byte um eins |
1 |
3 |
| DEC A |
Verringere Akkumulatorwert um eins |
1 |
1 |
| DEC Rn |
Verringere Arbeitsregisterwert um eins |
1 |
1 |
| DEC Rx |
Verringere direkt adressiertes Byte um eins |
1 |
2 |
| DEC @Ri |
Verringere indirekt adressiertes RAM-Byte um eins |
2 |
3 |
| INC DPTR |
Erhöhe 16-Bit-Datenzeigerregister um eins |
1 |
3 |
| MUL AB |
Multipliziere Akkumulator A mit Register B |
1 |
5 |
| DIV AB |
Dividiere Akkumulator A durch Register B |
1 |
5 |
| DA A |
Dezimale Korrektur des Akkumulators für BCD-Ergebnisse |
1 |
1 |
Arithmetische Befehle dienen nicht nur reinen Datenverarbeitungsaufgaben; sie sind integraler Bestandteil von Prüfsummen- und Verschlüsselungsroutinen, die die Firmware-Integrität validieren. Angreifer, die Additions- oder Subtraktionsergebnisse durch Spannungsschwankungen korrumpieren können, können Sicherheitsprüfungen umgehen, die berechnete Prüfsummen mit gespeicherten Referenzwerten vergleichen. Diese Manipulation kann eine Entsperrsequenz auslösen, selbst wenn die Lockbit-Sicherung gesetzt bleibt. Für Firmware-Extraktions-Workflows ist tiefgehendes Wissen über das ALU-Arithmetikverhalten erforderlich, um gezielte Fehlerinjektionsangriffe zu entwickeln, die die Sperrvalidierungslogik überspringen. Darüber hinaus sind die Übertrags- (C) und Überlaufflags (OV) häufige Angriffsziele: Das Stören der arithmetischen Logikeinheit kann falsche Flag-Zustände erzwingen und kritische Sperrzustandsvergleiche umgehen.
Verzweigungsbefehle
Verzweigungsbefehle fallen in zwei verschiedene Kategorien:
Unbedingte Sprungbefehle: Bei der Ausführung springt die CPU sofort zu einer neuen Speicheradresse und setzt den Programmfluss von dort ohne Vorbedingungen fort.
Bedingte Sprungbefehle: Ein Sprung zu einer alternativen Programmadresse wird nur ausgeführt, wenn eine bestimmte logische Bedingung wahr ist. Wenn die Bedingung fehlschlägt, fährt die CPU sequenziell mit dem nächsten Befehl im Speicher fort.
| Verzweigungsbefehle |
| Mnemonik |
Beschreibung |
Byte |
Zyklus |
| ACALL addr11 |
Absoluter Unterprogrammaufruf in 2KB-Seite |
2 |
6 |
| LCALL addr16 |
Langer Unterprogrammaufruf über 64KB |
3 |
6 |
| RET |
Rückkehr aus standardmäßiger Unterroutine |
1 |
4 |
| RETI |
Rückkehr aus Interrupt-Serviceroutine |
1 |
4 |
| AJMP addr11 |
Absoluter Sprung innerhalb der aktuellen 2KB-Seite |
2 |
3 |
| LJMP addr16 |
Langer Sprung zu beliebiger 64KB-Adresse |
3 |
4 |
| SJMP rel |
Kurzer relativer Sprung (-128 bis +127) |
2 |
3 |
| JC rel |
Kurzer Sprung, wenn Übertragsflag C gesetzt ist |
2 |
3 |
| JNC rel |
Kurzer Sprung, wenn Übertragsflag C gelöscht ist |
2 |
3 |
| JB bit,rel |
Kurzer Sprung, wenn angegebenes direktes Bit logisch 1 ist |
3 |
4 |
| JBC bit,rel |
Sprung, wenn direktes Bit gesetzt ist, dann Bit löschen (kurzer Sprung) |
3 |
4 |
| JMP @A+DPTR |
Indirekter indizierter Sprung mit Akkumulator + Datenzeiger-Offset |
1 |
2 |
| JZ rel |
Kurzer Sprung, wenn Akkumulator Null ist |
2 |
3 |
| JNZ rel |
Kurzer Sprung, wenn Akkumulator ungleich Null ist |
2 |
3 |
| CJNE A,direct,rel |
Vergleiche Akkumulator und direktes Byte; kurzer Sprung bei Ungleichheit |
3 |
4 |
| CJNE A,#data,rel |
Vergleiche Akkumulator und unmittelbare Konstante; kurzer Sprung bei Ungleichheit |
3 |
4 |
| CJNE Rn,#data,rel |
Vergleiche Arbeitsregister und unmittelbare Konstante; kurzer Sprung bei Ungleichheit |
3 |
4 |
| CJNE @Ri,#data,rel |
Vergleiche indirektes RAM-Byte und Konstante; kurzer Sprung bei Ungleichheit |
3 |
4 |
| DJNZ Rn,rel |
Dekrementiere Register, kurzer Sprung, wenn Ergebnis ungleich Null |
2 |
3 |
| DJNZ Rx,rel |
Dekrementiere direktes Byte, kurzer Sprung, wenn Ergebnis ungleich Null |
3 |
4 |
| NOP |
Keine Operation (Taktzyklus-Verzögerungsplatzhalter) |
1 |
1 |
Verzweigungsbefehle bilden den Kern der bedingten Programmlogik, einschließlich aller kritischen Sicherheitsvalidierungsroutinen. Der JB-Opcode wird beispielsweise häufig verwendet, um den Lockbit-Sicherungsstatus zu testen. Wenn das Lockbit gesetzt ist, springt das Programm zu einer Sicherheitsunterroutine, die Debug-Schnittstellen deaktiviert und das Speicherrücklesen blockiert. Angreifer können die JB-Befehlsausführung mit Taktstörungen angreifen, um die Hardware zu zwingen, ein gesetztes Lockbit als gelöscht zu behandeln, wodurch der Mikrocontroller vollständig entsperrt wird. Ebenso versorgen CJNE-Befehle Passwortüberprüfungsschleifen; das Injizieren eines Timing- oder Spannungsfehlers während des Vergleichs kann den Programmzähler auf eine unbeabsichtigte Adresse umleiten und geschützten Firmware-Code freilegen. Innerhalb von Reverse-Engineering-Workflows ist die Kartierung des vollständigen Verzweigungs-Kontrollflussgraphen erforderlich, um legitime Entsperrpfade zu lokalisieren und Binärfirmware für die Datenwiederherstellung zu patchen.
Datenübertragungsbefehle
Datenübertragungsopcodes kopieren Werte von einem Register oder Speicherort zu einem anderen, wobei die Quelldaten unverändert bleiben. Befehle mit dem Suffix "X" (MOVX) ermöglichen den Datenaustausch mit externen RAM-Speicherbereichen.
| Datenübertragungsbefehle |
| Mnemonik |
Beschreibung |
Byte |
Zyklus |
| MOV A,Rn |
Kopiere Arbeitsregisterwert in den Akkumulator |
1 |
1 |
| MOV A,direct |
Kopiere direkt adressiertes Byte in den Akkumulator |
2 |
2 |
| MOV A,@Ri |
Kopiere indirekt adressiertes internes RAM-Byte in den Akkumulator |
1 |
2 |
| MOV A,#data |
Lade unmittelbaren Konstantenwert in den Akkumulator |
2 |
2 |
| MOV Rn,A |
Kopiere Akkumulatorwert in das Arbeitsregister |
1 |
2 |
| MOV Rn,direct |
Kopiere direkt adressiertes Byte in das Arbeitsregister |
2 |
4 |
| MOV Rn,#data |
Lade unmittelbaren Konstantenwert in das Arbeitsregister |
2 |
2 |
| MOV direct,A |
Kopiere Akkumulatorwert in direkt adressiertes Byte |
2 |
3 |
| MOV direct,Rn |
Kopiere Arbeitsregisterwert in direkt adressiertes Byte |
2 |
3 |
| MOV direct,direct |
Kopiere ein direkt adressiertes Byte an eine andere direkte Adresse |
3 |
4 |
| MOV direct,@Ri |
Kopiere indirektes RAM-Byte in direkt adressiertes Byte |
2 |
4 |
| MOV direct,#data |
Lade unmittelbaren Konstantenwert in direkt adressiertes Byte |
3 |
3 |
| MOV @Ri,A |
Kopiere Akkumulatorwert in indirekt adressiertes RAM-Byte |
1 |
3 |
| MOV @Ri,direct |
Kopiere direkt adressiertes Byte in indirekten RAM-Speicherort |
2 |
5 |
| MOV @Ri,#data |
Lade unmittelbaren Konstantenwert in indirektes RAM-Byte |
2 |
3 |
| MOV DPTR,#data |
Lade 16-Bit-unmittelbare Konstante in den Datenzeiger |
3 |
3 |
| MOVC A,@A+DPTR |
Lese Codespeicher-Byte bei Offset A+DPTR in den Akkumulator |
1 |
3 |
| MOVC A,@A+PC |
Lese Codespeicher-Byte bei Offset A+PC in den Akkumulator |
1 |
3 |
| MOVX A,@Ri |
Lese 8-Bit-adressiertes externes RAM-Byte in den Akkumulator |
1 |
3-10 |
| MOVX A,@DPTR |
Lese 16-Bit-adressiertes externes RAM-Byte in den Akkumulator |
1 |
3-10 |
| MOVX @Ri,A |
Schreibe Akkumulatorwert an 8-Bit-externe RAM-Adresse |
1 |
4-11 |
| MOVX @DPTR,A |
Schreibe Akkumulatorwert an 16-Bit-externe RAM-Adresse |
1 |
4-11 |
| PUSH direct |
Schiebe direkt adressiertes Byte auf den Systemstack |
2 |
4 |
| POP direct |
Hole obersten Stack-Wert in direkt adressiertes Byte |
2 |
3 |
| XCH A,Rn |
Tausche vollständige Bytewerte zwischen Akkumulator und Arbeitsregister |
1 |
2 |
| XCH A,direct |
Tausche vollständige Bytewerte zwischen Akkumulator und direktem Byte |
2 |
3 |
| XCH A,@Ri |
Tausche vollständige Bytewerte zwischen Akkumulator und indirektem RAM-Byte |
1 |
3 |
| XCHD A,@Ri |
Tausche nur die unteren 4-Bit-Nibbles von Akkumulator und indirektem RAM-Byte |
1 |
3 |
Datenübertragungsbefehle erscheinen am häufigsten in jeder eingebetteten Firmware und stellen gleichzeitig kritische Angriffsflächen für Sicherheitsexploits dar. MOVC-Opcodes sind ausschließlich zum Lesen des Programmcodespeichers konzipiert; bei aktivem Lockbit-Schutz liefern diese Befehle korrumpierte, bedeutungslose Daten. Durch präzise Spannungsschwankungen während der MOVC-Ausführung kann der MCU jedoch gezwungen werden, unveränderte Originalcode-Bytes auszugeben, was byteweise Flash-Dump-Angriffe ermöglicht, die in der Seitenkanal-Reverse-Engineering weit verbreitet sind. MOVX-Befehle greifen auf unverschlüsselte externe Speicherbusse zu, die Angreifer passiv mit Logikanalysatoren überwachen können, um Firmware vollständig zu duplizieren, ohne interne Sicherungssicherungen zu manipulieren. Für internen EEPROM-Speicher ermöglichen direkte MOV-Varianten Lese-/Schreibzugriff auf Special Function Registers, die den Sicherungszustand steuern; ungeschlossene Debug-Schnittstellen erlauben Angreifern, einfache MOV-Sequenzen zu nutzen, um den Chip zu entsperren und vollständige Speicherextraktion durchzuführen. PUSH und POP verwalten den Stapelspeicher, ein häufiges Ziel für Stack-Overflow-Exploits, die Rücksprungadressen überschreiben und die Ausführung auf bösartige Entsperr-Unterroutinen umleiten. Bei der forensischen Wiederherstellung gesperrter eingebetteter Hardware verfolgen Analysten alle MOV-Befehlsequenzen, um undokumentierte Hersteller-Hintertüren zu lokalisieren, die absichtlich für das erneute Flashen von Geräten im Werk hinterlassen wurden.
Logische Befehle
Logische Befehle führen bitweise logische Operationen über übereinstimmende Bitpositionen zweier Byte-Operanden aus und speichern das endgültige berechnete Ergebnis im ersten Operandenregister.
| Logische Befehle |
| Mnemonik |
Beschreibung |
Byte |
Zyklus |
| ANL A,Rn |
Bitweises UND des Arbeitsregisters mit dem Akkumulator |
1 |
1 |
| ANL A,direct |
Bitweises UND des direkt adressierten Bytes mit dem Akkumulator |
2 |
2 |
| ANL A,@Ri |
Bitweises UND des indirekten RAM-Bytes mit dem Akkumulator |
1 |
2 |
| ANL A,#data |
Bitweises UND der unmittelbaren Konstante mit dem Akkumulator |
2 |
2 |
| ANL direct,A |
Bitweises UND des Akkumulators mit direkt adressiertem Byte, Ergebnis in direktem Byte |
2 |
3 |
| ANL direct,#data |
Bitweises UND der unmittelbaren Konstante mit direkt adressiertem Byte |
3 |
4 |
| ORL A,Rn |
Bitweises ODER des Arbeitsregisters mit dem Akkumulator |
1 |
1 |
| ORL A,direct |
Bitweises ODER des direkt adressierten Bytes mit dem Akkumulator |
2 |
2 |
| ORL A,@Ri |
Bitweises ODER des indirekten RAM-Bytes mit dem Akkumulator |
1 |
2 |
| ORL direct,A |
Bitweises ODER des Akkumulators mit direkt adressiertem Byte, Ergebnis in direktem Byte |
2 |
3 |
| ORL direct,#data |
Bitweises ODER der unmittelbaren Konstante mit direkt adressiertem Byte |
3 |
4 |
| XRL A,Rn |
Bitweises XOR des Arbeitsregisters mit dem Akkumulator |
1 |
1 |
| XRL A,direct |
Bitweises XOR des direkt adressierten Bytes mit dem Akkumulator |
2 |
2 |
| XRL A,@Ri |
Bitweises XOR des indirekten RAM-Bytes mit dem Akkumulator |
1 |
2 |
| XRL A,#data |
Bitweises XOR der unmittelbaren Konstante mit dem Akkumulator |
2 |
2 |
| XRL direct,A |
Bitweises XOR des Akkumulators mit direkt adressiertem Byte, Ergebnis in direktem Byte |
2 |
3 |
| XORL direct,#data |
Bitweises XOR der unmittelbaren Konstante mit direkt adressiertem Byte |
3 |
4 |
| CLR A |
Lösche alle Bits des Akkumulatorregisters |
1 |
1 |
| CPL A |
Bitweises Invertieren aller Bits im Akkumulator |
1 |
1 |
| SWAP A |
Tausche oberes und unteres 4-Bit-Nibble im Akkumulator |
1 |
1 |
| RL A |
Rotation der Akkumulatorbits um eine Position nach links (ohne Übertrag) |
1 |
1 |
| RLC A |
Rotation des Akkumulators nach links durch das Übertragsflag |
1 |
1 |
| RR A |
Rotation der Akkumulatorbits um eine Position nach rechts (ohne Übertrag) |
1 |
1 |
| RRC A |
Rotation des Akkumulators nach rechts durch das Übertragsflag |
1 |
1 |
Bitweise logische Befehle werden häufig verwendet, um Lockbit-Sicherungen und andere kritische Sicherheitskonfigurationsregister zu maskieren und zu manipulieren. Beispielsweise können ANL-Masken einzelne Bits in Sicherheits-SFRs selektiv löschen, während ORL-Masken bestimmte Sicherungs-Aktivierungsbits setzen. Angreifer, die Timing- oder Spannungsfehler während der Ausführung dieser Logik-Opcodes injizieren können, könnten versehentlich den Lockbit-Zustand umschalten und den Mikrocontroller vollständig entsperren. Darüber hinaus bilden XOR-Befehle die Grundlage für gängige Firmware-Verschleierung und leichte Verschlüsselungsroutinen; das Umkehren der XOR-Maskierung ermöglicht es Angreifern, Klartext-Sicherheitsschlüssel aus dem EEPROM-Speicher wiederherzustellen. Für Firmware-Extraktions-Workflows ist ein tiefes Verständnis der bitweisen Logikoperationen erforderlich, um verschleierte geschützte Code-Segmente zu entschlüsseln, bevor vollständige Binärspeicherdumps durchgeführt werden.
Bitorientierte Befehle
Bitorientierte Befehle führen logische Operationen analog zur byteweiten Logikgruppe aus, operieren jedoch ausschließlich auf einzelnen Bitpositionen anstelle vollständiger 8-Bit-Bytes.
| Bitorientierte Befehle |
| Mnemonik |
Beschreibung |
Byte |
Zyklus |
| CLR C |
Lösche Übertragsflag-Bit (setze auf 0) |
1 |
1 |
| CLR bit |
Lösche angegebenen direkt bitadressierbaren Speicherplatz (setze auf 0) |
2 |
3 |
| SETB C |
Setze Übertragsflag-Bit auf 1 |
1 |
1 |
| SETB bit |
Setze angegebenen direkt bitadressierbaren Speicherplatz auf 1 |
2 |
3 |
| CPL C |
Invertiere logischen Zustand des Übertragsflags |
1 |
1 |
| CPL bit |
Invertiere logischen Zustand des angegebenen direkten Bits |
2 |
3 |
| ANL C,bit |
Bitweises UND des Zielbits mit dem Übertragsflag, Ergebnis in C |
2 |
2 |
| ANL C,/bit |
Bitweises UND des invertierten Zielbits mit dem Übertragsflag, Ergebnis in C |
2 |
2 |
| ORL C,bit |
Bitweises ODER des Zielbits mit dem Übertragsflag, Ergebnis in C |
2 |
2 |
| ORL C,/bit |
Bitweises ODER des invertierten Zielbits mit dem Übertragsflag, Ergebnis in C |
2 |
2 |
| MOV C,bit |
Kopiere logischen Zustand des direkten Bits in das Übertragsflagregister |
2 |
2 |
| MOV bit,C |
Kopiere logischen Zustand des Übertragsflags in das angegebene direkte Bit |
2 |
3 |
Bitorientierte Opcodes stellen die primäre Softwareschnittstelle zur Manipulation von Lockbit-Sicherungen und anderen sicherheitskritischen Ein-Bit-Konfigurationsflags dar. SETB und CLR können die Sicherungszustände direkt ändern, obwohl die meisten modernen 8051-Derivate die Hardwareschutzmaßnahmen so verstärken, dass Lockbit-Register während der normalen Laufzeit schreibgeschützt sind. Kritische Softwarefehler, die Schreibzugriff auf diese bitadressierbaren Sicherheitsregister ermöglichen, schaffen Remote-Entsperr-Angriffsvektoren für böswillige Akteure. Der MOV C,bit-Befehl liest den Sicherungsstatus und überträgt den Wert in das Übertragsflag, das nachfolgende bedingte Verzweigungen JC/JNC auswerten, um Speicherzugriffsbeschränkungen durchzusetzen. Diese standardmäßige Sperrprüf-Befehlssequenz ist ein Hauptziel für Glitch-Injektionsangriffe: Das künstliche Umschalten des Übertragsflags umgeht den gesamten Sicherheitsvalidierungszweig. Bei physischen dekapsulationsbasierten Chip-Angriffen greift die Mikrosondierung direkt auf diese Bit-Sicherungspositionen zu, um die rohen Sperrzustandsbits zu lesen, wodurch vollständige und ungehinderte Programmspeicherdumps ohne Änderung des Firmware-Codes möglich sind.
3.2 Beschreibung aller 8051-Befehle
Nachfolgend finden Sie ein Referenzglossar, das jede standardmäßige Operandenschreibweise des 8051-Befehlssatzes definiert:
- A – Akkumulatorregister;
- Rn – Beliebiges Arbeitsregister (R0 bis R7) in der aktuell aktiven RAM-Registerbank;
- Direct – Beliebiges 8-Bit-Byte-RAM-Adresse, die allgemeinen internen RAM oder alle Special Function Registers (I/O-Ports, Steuerregister, Statusperipherie) abdeckt;
- @Ri – Indirekt adressiertes internes oder externes RAM-Byte, wobei die Speicheradresse im Zeigerregister R0 oder R1 gehalten wird;
- #data – 8-Bit-unmittelbarer Konstantenliteral, der direkt im Befehlscode enthalten ist (gültiger Bereich 0–255);
- #data16 – 16-Bit-unmittelbarer Konstantenliteral, der als zweites und drittes Byte eines 3-Byte-Befehls gespeichert wird (gültiger Bereich 0–65535);
- addr16 – Vollständige 16-Bit-Programmspeicheradresse, die jede Stelle im gesamten 64KB-Code-Adressraum referenzieren kann;
- addr11 – 11-Bit-Teiladresse, beschränkt auf Sprung-/Aufrufziele, die sich in derselben 2KB-Speicherseite befinden wie das Byte, das unmittelbar auf den ACALL/AJMP-Befehl folgt;
- rel – Relatives Offset-Byte für kurze Verzweigungen, von -128 bis +127 relativ zum ersten Byte des Befehls unmittelbar nach dem Verzweigungsopcode. Der Assembler berechnet automatisch den erforderlichen Offset-Wert, der zur aktuellen Programmzähleradresse addiert oder von ihr subtrahiert wird;
- bit – Beliebiges bitadressierbaren GPIO-Pin, Steuerregister-Flag oder Statusbit im RAM/SFR-Bereich;
- C – Globales Übertragsflag-Bit im PSW-Programmstatuswortregister.
Diese Operandenschreibweisen definieren das gesamte Spektrum der 8051-Adressierungsmodi und sind für die Lokalisierung von Lockbit-Sicherungsadressen in der Speicherkarte des Chips unerlässlich. Ein standardmäßiger Reverse-Engineering-Workflow scannt die Binärfirmware nach direkten Operandenreferenzen, die auf Sicherheits-SFR-Speicheradressen zeigen, und verfolgt dann alle Lese-/Schreibbefehlspfade, die auf diese Register abzielen. Diese statische Analyse deckt häufig undokumentierte Werks-Testmodi oder versteckte Hintertür-Codepfade auf, die vollständiges Speicherrücklesen ermöglichen, selbst wenn der Lockbit-Schutz aktiv bleibt. Für legitime Firmware-Datenwiederherstellungsprojekte ist ein genaues Verständnis jedes Operandentyps erforderlich, um die vollständigen Speicherdump-Layouts genau zu rekonstruieren und extrahierte Binärcodes korrekt zu interpretieren.
ACALL addr11 – Absoluter Unterprogrammaufruf in 2KB-Seite
addr11: Zieladresse der Unterroutine (11-Bit-Seitenoffset)
Beschreibung: Dieser Opcode schiebt die Rücksprungadresse des Programmzählers bedingungslos auf den Systemstack und springt zur angegebenen Unterprogrammadresse. Eine wichtige Einschränkung gilt: Das Byte nach dem aktuellen Befehl und der Einstiegspunkt der Unterroutine müssen innerhalb derselben 2KB-Programmspeicherseitengrenze liegen.
Syntax: ACALL [Unterprogrammbezeichnung];
Befehlsbytes: 2 (Opcode-Byte, 11-Bit-Adressnutzlast);
Betroffene PSW-Statusflags: Keine Statusflags werden durch diesen Befehl geändert.
BEISPIEL:
PC-Wert vor Ausführung = 0123h
PC-Wert nach Ausführung = 0345h
Dieser Unterprogrammaufruf-Opcode erscheint häufig in der MCU-Bootloader-Firmware. Angreifer, die den 11-Bit-addr11-Operanden durch Pufferüberlauf-Speicherkorruption überschreiben können, können die Programmausführung auf benutzerdefinierte Entsperr-Unterroutinen umleiten, die Lockbit-Schutzmaßnahmen deaktivieren. In den meisten Reverse-Engineering-Wiederherstellungsszenarien stellt das binäre Patchen der ACALL-Zieladresse eine einfache Methode dar, um die vollständige Flash-Firmware-Extraktion zu ermöglichen.
ADD A,Rn – Addiere Arbeitsregisterwert zum Akkumulatorregister
A: Akkumulatorregister
Rn: Beliebiges Arbeitsregister von R0 bis R7
Beschreibung: Der Opcode führt eine vorzeichenlose Byte-Addition zwischen dem Akkumulator und dem ausgewählten Arbeitsregister Rn durch und speichert die resultierende Summe zurück im Akkumulatorregister.
Syntax: ADD A,Rn;
Bytes: 1;
Betroffene PSW-Flags: C, OV, AC
BEISPIEL:
Vor Ausführung: A = 12h, R5 = 23h
Nach Ausführung: A = 35h, C = 0
Kapitel 4 : Mikrocontroller AT89S8253
Einleitung
Mehr als zwei Jahrzehnte sind seit der ursprünglichen Veröffentlichung des grundlegenden 8051-Mikrocontroller-Kerns vergangen. In dieser Zeit wurde die Architektur umfangreichen iterativen Upgrades und funktionalen Erweiterungen unterzogen. Heute produzieren Dutzende von Halbleiterherstellern weltweit kompatible derivative Mikrocontroller-Varianten unter verschiedenen Produktteilenummern. Moderne aktualisierte Iterationen bieten wesentlich erweiterte Funktionssätze im Vergleich zum ursprünglichen 8051-Design. Die meisten dieser Derivate tragen Bezeichnungen wie "8051-kompatibel", "8051-konform" oder "8051-Familie", um ihre gemeinsame architektonische Abstammung hervorzuheben. Diese Bezeichnungen bedeuten identische CPU-Kernarchitekturen und einheitliche Programmiermodelle, die den standardmäßigen 8051-Befehlssatz verwenden. In praktischen Entwicklungsabläufen ermöglicht die Beherrschung eines einzigen Geräts innerhalb dieser Familie eine nahtlose Migration zu jedem anderen kompatiblen Modell und gibt Ingenieuren Zugang zu Hunderten verschiedener Mikrocontroller-SKUs.
Dieses Kapitel konzentriert sich auf den von Atmel hergestellten Mikrocontroller AT89S8253 als repräsentatives Familienmitglied. Dieses spezielle Gerät wurde aufgrund seiner weiten industriellen Verbreitung, seiner niedrigen Stückkosten und des integrierten Flash-Programmspeichers für eine detaillierte Analyse ausgewählt. Die Flash-Speichereigenschaft macht es ideal für Prototyping und iterative Tests, da Programmabbilder tausende Male gelöscht und neu programmiert werden können. Darüber hinaus ermöglicht die integrierte SPI-Serienschnittstelle das erneute Flashen der Firmware, selbst nachdem der Chip dauerhaft auf Endprodukt-Leiterplatten gelötet wurde.
Diese bequeme In-Circuit-Programmierbarkeit birgt jedoch kritische Firmware-Sicherheitsrisiken. Wenn die Hardware-Lockbits des Geräts nicht programmiert sind, kann der gesamte Inhalt des Flash-Programmspeichers über die SPI-Schnittstelle extern ausgelesen werden. Atmel integrierte einen dreistufigen Hardware-Programmspeicher-Sperrmechanismus, um unbefugte externe Firmware-Extraktion zu blockieren. Dennoch sind Hardwaresicherungen nicht immun gegen Umgehung, unabhängig vom Mikrocontroller-Hersteller. Bösartige Reverse Engineers haben erfolgreich Chip-Dekapsulation und Mikrosondenangriffe eingesetzt, um Lockbit-Schutzmaßnahmen zu umgehen und vollständige Binär-Firmware-Abbilder wiederherzustellen. In bestimmten Exploit-Szenarien kann die On-Chip-EEPROM-Partition – die vertrauliche Kalibrierungsparameter, Serienkennungen und kryptografische Schlüssel speichert – vollständig mit dem MOVX-Befehl ausgelesen werden, wenn das EEMEN-Steuerbit aktiviert ist. Diese inhärente Schwachstelle unterstreicht die Notwendigkeit für eingebettete Entwickler, die nativen Sicherheitsmechanismen des AT89S8253 vollständig zu verstehen, wenn sie Produkte entwerfen, die robuste Firmware-Vertraulichkeit und Integritätsgarantien erfordern.
Der AT89S8253 integriert auch ein Hardware-Watchdog-Timer-Modul, das so konfiguriert werden kann, dass es Manipulationsereignisse erkennt und sofort einen vollständigen Systemreset auslöst. Die richtige Watchdog-Konfiguration dient als Anti-Extraktions-Gegenmaßnahme: Wenn ein Angreifer versucht, die CPU-Ausführung anzuhalten, um Bus-Sondierung oder Speicherdumping durchzuführen, wird der Watchdog-Timeout einen Geräte-Reset erzwingen und Datenwiederherstellungsversuche unterbrechen. Dennoch können Gegner Taktstörungsangriffe oder direkte Manipulation der Watchdog-Steuer-SFR-Register ausnutzen, um den Timer zu deaktivieren, sofern diese Register nicht durch Lockbit-Einschränkungen geschützt sind. Die kombinierte Bereitstellung von Lockbit-Sicherungen und Watchdog-Reset-Logik schafft eine mehrschichtige Hardware-Sicherheitsbarriere, die die Komplexität und Kosten des Geräteklonens und Reverse Engineerings erhöht. Wie bei allen 8051-Familien-Mikrocontrollern bietet keine einzelne Hardware-Sicherheitsprimitive absoluten Schutz. Die vollständige Firmware-Wiederherstellung erfordert typischerweise die Kombination mehrerer Angriffsmethoden, einschließlich elektromagnetischer Seitenkanalanalyse, Spannungs-/Fehlerinjektions-Störungen und vollständiger Silizium-Dekapsulation, um interne Sicherungssicherungen und Speicherzellen freizulegen. Sowohl eingebettete Sicherheitsverteidigungen als auch bösartige Extraktionstechniken entwickeln sich parallel zur allgemeinen industriellen Mikrocontroller-Bereitstellung weiter.
4.1 Identifikationsspezifikationen des AT89S8253
- Vollständig befehlssatzkompatibel mit der klassischen 8051-Kernarchitektur.
- 12 Kilobyte In-System-programmierbarer Flash-Programmspeicher.
- Firmware-Binärdateien werden über die integrierte SPI-Schnittstelle hochgeladen.
- Flash-Speicher unterstützt bis zu 1.000 kombinierte Lösch- und Schreibzyklen.
- 2 Kilobyte nichtflüchtiger On-Chip-EEPROM-Datenspeicher.
- Betriebsspannungsbereich: 4V bis 6V DC.
- Unterstützte externe Oszillatorfrequenz: 0 MHz bis 24 MHz.
- 256 Byte flüchtiger interner RAM für Laufzeitvariablen.
- 32 allgemeine digitale Ein-/Ausgangspins, aufgeteilt auf vier 8-Bit-Ports.
- Drei unabhängige 16-Bit-Timer/Zähler-Peripheriemodule.
- Neun verschiedene Hardware-Interruptquellen-Eingänge.
- Zwei zusätzliche stromsparende Betriebsmodi: Idle-Modus und Power-Down-Modus.
- Konfigurierbare Hardware-UART-asynchrone serielle Kommunikationsperipherie.
- Integrierter programmierbarer Watchdog-Timer-Peripherie.
- Dreistufiges Hardware-Programmspeicher-Sicherungssperrsystem.
Der AT89S8253-Halbleiterdie ist in drei standardmäßigen Industriegehäuseformen verpackt:
Die physische Gehäuseform hat direkten Einfluss auf die Schwierigkeit destruktiver Dekapsulationsangriffe. Größere Gehäuse mit größerer freiliegender Siliziumoberfläche (wie DIP und PLCC) sind für Gegner wesentlich einfacher zu sezieren und zu mikroskopieren als kompakte TQFP-Oberflächenmontagegehäuse. Unabhängig von der Gehäusevariante bleiben Hardware-Lockbits die primäre Verteidigungslinie gegen externes Firmware-Dumping über die Programmierchnittstelle. Die Industriestandardpraxis schreibt vor, die höchste verfügbare Sperr-Sicherheitsstufe zu programmieren, um alle SPI-Rücklesebefehle zu deaktivieren. Viele Hardware-Designteams härten Geräte weiter, indem sie die SPI-Programmierpin-Schaltungen nach der Massenproduktion dauerhaft deaktivieren, um die Hürde gegen unbefugte Firmware-Extraktionsversuche zu erhöhen.
4.2 Pinbelegungsfunktionsbeschreibungen
VCC Hauptpositive Stromversorgung (4V bis 6V DC Betriebsbereich)
GND Systemmasse (negative Stromschiene)
Port 0 (P0.0–P0.7) Als digitale Ausgänge konfiguriert, kann jeder Pin bis zu 8 standardmäßige TTL-Logikeingänge treiben. Im Eingangsmodus arbeiten die P0-Pins als hochohmige schwebende Eingänge mit undefinierten Spannungspegeln relativ zur Masse. Bei externer Daten- oder Programmspeichererweiterung dient Port 0 als multiplexter Adress-/Datenbus. Das ALE-Steuerpin-Signal bestimmt, ob Adress- oder Datenwerte über die Port-0-Busleitungen übertragen werden.
Port 1 (P1.0–P1.7) Im Ausgangsmodus kann jeder Port-1-Pin bis zu 4 TTL-Eingänge treiben. Als Eingänge konfiguriert, fungieren diese Pins als standardmäßige TTL-kompatible Eingänge mit internen schwachen Pull-up-Widerständen zur 5V-VCC-Versorgung. Jeder Port-1-Pin bietet auch dedizierte sekundäre alternative Peripheriefunktionen, die in der folgenden Tabelle aufgeführt sind:
| Port-Pin-Kennung |
Alternative Peripheriefunktion |
| P1.0 |
T2 (Timer 2 externer Zählereingang) |
| P1.1 |
T2EX (Timer 2 externer Trigger-Steuereingang) |
| P1.4 |
SS (SPI-Slave-Auswahlsignal) |
| P1.5 |
MOSI (SPI-Master-Ausgang / Slave-Eingang) |
| P1.6 |
MISO (SPI-Master-Eingang / Slave-Ausgang) |
| P1.7 |
SCK (SPI-synchrones serielles Taktsignal) |
Port 2 (P2.0–P2.7) Die elektrischen Eigenschaften von Port 2 entsprechen denen von Port 1 für Eingangs- und Ausgangsmodi. Bei externer Speichererweiterung gibt Port 2 das obere 8-Bit-Byte des 16-Bit-Speicheradressbusses (A8–A15) zur Zielspeicheradressierung aus.
Port 3 (P3.0–P3.7) Port 3 teilt die gleiche allgemeine Ein-/Ausgangsfunktionalität mit Port 1, und jeder Pin implementiert dedizierte sekundäre Peripherie-Alternativfunktionen, die später in diesem Kapitel detailliert beschrieben werden.
| Port-Pin-Kennung |
Alternative Peripheriefunktion |
| P3.0 |
RXD (UART serieller Datenempfangseingang) |
| P3.1 |
TXD (UART serieller Datenausgang) |
| P3.2 |
INT0 (Externer Hardware-Interrupt 0 Trigger-Eingang) |
| P3.3 |
INT1 (Externer Hardware-Interrupt 1 Trigger-Eingang) |
| P3.4 |
T0 (Timer 0 externer Ereigniszähler-Eingang) |
| P3.5 |
T1 (Timer 1 externer Ereigniszähler-Eingang) |
| P3.6 |
WR (Schreib-Strobe-Steuersignal für externen Datenspeicher) |
| P3.7 |
RD (Lese-Strobe-Steuersignal für externen Datenspeicher) |
RST Ein logisch-hoher (digital 1) Spannungspegel an diesem Pin löst eine vollständige Mikrocontroller-Hardware-Reset-Sequenz aus.
ALE/PROG Während des normalen Betriebs erzeugt der ALE-Pin ein kontinuierliches Taktimpulssignal mit einer Frequenz von 1/16 der Hauptoszillatorfrequenz, das für externe Timing- und Taktgeneratorschaltungen verwendet werden kann. Bei aktiver externer Speichererweiterung latcht das ALE-Signal das untere 8-Bit-Adressbyte (A0–A7), das über Port 0 übertragen wird. Während Flash-In-System-Programmiervorgängen dient dieser Pin auch als dedizierte Programmier-Steuereingangsleitung.
PSEN Dieser Pin gibt ein aktives-niedriges Strobe-Signal aus, das ausschließlich für den Zugriff auf externe Off-Chip-Programm-ROM-Speichergeräte verwendet wird.
EA/VPP Das direkte Verbinden dieses Pins mit der Systemmasse zwingt die CPU, alle Programmbefehle aus dem externen Off-Chip-Programmspeicher zu holen. Für standardmäßige eingebettete Anwendungen, die den On-Chip-Flash-Programmspeicher nutzen (das häufigste Bereitstellungsszenario), muss dieser Pin mit der positiven VCC-Versorgung verbunden werden. Während Hochspannungs-Flash-Programmierzyklen erhält dieser Pin eine +12V-Programmiervorspannung.
XTAL 1 Eingangspin des internen Oszillators. Dieser Anschluss verbindet sich mit externen Quarzkristallkomponenten oder externen Präzisionstaktsignalquellen für den synchronen CPU-Betrieb.
XTAL 2 Ausgangspin des internen Oszillators. Dieser Pin bleibt ungenutzt, wenn ein externes, eigenständiges Taktsignal an XTAL1 angelegt wird.
4.3 Speicherarchitektur des AT89S8253
Programmspeicher (Flash-ROM)
Die 12-Kilobyte-Programmspeicherbank wird mithilfe von Floating-Gate-Flash-Halbleitertechnologie implementiert, was wiederholte Lösch- und Neuprogrammierzyklen ermöglicht. Alle Programmbinarys werden über die integrierte SPI-Schnittstelle in den Flash geschrieben. Die externe Off-Chip-Programm-ROM-Erweiterung wird als optionale Hardware-Erweiterung unterstützt, obwohl die native 12KB-Flash-Kapazität die meisten eingebetteten Anwendungsanforderungen ohne zusätzliche externe Speicherhardware erfüllt.
Aus Sicht der Hardware-Sicherheitsbedrohung stellt der On-Chip-Flash-Programmspeicher das primäre Ziel für unbefugte Firmware-Wiederherstellungsangriffe dar. Ordnungsgemäß programmierte Lockbit-Sicherungen blockieren alle externen Rücklesebefehle, die über die SPI-Programmierschnittstelle übertragen werden. Der physische Zugriff auf den verpackten Chip ermöglicht jedoch kostspielige, aber bewährte Dekapsulationsangriffe, bei denen die schützende Epoxidharzverpackung entfernt wird, um den Silizium-Die freizulegen, was eine direkte elektrische Mikrosondierung einzelner Flash-Speicherzellen ermöglicht. Um diesen kostenintensiven physischen Angriffsvektor zu mindern, implementierte Atmel drei hierarchische Sperr-Sicherheitsstufen, aber alle hardware-basierten Sicherungsschutzsysteme bleiben für fortgeschrittene Reverse-Engineering-Laborgeräte und -Techniken anfällig.
Random Access Memory (RAM)
Der interne flüchtige RAM-Bereich ist in drei diskrete 128-Byte-Speicherblöcke unterteilt, die streng der ursprünglichen 8051-Speicherlayout-Spezifikation entsprechen:
- 128 Byte allgemeiner Laufzeitarbeitsspeicher;
- 128 reservierte Adressplätze, die ausschließlich für Special Function Registers (SFRs) reserviert sind. Nicht belegte, ungenutzte SFR-Adressen können nicht für allgemeine Variablenspeicherung umfunktioniert werden; und
- Eine zusätzliche 128-Byte-Bank mit allgemeinem RAM ohne dedizierte Hardware-Peripheriefunktionen. Diese Speicherplätze teilen sich die gleichen Adressoffsets wie der SFR-Block und sind nur über indirekte Adressierungsmodi zugänglich.
EEPROM-nichtflüchtiger Datenspeicher
EEPROM ist ein hybrider nichtflüchtiger Speicher, der die Lese-/Schreibflexibilität von RAM mit der persistenten Datenspeicherung von ROM kombiniert. Daten, die in EEPROM geschrieben werden, bleiben ohne kontinuierliche Stromversorgung des Mikrocontrollers dauerhaft gespeichert. Der AT89S8253 integriert insgesamt 2 Kilobyte (2048 einzelne Byte-Positionen) dedizierten On-Chip-EEPROM-Speicher.
Diese EEPROM-Partition wird üblicherweise zur Speicherung geräteeindeutiger Seriennummern, Fabrikkalibrierungskoeffizienten und vertraulicher kryptografischer Sicherheitsschlüssel verwendet. Ein erfolgreiches unbefugtes Auslesen der EEPROM-Partition legt alle darin gespeicherten sensiblen eingebetteten Geheimdaten offen. Während Hardware-Lockbits auch externe SPI-basierte EEPROM-Lesevorgänge einschränken, bleibt diese Speicherbank anfällig für elektromagnetische Seitenkanal-Leckageanalyse und Spannungs-Fehlerinjektions-Störungen. In bestimmten Exploit-Szenarien können vollständige EEPROM-Speicherdumps mithilfe der MOVX-externen Speicherbefehlsequenz ausgeführt werden, wenn das EEMEN-Steuerbit im EECON-SFR gesetzt ist, was eine gut dokumentierte Hardware-Hintertür-Schwachstelle für böswillige Firmware-Extraktion darstellt.
Externe Speichererweiterungsfähigkeiten
Alle Regeln für die externe Programm- und Datenspeichererweiterung, die für den ursprünglichen 8051-Kern definiert wurden, gelten vollständig für den AT89S8253. Sowohl Programm-ROM als auch Daten-RAM können mit externen Halbleiterspeicherchips auf eine maximale adressierbare Kapazität von jeweils 64 Kilobyte erweitert werden. Der 16-Bit-Speicheradressierungsmechanismus funktioniert identisch zur ursprünglichen 8051-Architektur.
Unterstützte Speicheradressierungsmodi
Konsistent mit allen standardmäßigen 8051-kompatiblen Mikrocontrollern werden zwei verschiedene Speicheradressierungsmodi im CPU-Befehlssatz implementiert:
- Direkte Adressierung (Beispielbefehlssyntax: MOV A,30h); und
- Indirekte Adressierung (Beispielbefehlssyntax: MOV A,@R0).
Ein umfassendes Verständnis dieser beiden Adressierungsmodi ist für die Sicherheitsverteidigung eingebetteter Systeme entscheidend. Indirekte Adressierungsmechanismen stellen einen bedeutenden Exploit-Vektor dar: Wenn ein Angreifer den Zeigerwert in den indirekten Adressierungsregistern R0/R1 korrumpiert, kann er Speicherlesevorgänge umleiten, um auf geschützte Speicherbereiche zuzugreifen, die normalerweise durch direkte Adressierungseinschränkungen blockiert sind. Diese Klasse von Speicherkorruptionsexploits wird häufig genutzt, um gesperrte Firmware-Binärdateien zu extrahieren, wenn der direkte Speicherzugriff durch Hardware-Sicherungen blockiert ist.
4.4 Special Function Registers (SFRs)
Der AT89S8253 verfügt über insgesamt 40 eindeutige Special Function Registers. Um die vollständige Abwärtskompatibilität mit älteren 8051-Mikrocontroller-Generationen zu gewährleisten, behält der Kernbestand von 22 grundlegenden Systemregistern über alle Familienvarianten hinweg identische Speicheradressen und Funktionalität bei. Die verbleibenden ergänzenden SFRs wurden hinzugefügt, um die Kontrolle über die erweiterten Peripheriehardware-Module des AT89S8253 zu ermöglichen, die in diesem aktualisierten Derivatdesign eingeführt wurden.
Wie in der SFR-Speicherkarte dargestellt, ist jedem Register ein eindeutiger fester RAM-Adressoffset zugewiesen. Unbenutzte reservierte Adressplätze sind für zukünftige Siliziumrevisions-Upgrades vorgesehen und dürfen niemals für benutzerdefinierte Variablenspeicherung verwendet werden. Wie ihr Name schon sagt, steuert jedes SFR den Betrieb eines dedizierten Hardware-Peripheriesubschaltkreises, einschließlich Timer, UART und SPI-Schnittstellen, die alle später in diesem Kapitel ausführlich behandelt werden. Dieser Abschnitt behandelt nur die kernsystemweiten SFR-Register, die mehrere unabhängige Hardwaremodule gleichzeitig steuern.
Unter allen erweiterten SFR-Peripheriegeräten ist das EECON-EEPROM-Steuerregister der sicherheitsrelevanteste Peripheriesteuerblock, da es alle Lese-/Schreibzugriffsberechtigungen für die interne nichtflüchtige EEPROM-Speicherbank verwaltet. Ein Gegner, der in der Lage ist, das EEMEN-Bit im EECON zu setzen, kann die MOVX-Befehlsequenz nutzen, um den gesamten EEPROM-Adressraum vollständig auszulesen und damit die Hardware-Lockbit-Schutzmaßnahmen effektiv zu umgehen. Dieser ungepatchte Hardware-Designfehler ist eine gut dokumentierte kritische Schwachstelle, die in mehreren 8051-Derivat-Mikrocontroller-Varianten vorhanden ist. In ähnlicher Weise steuert das WDTCON-Watchdog-Timer-Steuerregister die Manipulationserkennungs-Reset-Logik; Angreifer können jedoch den Watchdog-Zählerbetrieb durch präzise Taktstörungen oder direkte SFR-Register-Schreibvorgänge deaktivieren, wenn die Watchdog-Steuerregister nicht durch Lockbit-Einschränkungen geschützt sind. Hardware-Lockbit-Sicherungen und Watchdog-Timeout-Reset-Logik arbeiten als komplementäre mehrschichtige Sicherheitsbarrieren, die darauf abzielen, die Komplexität des Geräteklonens und Firmware-Reverse-Engineerings zu erhöhen. Leider bietet keine einzelne Hardware-Sicherheitsprimitive absolute Manipulationssicherheit, da die Silizium-Dekapsulation Sicherungszustände freilegen und physisch verändern kann, um Sperrschutzmaßnahmen zu neutralisieren. Diese kritische Einschränkung hat die Entwicklung moderner sicherer Mikrocontroller-Hardware vorangetrieben, die aktive Metallabschirmung und dedizierte Manipulationserkennungssensorschaltungen integriert.