Εργαστήριο ΕΙΣΑΓΩΓΗ ΣΤΗΝ INTEL ASSEMBLY 32BIT

Σχετικά έγγραφα
Δομημένος Προγραμματισμός

Συμβολική γλώσσα Εκπαιδευτικού Υπολογιστή - Λογισμικό Υπολογιστών

Η-Υ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ. Εργαστήριο 1 Εισαγωγή στη C. Σοφία Μπαλτζή s.mpaltzi@di.uoa.gr

Συνοπτικό εγχειρίδιο χρήσης του Microsoft Visual Studio 2010

Προηγμένοι Μικροεπεξεργαστές. Έλεγχος Ροής Προγράμματος

ΕΡΓΑΣΤΗΡΙΟ 3: Προγραμματιστικά Περιβάλλοντα και το Πρώτο Πρόγραμμα C

Αρχιτεκτονική Υπολογιστών Εργαστήριο

MIPS Interactive Learning Environment. MILE Simulator. Version 1.0. User's Manual

Οργάνωση και Σχεδίαση Υπολογιστών Η Διασύνδεση Υλικού και Λογισμικού, 4 η έκδοση. Σύντομη Εισαγωγή στη χρήση του προσομοιωτή και συμβολομεταφραστή

FORTRAN και Αντικειμενοστραφής Προγραμματισμός

Διαδικασιακός Προγραμματισμός

Τι χρειάζεται ένας φοιτητής για τη σωστή παρακολούθηση και συμμετοχή στο μαθημα;

Μικροεπεξεργαστές - Μικροελεγκτές Ψηφιακά Συστήματα

Συνοπτικό εγχειρίδιο χρήσης του Microsoft Visual Studio 2010

Προηγμένοι Μικροεπεξεργαστές. Εργαστήριο 4 - Editor

ΕΡΓΑΣΤΗΡΙΟ 3: Προγραμματιστικά Περιβάλλοντα και το Πρώτο Πρόγραμμα C

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Προγραμματισμός και Χρήση Ηλεκτρονικών Υπολογιστών - Βασικά Εργαλεία Λογισμικού

Ανάπτυξη εφαρμογής Input-Output

ΑΣΚΗΣΗ 1: TO ΠΕΡΙΒΑΛΛΟΝ ΕΡΓΑΣΙΑΣ DEV-C++

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 3-4: Προγραμματισμός MIPS. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Εισαγωγή εκτελέσιμου κώδικα σε διεργασίες

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Εργαστήριο 3 ΟΡΓΑΝΩΣΗ ΤΗΣ ΚΜΕ. Εισαγωγή

Συστήματα Μικροεπεξεργαστών

Αρχιτεκτονική Υπολογιστών

Data-Level Parallelism Linking & Loading

Οργάνωση επεξεργαστή (1 ο μέρος) ΜΥΥ-106 Εισαγωγή στους Η/Υ και στην Πληροφορική

ΕΡΓΑΣΤΗΡΙΟ 3: Προγραμματιστικά Περιβάλλοντα και το Πρώτο Πρόγραμμα C

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

ΕΡΓΑΣΤΗΡΙΟ ΑΡΧΙΤΕΚΤΟΝΙΚΗΣ ΙΙ Εργαστήριο 2 ο ΔΟΜΗ ΠΡΟΓΡΑΜΜΑΤΟΣ- ΨΕΥΔΟΕΝΤΟΛΕΣ ΜΑΚΡΟΕΝΤΟΛΕΣ- ΔΙΑΔΙΚΑΣΙΕΣ (ΕΙΣΑΓΩΓΗ)

Αρχιτεκτονική Υπολογιστών Ασκήσεις Εργαστηρίου

Αντικειμενοστρεφής Προγραμματισμός

Μικροεπεξεργαστές. Σημειώσεις Μαθήματος Υπεύθυνος: Δρ Άρης Παπακώστας,

Αρχιτεκτονική Υπολογιστών

Εντολές εισόδου - εξόδου. Εισαγωγή στη C++

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Δημιουργία μιας εφαρμογής Java με το NetBeans

Εισαγωγή στο περιβάλλον Code::Blocks

Προγραµµατισµός Ι Εισαγωγή Πανεπιστήµιο Πελοποννήσου Τµήµα Πληροφορικής & Τηλεπικοινωνιών Προγραµµατισµός Ι Νικόλαος Δ. Τσελίκας

Μικρή Εισαγωγή στο wxdev-c++

Η γλώσσα προγραμματισμού C

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Κεφάλαιο 2.3: Προγραμματισμός. Επιστήμη ΗΥ Κεφ. 2.3 Καραμαούνας Πολύκαρπος

Εισαγωγή στη γλώσσα προγραμματισμού C++

Το λειτουργικό σύστημα. Προγραμματισμός II 1

ΕΡΓΑΣΤΗΡΙΟ 6: Συναρτήσεις και Αναδρομή

Αρχιτεκτονικές Συνόλου Εντολών (ΙΙ)

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

To περιβάλλον Ανάπτυξης εφαρμογών της Visual Basic 2008 Express Edition

Αρχιτεκτονική x86(-64) 32-bit και 64-bit λειτουργία. Αρχιτεκτονική x86(-64) Αρχιτεκτονική επεξεργαστών x86(-64) Αρχιτεκτονικές Συνόλου Εντολών (ΙΙ)

Εγχειρίδιο χρήσης του Άβακα

