Assembly Code Hilfe?
Hallo, was genau macht dieser Code ? Könnte mir wer das netterweise erklären, da ich asm bisschen besser verstehen möchte :) Danke im Voraus.
[bits 16]
[org 0x7c00]
mov bx, msg
call print
jmp $
print:
pusha
start:
mov ah, 0x0e
mov al, [bx]
cmp al, 0
je end
int 0x10
inc bx
jmp start
end:
ret
popa
msg db "RIP your MBR...", 0
times 510 - ($ - $$) db 0
dw 0xaa55
3 Antworten
Assembler Code ist µController abhängig. Der Befehlssatz hängt vom Zielsystem ab, welches hier nicht angegeben ist. Also bleibt eine Unsicherheit in der Interpretation.
mov bx, msg 'mov ist eine Inhaltsübernahme: Inhalt von msg->bx kopieren (verschieben)
"cmp" bedeutet vergleichen.
"Print" ist eine Springmarke die hier wie ein Funktionsaufruf verwendet wird.
jmp bedeutet jump also ein Sprung an diese Stelle
pusha, popa sind Kommandos für die Stackverwendung
'inc' bedeutet inkrementieren. also den Inhalt um +1 erhöhen.
Scheint mir eine Schleife zu sein, die eine Zeitverzögerung darstellt.
Bis "Rest in Peace" kann also 'sehr lange' laufen.
Am Schluss noch ne Kennung die als Muster gerne verwendet wird: Binär Anagram
aa55= 10101010 01010101
[bits 16]
[org 0x7c00]
Das sind Assembler-Direktiven (verwende 16bit, starte an Adresse 0x7c00).
mov bx, msg
call print
Lade die Adresse msg ins Register bx und rufe dann print auf.
jmp $
$ ist die aktuelle Adresse. Das ist also eine Endlosschleife.
start:
mov ah, 0x0e
mov al, [bx]
...
int 0x10
int 0x10 ist ein BIOS-Funktionsaufruf. Das Register ah bestimmt die gewünschte Funktion (0x0e=Zeichen auf der Konsole ausgeben), und al enthält das Zeichen, hier das Byte an Adresse bx (beim ersten Aufruf also 'R').
inc bx
jmp start
Erhöht die Adresse und wiederholt die Ausgabe (für 'I', 'P', ' ', ...). Die Schleife endet, wenn 0 ausgegeben werden soll (hab' ich oben weggelassen).
msg db "RIP your MBR...", 0
Setzt das Label msg auf die aktuelle Adresse und legt dort ein paar Daten-Bytes ab; hier ein paar ASCII-Zeichen und ein abschließendes 0-Byte.
times 510 - ($ - $$) db 0
dw 0xaa55
$ ist die aktuelle Adresse, $$ vermutlich die Startadresse (von [org ...]). Dann wird von hier bis zur Adresse 0x7c00+510 mit Nullen aufgefüllt, und das Wort 0xaa55 (als 55 AA) angehängt. Der gesamte Block hat damit die Größe 512 Bytes.
Übrigens ist der MBR (erster Sektor auf der Festplatte) auch 512 Bytes lang und muss mit 0x55 0xaa enden. Gewöhnlich enthält er Code zum laden eines Betriebssystems nach dem Einschalten des Rechners.
Zusammen mit dem Text, der ausgegeben wird, würde ich das Programm, das diesen Code enthält, nur mit allergrößter Vorsicht ausführen − außer, Du nutzt Windows und musst Dein System sowieso ständig neu installieren :-)
Ich habe schon immer viel Mathematik gemacht; anfangs noch mit Rechenschieber und Tafeln, dann kam der Taschenrechner und später mein erster Computer. Aber auch der hat für meine Berechnungen oft Stunden oder sogar Tage gebraucht. Mit Assembler konnte ich die größte Rechenpower rausholen. Das habe ich mir selbst aus Büchern beigebracht.
[bits 16]
[org 0x7c00]
mov bx, msg // Kopiere die Adresse von "msg" ins bx Register, unten wird mit db ein String definiert, msg zeigt dann auf das erste Byte des Strings
call print // Springe Unterprogramm an, Adresse des nächsten befehls wird auf den Stack geschrieben damit der Prozessor weiß, wohin er bei Return zurüpck springen muss.
jmp $ // Programmende
print: // "Label", wird genutzt um die Adresse des nächsten Befehls herauszukriegen.
pusha // Inhalt der Prozessorregister auf den Stack schieben
start: // Label
mov ah, 0x0e // Kopiere den Wert 0e (hex) ins h Register, der Akku besteht aus HIGH und LOW register, hier wird also ein Wert in die obere Hälfte des Akkus kopiert
mov al, [bx] // Kopiere Inhalt des bx Registers in das l Register des Akkus (untere Hälfte des Akkus)
cmp al, 0 // Vergleiche l Reg des Akkus mit "0", überspringe den nächsten Befehl falls ungleich.
je end // Springe an Adresse end (label), das passiert hier wenn eine 0 im String gefunden wurde, also das Stringendezeichen im l register liegt
int 0x10 // Löse Interrupt 10h aus. Das ist der BIOS Interrupt zur Bildschirmsteuerung, genaueres hier: https://en.wikipedia.org/wiki/INT_10H
inc bx // Inkrementiere (um eins erhöhen) Register bx, das Register zeigt danach auf das nächste Zeichen im String.
jmp start // Springe an die Adresse hinter dem Label start. Damit hat man eine Schleife.
end:
ret // Return, springe aus dem Unterprogramm zurück, Adresse steht im Stack
popa // Hole die Werte der Prozessorregister vom Stack zurück die bei pusha abgelegt wurden.
msg db "RIP your MBR...", 0 // Erzeuge einen String im Speicher an der Adresse msg, wird vom Assembler angelegt bei Assemblierung des Programms angelegt, ebenso werden alle Adressen der Labels und Variablen wie dieser ausgerechnet.
times 510 - ($ - $$) db 0
dw 0xaa55
Wenn Du anschaulich lernen willst wie Maschinensprache (bzw. Assembler) programmiert wird, dann hol Dir das Spiel "Human Ressource Machine". Da steuert man einen Büroangestelten mit Befehlen die ein sehr einfacher RISC Prozessor auch hat und kann dem zusehen wie er das Programm abarbeitet.
Ich denke, dass das mir auch sehr weiterhilft unabhängig von Assembly. Ich code in C++ und versuche generell das “Vorgehen “ eines PC’s zu lernen. Danke :)
Hi, danke für deine Mühe, du hast mir sehr weitergeholfen. Bezüglich dem Code: Ich code Malware ( zum Lernen ) für mich selbst in C/C++ und habe sehr großes Interesse Assembly zu lernen. Wo haben Sie es gelernt, wenn ich fragen darf ^^ ?