Αρχιτεκτονική Υπολογιστών

Διαδικασιακός Προγραμματισμός

Διαδικασιακός Προγραμματισμός

Αρχιτεκτονική Υπολογιστών Ασκήσεις Εργαστηρίου

Είναι μια αλληλουχία κατάλληλων οδηγιών(εντολών) που εκτελεί ο υπολογιστής για την επίλυση ενός προβλήματος.

Προηγμένοι Μικροεπεξεργαστές. Εργαστήριο 6 C & Assembly

Το λειτουργικό σύστημα. Προγραμματισμός II 1

Αρχιτεκτονική Υπολογιστών

Δομή Προγράμματος C++, Χειρισμός Μεταβλητών και Συναρτήσεις Εισόδου - Εξόδου

Προγραμματισμός I (Θ)

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Παράλληλη Επεξεργασία

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Προγραμματισμός Ι (HY120)

ΤΕΙ ΙΟΝΙΩΝ ΝΗΣΩΝ ΣΧΟΛΗ ΔΙΟΙΚΗΣΗΣ ΚΑΙ ΟΙΚΟΝΟΜΙΑΣ ΤΜΗΜΑ ΔΙΟΙΚΗΣΗΣ ΕΠΙΧΕΙΡΗΣΕΩΝ - ΕΙΣ

ΕΡΓΑΣΤΗΡΙΟ 16. Χρησιμοποιώντας τον Αποσφαλματιστή (Debugger) του Eclipse

Περιεχόµενα. I Βασικές Γνώσεις 1

Αρχιτεκτονική Υπολογιστών Ι

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

S, (5, -3, 34, -23, 7) ( *, _

Δομημένος Προγραμματισμός

ΚΕΦΑΛΑΙΟ 4ο. Α. Το περιβάλλον της Microsoft Fortran Powerstation

Εισαγωγή στη γλώσσα προγραμματισμού JAVA. Δομές Δεδομένων Διδάσκων: Π.Α. Μήτκας Τομέας Ηλεκτρονικής και Υπολογιστών

C: Από τη Θεωρία στην Εφαρµογή 2 ο Κεφάλαιο

Αρχιτεκτονική Υπολογιστών

1. Ξεκινώντας. 1.1 Τι είναι η Java. PDF created with FinePrint pdffactory Pro trial version

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ. Εισαγωγή στην FORTRAN. Δρ. Ιωάννης Λυχναρόπουλος

Εργαστήριο 4. Εαρινό Εξάμηνο ΠΡΟΣΟΧΗ: Αρχίστε νωρίς το Εργαστήριο 4. Οι ασκήσεις είναι πιο απαιτητικές από τα προηγούμενα εργαστήρια.

Μετάφραση ενός Προγράμματος Εξαιρέσεις

Αρχιτεκτονική Υπολογιστών

ΜΥΥ- 402 Αρχιτεκτονική Υπολογιστών Μεταγλώτιση, σύνδεση

ΕΡΓΑΣΤΗΡΙΟ ΑΡΧΙΤΕΚΤΟΝΙΚΗΣ Η/Υ

ΘΕΜΑΤΑ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ Η/Υ

Ανάπτυξη εφαρμογής Input-Output

Εργαστήριο Δομημένος Προγραμματισμός (C#) Τμήμα Μηχανολογίας Νικόλαος Ζ. Ζάχαρης Καθηγητής Εφαρμογών

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Διάλεξη 2η: Αλγόριθμοι και Προγράμματα

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

Αρχιτεκτονική Υπολογιστών Ασκήσεις Εργαστηρίου

Αρχιτεκτονική Υπολογιστών Ασκήσεις Εργαστηρίου

Εισαγωγή. Διαλέξεις στο μάθημα: Μεταφραστές Γιώργος Μανής

Πως θα κατασκευάσω το πρώτο πρόγραμμα;

ΗΥ 232 Οργάνωση και Σχεδίαση Υπολογιστών. Intel x86 ISA. Νίκος Μπέλλας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών ΗΥ

H ΓΛΩΣΣΑ C. Μάθηµα 1: Το Πρώτο µας Πρόγραµµα σε C. ηµήτρης Ψούνης

Ανάπτυξη Εφαρμογών σε Προγραμματιστικό Περιβάλλον κεφ.6 Εισαγωγή στον Προγραμματισμό

Πληροφορική 2. Γλώσσες Προγραμματισμού

Transcript:

Εργαστήριο ΕΙΣΑΓΩΓΗ ΣΤΗΝ INTEL ASSEMBLY 32BIT Εισαγωγή 1 Σκοπός του εργαστηρίου είναι η εισαγωγή στον προγραμματισμό στη συμβολική γλώσσα assembly των 32-bit επεξεργαστών της Intel μέσα από απλά προγράμματα εμφάνισης δεδομένων. 1 Εισαγωγή στην Intel assembly 32bit 2 Είσοδος έξοδος δεδομένων 3 Αριθμητικές & λογικές πράξεις 4 Έλεγχος ροής εκτέλεσης 5 Διαδικασίες και μακροεντολές 6 Πίνακες και αλφαριθμητικά 7 Διαχείριση αρχείων 8 Πλαίσια μηνυμάτων και παράθυρα 9 Χρήση της assembly με την C/C++ 10 Ολοκληρωμένα Συστήματα - Εφαρμογές Μορφή προγράμματος 32-bit assembly Η βασική μορφή ενός 32-bit assembly προγράμματος έχει ως ακολούθως:.386 ; ή.486,.586,.686.model FLAT, STDCALL.STACK <τιμή> option casemap :none.data <αρχικοποιημένα δεδομένα>....data? < μη αρχικοποιημένα δεδομένα >....CONST <σταθερές>....code <ετικέτα>: <ο κώδικας της εφαρμογής>... end <ετικέτα> Επεξηγήσεις.386 Ενημερώνει τον συμβολομεταφραστή να κάνει χρήση του συνόλου εντολών για επεξεργαστές 80386 και μετέπειτα (ο επεξεργαστής 80386 ήταν η πρώτη μηχανή των 32-bit συνόλου εντολών)..model FLAT, STDCALL.MODEL <μοντέλο μνήμης> <calling convention> βασικά προσδιορίζει το μοντέλο μνήμης του προγράμματος και τον τρόπο περάσματος παραμέτρων. 1

Μόνο ένα μοντέλο είναι διαθέσιμο στο περιβάλλον ανάπτυξης 32-bit Windows εφαρμογών κι αυτό είναι το FLAT ανεξάρτητα από το είδος της εφαρμογής προς ανάπτυξη (standard executable, console, dll, static library, κλπ.). Σε αυτό το μοντέλο (protected mode) η μνήμη αποτελεί ένα μεγάλο συνεχές τμήμα (για δεδομένα και κώδικα) μεγέθους 4GB (2 32 ). Το λειτουργικό Windows εκτελεί κάθε Win32 εφαρμογή σε ένα ξεχωριστό εικονικό χώρο (virtual space) που σημαίνει ότι κάθε εφαρμογή έχει το δικό της 4GB χώρο διευθύνσεων. Αυτό δεν σημαίνει ότι κάθε Win32 εφαρμογή έχει 4GB φυσικής μνήμης αλλά ότι μπορεί να προσπελάσει οποιαδήποτε διεύθυνση σε αυτό το εύρος και το λειτουργικό θα φροντίσει αυτές οι αναφορές της εφαρμογής να είναι έγκυρες. Έτσι γίνεται κατανοητό ότι εδώ δεν χρειάζεται να μας απασχολούν τα διάφορα μοντέλα μνήμης (models) και τα τμήματα (segments) όπως γινόταν στην ανάπτυξη 16- bit εφαρμογών. STDCALL (Windows API calling convention) ενημερώνει τον assembler για τον τρόπο με τον οποίο οι παράμετροι περνούν στις συναρτήσεις κατά την κλήση τους (από τα δεξιά-στα-αριστερά) καθώς και για την εξισορρόπηση της στοίβας μετά την ολοκλήρωση της κλήσης της συνάρτησης (η καλούμενη συνάρτηση είναι υπεύθυνη). Άλλες επιλογές μπορεί να είναι: C, BASIC, FORTRAN, PASCAL, SYSCALL..STACK <τιμή> Προσδιορίζει το μέγεθος της στοίβας, π.χ..stack 4096 προσδιορίζει μια 4K στοίβα. option casemap :none Με αυτή την επιλογή οι ετικέτες είναι case sensitive. Δηλαδή οι upper case και lower case χαρακτήρες αντιμετωπίζονται ως διαφορετικοί..data Εμπεριέχει τα αρχικοποιημένα δεδομένα (variables) του προγράμματος..data? Εμπεριέχει μη αρχικοποιημένα δεδομένα. Μπορεί να χρησιμοποιηθεί όταν θέλουμε να δεσμεύσουμε μνήμη χωρίς να την αρχικοποιήσουμε. Ένα πλεονέκτημα είναι ότι δεν δεσμεύει χώρο στο εκτελέσιμο. Απλώς ενημερώνουμε τον assembler για το χώρο που χρειάζεται το πρόγραμμά μας κατά τη φόρτωσή του στη μνήμη..const Εμπεριέχει δηλώσεις σταθερών (constants)..code etiketa: Ο κώδικας του προγράμματος. End etiketa 2

ΠΑΡΑΔΕΙΓΜΑ 1 Παράδειγμα προγράμματος που αθροίζει δυο ακεραίους και τοποθετεί το αποτέλεσμα στη μνήμη. ; κάνει χρήση της εντολής ADD για να αθροίσει το 5 και το 10 σε δεκαεξαδική μορφή και τοποθετεί το αποτέλεσμα στη μνήμη στην παράμετρο sum.386.model flat, stdcall.data? sum DWORD? ; δεσμεύει 4 bytes (32 bits).code start: ret end start mov eax,05h ; 5 add eax,0ah ; 5+10 mov sum, eax Μπορούμε να παρακολουθήσουμε την εκτέλεση του προγράμματος και να δούμε το αποτέλεσμα που προκύπτει στη μνήμη κάνοντας χρήση κάποιου debugger, π.χ. όπως ο OllyDbg. Σε αυτόν τον debugger, επιλέγοντας DEBUG-> Step into μπορούμε να παρακολουθήσουμε τη βηματική εκτέλεση της κάθε εντολής του προγράμματός μας στο παράθυρο disassembly, όπως έχει διαμορφωθεί με τις πρόσθετες εντολές που προκύπτουν από τη μετάφραση, και στα παράθυρα των καταχωρητών και της μνήμης πως διαμορφώνονται τα περιεχόμενά τους. Το παράθυρο disassembly: Το αποτέλεσμα της άθροισης F που έχει προκύψει με την εντολή ADD στον καταχωρητή EAX, η εντολή MOV το τοποθετεί στην παράμετρο sum στη διεύθυνση [00402000] στο τμήμα δεδομένων στη μνήμη. 3

ΠΑΡΑΔΕΙΓΜΑ 2α Παράδειγμα προγράμματος που εμφανίζει το μήνυμα Hello World στην οθόνη (με χρήση του Command prompt window ή Console)..386.model flat, stdcall option casemap :none ; include files include \masm32\include\windows.inc ; ορισμοί και δηλώσεις για τις Win32 API δομές include \masm32\include\masm32.inc ; διαδικασίες του MASM32 assembler ;Windows API include files include \masm32\include\kernel32.inc ; API συναρτήσεις διαχείρισης μνήμης και διεργασιών ; libraries includelib \masm32\lib\masm32.lib ; masm32 static library, διότι κάνουμε χρήση της StdOut ; import libraries for Windows API functions includelib \masm32\lib\kernel32.lib ; διότι κάνουμε χρήση της ExitProcess.data minima db "Hello World!", 0 ; string που τερματίζει με NUL (0 hexadecimal ASCII).code start: invoke StdOut, addr minima ; εμφάνιση του μηνύματος στην έξοδο (console) invoke ExitProcess, 0 ;κλήση της Win32 API συνάρτησης ExitProcess για έξοδο στα Windows ; ή push 0 call ExitProcess ; ή exit (MASM μακροεντολή), θα πρέπει να συμπεριληφθεί και το αρχείο macros.asm end start Επεξηγήσεις OPTION CASEMAP:NONE Με αυτή την επιλογή οι ετικέτες είναι case sensitive. Έτσι για παράδειγμα το ExitProcess και exitprocess είναι διαφορετικά. Include... Ενημερώνει τον assembler να ανοίξει το αρχείο το όνομα του οποίου ακολουθεί και να επεξεργαστεί τα περιεχόμενά του. Το αρχείο windows.inc συμπεριλαμβάνεται πάντα καθώς περιέχει ορισμούς και δηλώσεις για τις Win32 API σταθερές και δομές. Το αρχείο masm32.inc περιέχει διαδικασίες του MASM32 assembler (π.χ. η StdOut). Το αρχείο kernel32.inc περιέχει API συναρτήσεις διαχείρισης μνήμης και διεργασιών (π.χ. η ExitProcess). 4

IncludeLib... Με την ντιρεκτίβα αυτή ενημερώνουμε τον assembler ποιες βιβλιοθήκες (include libraries) χρησιμοποιούμε στην εφαρμογή μας (στην περίπτωσή μας τη masm32.lib) για να τις συμπεριλάβει. Σε αυτό το σημείο ο assembler τοποθετεί μια εντολή διασύνδεσης (linker command) στο objective αρχείο έτσι ώστε ο linker να γνωρίζει με ποιες βιβλιοθήκες η εφαρμογή μας χρειάζεται να συνδεθεί. Η db (define byte) προσδιορίζει ότι η παράμετρος minima δεσμεύει ένα αριθμό από bytes για το αλφαριθμητικό με περιεχόμενο "Hello World!" (ακολουθούμενο από τον ascii χαρακτήρα NUL, κατά τα πρότυπα του ASCII/ANSI αλφαριθμητικού). Η invoke καλεί μια συνάρτηση και τυχόν παραμέτρους της. Στην περίπτωσή μας καλεί την StdOut (στη masm32.lib) με τις παραμέτρους της. Η επιλογή addr minima δίνει τη διεύθυνση της παραμέτρου minima. Η επιλογή αυτή μπορεί να διαχειριστεί τοπικές μεταβλητές (δεσμευμένες στην στοίβα των οποίων η διεύθυνση γίνεται γνωστή κατά την εκτέλεση) και όχι forward references (δηλ. εάν η παράμετρος δηλώνεται παρακάτω στον κώδικα τότε δεν θα μπορεί να τη διαχειριστεί). Η επιλογή ADDR μπορεί να χρησιμοποιηθεί μόνο σε συνδυασμό με την INVOKE. Η επιλογή offset επιστρέφει την απόσταση της διεύθυνσης μιας παραμέτρου (συνήθως μεταβλητή) σε σχέση με την αρχή του τμήματος ή ομάδας (segment/group) που την περιέχει. Η επιλογή offset μπορεί να διαχειριστεί forward references όμως δεν μπορεί να διαχειριστεί τοπικές μεταβλητές καθώς η offset ερμηνεύεται κατά τη συμβολομετάφραση (compile time). Δηλαδή η offset δουλεύει μόνο με διευθύνσεις που είναι γνωστές κατά τη συμβολομετάφραση. Έτσι δεν μπορούμε να την χρησιμοποιήσουμε για να πάρουμε τη διεύθυνση μιας παραμέτρου της στοίβας. Όσον αφορά τις σφαιρικές μεταβλητές (global variables) με την addr ο assembler τοποθετεί τις διευθύνσεις τους στο object αρχείο όπως ακριβώς συμπεριφέρεται και με την offset. Η συνάρτηση StdOut είναι μια συνάρτηση που είναι διαθέσιμη μόνο στον MASM32 (αποτελεί μια μακροεντολή η οποία καλεί μια άλλη διαδικασία για να εξάγει στην έξοδο κείμενο). Ο MASM32 assembler έχει ένα πλήθος μακροεντολών που διευκολύνουν τον προγραμματισμό σε assembly και τον κάνουν πιο φιλικό όπως συμβαίνει και με τις γλώσσες υψηλού επιπέδου. Π.χ. μερικές άλλες μακροεντολές είναι:.if.else.endif.repeat until.while....break.endw. for. Endm Η ExitProcess προκαλεί την έξοδο και επιστροφή στα Windows με το 0 ως τιμή επιστροφής. 5

Μετάφραση, διασύνδεση και εκτέλεση από τη γραμμή εντολών Μετάφραση Στη γραμμή εντολών (command line) πληκτρολογούμε: masm32\bin\ml /c /coff hello.asm Η παράμετρος /c προσδιορίζει ότι ο MASM θα κάνει μόνο συμβολομετάφραση. Η παράμετρος /coff προσδιορίζει ότι ο MASM θα δημιουργήσει ένα αρχείο.obj file σε μορφή COFF (Common Object File Format). Έτσι εφόσον δεν υπάρχουν λάθη θα δημιουργηθεί το object αρχείο hello.obj. Διασύνδεση Στη συνέχεια θα πρέπει να γίνει η διασύνδεσή του καλώντας τον linker: masm32\bin\link /SUBSYSTEM:CONSOLE hello.obj Η παράμετρος /SUBSYSTEM:CONSOLE ενημερώνει τον linker τι είδους εκτελέσιμο είναι η εφαρμογή μας (CONSOLE/WINDOWS). Εκτέλεση Τώρα δημιουργήθηκε το εκτελέσιμο hello.exe το οποίο εκτελούμε πληκτρολογώντας στη γραμμή εντολών το όνομά του: hello.exe 6

M ASM32 Quick Editor Η σύνταξη του προγράμματος μπορεί να γίνει και στο περιβάλλον του MASM32 χρησιμοποιώντας τον Quick Editor (\masm32\qeditor.exe) και η εκτέλεση μέσα από το μενού Project-> Console Build All, Project-> Run Program. Το μενού Tools περιλαμβάνει δυνατότητες ανάλυσης της μετάφρασης και εκτέλεσης (Dis-assemble EXE file) καθώς και debugging με το λογισμικό VKDEBUG. 7

W inasm Παρομοίως η σύνταξη και η εκτέλεση του παραπάνω παραδείγματος φυσικά μπορεί να γίνει και στο περιβάλλον της εφαρμογής WinAsm. Δημιουργία του έργου: File -> New Project -> Empty Project -> Console Application hello.asm ; όνομα του assembly προγράμματος hello.wap ; όνομα του assembly project Στο παραπάνω παράδειγμα η εκτέλεση του προγράμματος θα μπορούσε να τερματιστεί εφόσον πατηθεί κάποιο πλήκτρο, με χρήση της μακροεντολής inkey (θα πρέπει να συμπεριληφθεί και το αρχείο macros.asm). Η μακροεντολή αυτή χρησιμοποιεί επίσης την μακροεντολή print για την εμφάνιση του μηνύματος (εφόσον υπάρχει), και τη μακροεντολή wait_key για να διαβάσει το χαρακτήρα (χρησιμοποιεί συναρτήσεις της Microsoft Visual C Run-Time Library msvcrt.lib στην υλοποίησή της οπότε θα πρέπει να συμπεριληφθεί), τον οποίο και τοποθετεί στον καταχωρητή EAX. ΠΑΡΑΔΕΙΓΜΑ 2β (Console Application) Παράδειγμα προγράμματος που εμφανίζει το μήνυμα Hello World στην οθόνη (με χρήση της Console) (τερματίζει την εμφάνιση όταν πατηθεί ένα πλήκτρο). File -> New Project -> Empty Project -> Console Application.386 8

.model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\msvcrt.inc include \masm32\macros\macros.asm includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\msvcrt.lib ; the macros library ; the Microsoft Visual C Run-Time Library.data minima db "Hello World!", 13,10,0 ; Carriage Return και Line Feed.code start: invoke StdOut, addr minima inkey ;ή inkey "Hit any Key";διαβάζει το χαρακτήρα που δόθηκε και τοποθετεί την ASCII ; αναπαράσταση (σε δεκαεξαδική μορφή) του χαρακτήρα στον EAX ; η γραμμή της εντολής inkey :Hit any key ισοδυναμεί με τις παρακάτω εντολές: ; print "Hit any Key" ; call wait_key ;μόλις πατηθεί πλήκτρο τοποθετεί την ASCII αναπαράσταση του χαρακτήρα (σε δεκαεξαδική μορφή) στον EAX ; print chr$(13,10) ; ακόμα μπορεί να χρησιμοποιηθεί και η getkey invoke ExitProcess, 0 end start Μετάφραση, διασύνδεση και εκτέλεση: Make-> Assemble, Make-> Link, Make-> Execute Στην περίπτωση αυτή του κώδικα το παράθυρο εκτέλεσης (console) παραμένει ανοιχτό (δηλ. συνεχίζει να τρέχει το thread) και θα κλείσει με το πάτημα οποιουδήποτε πλήκτρου. Παρακολούθηση και ανάλυση της εκτέλεσης Μπορούμε να προχωρήσουμε σε ανάλυση της εκτέλεσης του έργου χρησιμοποιώντας ένα external debugger όπως ο OllyDbg (32-bit assembler level analysing debugger for Microsoft Windows) από το μενού Make-> Debug. 9

Επιλέγοντας DEBUG-> Step into (αλλά και Step over όποτε κρίνουμε αναγκαίο) μπορούμε να προβούμε σε ανάλυση της εκτέλεσης. Το παράθυρο disassembly που δείχνει το πρόγραμμά μας σε assembly με τις πρόσθετες εντολές όπως προκύπτουν από τη μετάφραση. 10

Το παράθυρο των καταχωρητών. Χαρακτηριστικό είναι ότι ο δείκτης των εντολών EIP (instruction pointer) δείχνει κάθε φορά τη διεύθυνση της επόμενης εντολής στη μνήμη (π.χ. 00401000h) από όπου θα τη φέρει προς εκτέλεση. Στο παράθυρο μνήμης στη διεύθυνση 00403000h περιέχονται τα δεδομένα μας (κάθε byte σε δεκαεξαδική μορφή που αντιστοιχούν στους ASCII χαρακτήρες στα δεξιά του παραθύρου). Συγκεκριμένα το μήνυμα της παραμέτρου minima ( Hello World ) της εντολής εμφάνισης (invoke StdOut), και στη διεύθυνση 0040300Fh το μήνυμα ( Hit any key ) της εντολής inkey. 11

Εκτελώντας βηματικά την εφαρμογή μας (Step into) ξεκινά από την εκτέλεση της εντολής: invoke StdOut, addr minima η οποία σε disassembly έχει τη μορφή: 00401000 PUSH OFFSET 00403000 ; Arg1 = ASCII "Hello World!" 00401005 CALL 00401030 ; hello.00401030 Πρώτα τοποθετεί (PUSH) στη στοίβα τη διεύθυνση (00403000h) του δεδομένου μας (minima) στη μνήμη, στην κορυφή της στοίβας στη διεύθυνση 0019FF80h. Όπως βλέπουμε τώρα και στο παράθυρο των καταχωρητών ο δείκτης στοίβας (ESP) δείχνει σε αυτή τη διεύθυνση. ESP 0019FF80 PTR to ASCII "Hello World!" Στη συνέχεια (με Step into) μετακινείται (CALL) στη διαδικασία στη διεύθυνση 00401030h (μπορούμε και με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). Εκεί συνεχίζει την εκτέλεσή του όσον αφορά την StdOut και τη δέσμευση του διαχειριστή (StdHandle) του αρχείου της τυπικής εξόδου (standard output handle), 12

καταλήγοντας να γράψει (.WriteFile) στην τυπική έξοδο το μήνυμα "Hello World!" και επιστρέφει. Κατά τη βηματική εκτέλεση (step into) της διαδικασίας αυτής παρατηρούμε ότι ο μεταγλωττιστής τοποθετεί εντολές που αποθηκεύουν το δείκτη βάσης EBP και στη συνέχεια αντιγράφουν σε αυτόν το περιεχόμενο του δείκτη στοίβας ESP. Αυτό γίνεται διότι ο δείκτης βάσης EBP χρησιμοποιείται σαν σημείο αναφοράς για την εύρεση των παραμέτρων στη στοίβα. 00401030 PUSH EBP ; hello.00401030(guessed Arg1) 00401031 MOV EBP,ESP Στη συνέχεια (Step into) προχωράμε με την εκτέλεση της εντολής: inkey "Hit any Key" η οποία σε disassembly έχει τη μορφή: 0040100A PUSH OFFSET 0040300F ; Arg1 = ASCII "Hit any Key" 0040100F CALL 00401030 ; hello.00401030 00401014 CALL 00401070 ; hello.00401070 Πρώτα τοποθετεί (PUSH) στη στοίβα τη διεύθυνση (0040300Fh) του δεδομένου ("Hit any Key") στη μνήμη, στην κορυφή της στοίβας στη διεύθυνση 0019FF80h, όπως βλέπουμε τώρα και από τον δείκτη στοίβας (ESP) ο οποίος δείχνει σε αυτή τη διεύθυνση. ESP 0019FF80 PTR to ASCII "Hit any Key" Στη συνέχεια (Step into) μετακινείται (CALL) και πάλι στη διαδικασία στη διεύθυνση 00401030h (μπορούμε και πάλι με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). Εκεί συνεχίζει την εκτέλεσή του όσον αφορά την StdOut και τη δέσμευση του διαχειριστή (StdHandle) του αρχείου της τυπικής εξόδου (standard output handle), καταλήγοντας να γράψει (.WriteFile) στην τυπική έξοδο και το μήνυμα "Hit any Key", και επιστρέφει. 13

Στη συνέχεια (Step into) προχωρώντας με την εκτέλεση της εντολής (inkey) μετακινείται (CALL) στη διαδικασία στη διεύθυνση 00401070 (μπορούμε και πάλι με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). Εκεί συνεχίζει την εκτέλεση περιμένοντας από το χρήστη να πατήσει ένα πλήκτρο για να συνεχίσει. Όταν το πλήκτρο πατηθεί συνεχίζει με την επόμενη εντολή και ο χαρακτήρας του πλήκτρου τοποθετείται σε ASCII δεκαεξαδική μορφή στον καταχωρητή EAX. Στη συνέχεια (Step over) προχωρά με την τοποθέτηση των χαρακτήρων τέλους γραμμής Carriage return (13, Dh) και Line feed (10, Ah) στο τερματικό 00401019 PUSH OFFSET 0040301B ; Arg1 = ASCII "13,10" 0040101E CALL 00401030 ; hello.00401030 Τέλος, παρομοίως (Step over) προχωρά με την εκτέλεση της εντολής εξόδου και ολοκλήρωσης της εκτέλεσης του προγράμματος. invoke ExitProcess, 0 η οποία σε disassembly έχει τη μορφή: 00401023 PUSH 0 ; ExitCode = 0 00401025 CALL <JMP.&kernel32.ExitProcess>; KERNEL32.ExitProcess 0040102A JMP DWORD PTR DS:[<&kernel32.ExitProcess>] 14

MS Visual Studio Παρομοίως η δημιουργία της εφαρμογής μπορεί να γίνει και στο περιβάλλον του Visual Studio Professional 2015 της Microsoft (ή σε προγενέστερα versions, ή στο Visual Studio Community). Δημιουργία του έργου: File -> New Project -> Visual C++ ->Win32 -> Win32 console application (empty project) hello.asm ; όνομα του assembly προγράμματος hello.vcxproj ; όνομα του assembly project Μετάφραση, διασύνδεση και εκτέλεση: Η μετάφραση εκτελείται από το μενού: Build -> Compile και στη συνέχεια για τη δημιουργία του εκτελέσιμου του project επιλέγουμε: Build -> Solution και η εκτέλεσή του μπορεί να γίνει από το μενού: DEBUG -> Start Debugging (ή με τον Local Windows Debugger). Παρακολούθηση και ανάλυση της εκτέλεσης Μπορούμε να προχωρήσουμε σε ανάλυση της εκτέλεσης του έργου (debugging) μέσα από την επιλογή DEBUG ->Windows-> Disassembly. Μετά τη δημιουργία του εκτελέσιμου, επιλέγοντας DEBUG-> Step into (αλλά και Step over όπου κρίνουμε αναγκαίο) μπορούμε να προβούμε σε ανάλυση της εκτέλεσης χρησιμοποιώντας στη συνέχεια το παράθυρο disassembly με την επιλογή DEBUG-> Windows-> Disassembly και βοηθητικών παραθύρων καταχωρητών (DEBUG-> Windows->Registers) και μνήμης (DEBUG-> Windows->Memory) και ενδεχομένως εισάγοντας και breakpoints. 15

Το παράθυρο με τον πηγαίο κώδικα της εφαρμογής μας. Το παράθυρο disassembly που δείχνει το πρόγραμμά μας σε assembly με τις πρόσθετες εντολές όπως προκύπτουν από τη μετάφραση. 16

Το παράθυρο των καταχωρητών. Χαρακτηριστικό είναι ότι ο δείκτης των εντολών EIP (instruction pointer) δείχνει κάθε φορά τη διεύθυνση της επόμενης εντολής στη μνήμη (π.χ. 0089212C) από όπου θα τη φέρει προς εκτέλεση. Στο παράθυρο μνήμης τοποθετούμε τη διεύθυνση 00895000h στην οποία περιέχονται τα δεδομένα μας και συγκεκριμένα αρχικά το μήνυμα της παραμέτρου minima (Hello World) προς εμφάνιση. Αυτά μπορούμε στη συνέχεια να τα παρατηρήσουμε στο παράθυρο μνήμης όπου μας δείχνει από αριστερά τις διευθύνσεις μνήμης, στη μέση τα περιεχόμενά τους σε κάθε byte σε δεκαεξαδική μορφή που αντιστοιχούν στους ASCII χαρακτήρες στα δεξιά. 17

Εκτελώντας βηματικά την εφαρμογή μας (Step into) ξεκινά από την εκτέλεση της εντολής: invoke StdOut, addr minima η οποία σε disassembly έχει τη μορφή: 0089212C push 895000h 00892131 call _StdOut@4 (0891000h) Πρώτα τοποθετεί (PUSH) το δεδομένο μας (minima), από τη διεύθυνση (00895000h) όπου βρίσκεται στη μνήμη, στη στοίβα στη διεύθυνση 0034FCF0, όπως βλέπουμε τώρα και από τον δείκτη στοίβας (ESP) ο οποίος δείχνει σε αυτή τη διεύθυνση. ESP = 0034FCF0 ; εμπεριέχει το δεδομένο "Hello World!" Στη συνέχεια (Step into) μετακινείται (call) στη διαδικασία στη διεύθυνση 0891000h (μπορούμε και με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). Εκεί συνεχίζει την εκτέλεσή του όσον αφορά την StdOut και τη δέσμευση του διαχειριστή (StdHandle) του αρχείου της τυπικής εξόδου (standard output handle), καταλήγοντας να γράψει (.WriteFile) στην τυπική έξοδο το μήνυμα "Hello World!", και επιστρέφει. Κατά τη βηματική εκτέλεση (step into) της διαδικασία αυτής παρατηρούμε ότι ο μεταγλωττιστής τοποθετεί εντολές που αποθηκεύουν το δείκτη βάσης EBP και στη συνέχεια αντιγράφουν σε αυτόν το περιεχόμενο του δείκτη στοίβας ESP. Αυτό γίνεται διότι ο δείκτης βάσης EBP χρησιμοποιείται σαν σημείο αναφοράς για την εύρεση των παραμέτρων στη στοίβα. _StdOut@4: 00891000 push ebp 00891001 mov ebp,esp Στη συνέχεια (Step into) προχωράμε με την εκτέλεση της εντολής: inkey "Hit any Key" η οποία σε disassembly έχει τη μορφή: 00892136 push 89500Fh 0089213B call _StdOut@4 (0891000h) 18

Πρώτα τοποθετεί (PUSH) το δεδομένο ("Hit any Key"), από τη διεύθυνση (0089500Fh) όπου βρίσκεται στη μνήμη, στη στοίβα στη διεύθυνση 0019FF80h, όπως βλέπουμε τώρα και από τον δείκτη στοίβας (ESP) ο οποίος δείχνει σε αυτή τη διεύθυνση. ESP = 0034FCF0 ; εμπεριέχει το δεδομένο "Hit any Key" Στη συνέχεια (Step into) μετακινείται (call) και πάλι στη διαδικασία στη διεύθυνση 0891000h (μπορούμε και πάλι με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). Εκεί συνεχίζει την εκτέλεσή του όσον αφορά την StdOut και τη δέσμευση του διαχειριστή (StdHandle) του αρχείου της τυπικής εξόδου (standard output handle), καταλήγοντας να γράψει (.WriteFile) στην τυπική έξοδο και το μήνυμα "Hit any Key", και επιστρέφει. Στη συνέχεια (Step into) προχωρώντας με την εκτέλεση της εντολής (inkey) μετακινείται (call) στη διαδικασία στη διεύθυνση 0891040h (μπορούμε και πάλι με Step over απλώς να συνεχίσουμε με την ολοκλήρωση της εκτέλεσή της). 00892140 call _wait_key@0 (0891040h) 00892145 push 89501Bh Εκεί συνεχίζει την εκτέλεση περιμένοντας από το χρήστη να πατήσει ένα πλήκτρο για να συνεχίσει. Όταν το πλήκτρο πατηθεί συνεχίζει με την επόμενη εντολή και ο χαρακτήρας του πλήκτρου τοποθετείται σε ASCII δεκαεξαδική αναπαράσταση στον καταχωρητή EAX. Στη συνέχεια (Step over) προχωρά με την τοποθέτηση των χαρακτήρων τέλους γραμμής Carriage return (13, Dh) και Line feed (10, Ah) στο τερματικό. 00892145 push 89501Bh 0089214A call _StdOut@4 (0891000h) Τέλος, παρομοίως (Step over) προχωρά με την εκτέλεση της εντολής εξόδου και την ολοκλήρωση της εκτέλεσης του προγράμματος. invoke ExitProcess, 0 η οποία σε disassembly έχει τη μορφή: 0089214F push 0 00892151 call _ExitProcess@4 (0892160h) 00892156 int 3 19

Εργαστήριο 1: Ασκήσεις 1. Να μελετηθεί (debug/disassembly) η εκτέλεση του παρακάτω προγράμματος και τα περιεχόμενα της μνήμης και των καταχωρητών και ειδικότερα του καταχωρητή EAX..386.model flat, stdcall.data p1 DWORD 5 ;decimal p2 DWORD 10 ;decimal.data? sum DWORD?.code start: mov eax, p1 add eax, p2 mov sum, eax ret end start 2. Να μελετηθεί (debug/disassembly) η εκτέλεση του παρακάτω προγράμματος και τα περιεχόμενα της μνήμης και των καταχωρητών και ειδικότερα του καταχωρητή EAX (θα χρειαστείτε και υπενθύμιση της αναπαράστασης αρνητικών twos complement representation). Σημείωση: όσον αφορά τα δεδομένα στη μνήμη οι x86 επεξεργαστές χρησιμοποιούν το πρότυπο αποθήκευσης little endian, στο οποίο το μικρότερης σημασίας (low-order) byte αποθηκεύεται στη διεύθυνση έναρξης της παραμέτρου..386.model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib.data onebyte BYTE 0ffh ; δεκαεξαδικά δεδομένα oneword WORD 1234h onesword SWORD -1234h onedword DWORD 12345678h.code start: mov eax,0 ; EAX =? mov al,onebyte ; EAX =? mov ax,oneword ; EAX =? mov ax,onesword ; EAX =? mov eax,onedword ; EAX =? 20

mov ax,0 ; EAX =? invoke ExitProcess,NULL end start 3. Να γραφεί πρόγραμμα το οποίο εμφανίζει το ονοματεπώνυμό σας και να μελετηθεί η εκτέλεσή του (δεδομένα στη μνήμη, περιεχόμενα καταχωρητών, στοίβας). 4. Να μελετηθεί (debug/disassembly) η εκτέλεση του παρακάτω προγράμματος και ειδικότερα το περιεχόμενο του καταχωρητή EAX (θα χρειαστείτε και υπενθύμιση της ASCII κωδικοποίησης χαρακτήρων)..386.model flat, stdcall option casemap :none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\msvcrt.inc include \masm32\macros\macros.asm includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\msvcrt.lib.data? char BYTE?.code start: call wait_key mov char,al print chr$(13,10) print addr char print chr$(13,10) print chr$(46h,49h,4eh,49h,53h,48h,0dh,0ah) inkey "press any key..." invoke ExitProcess, 0 end start 5. Να γραφεί πρόγραμμα το οποίο διαβάζει και εμφανίζει ένα χαρακτήρα (να μελετηθεί η εκτέλεσή του). 21