Záhady programovania
O svete medzi
nebom (zdrojákom) a zemou (procesorom)
spustiteľný
beh programu
kompilácia
Programovanie:
- príkazy
- premenné
- if-y, cykly
- metódy
- triedy a objekty
Disassembler:
- program, ktorý preloží strojový kód do assembleru (jazyk symbolických inštrukcií) = čísla zapísané nejako zrozumiteľnejšie pre ľudí
Debugger:
- program, ktorý umožňuje krokovať beh iného programu
Kompilátor
- prekladá zdrojový kód z jedného programovacieho jazyka do iného programovacieho jazyka
- zvyčajne: preklad z vyššieho programovacieho jazyka (Pascal, C, C++, ...) do strojového kódu
- moderné kompilátory optimalizujú vytvorený kód (to, čo ste napísali sa môže vykonať úplne inak, avšak s rovnakým výsledkom)
sledovať
činnosť
programu
pozmeniť
funkčnosť
programu
ukážka...
CPU okno bežiaceho programu v OllyDbg
Chladič, pod ktorým je procesor (CPU)
V akom jazyku sú
inštrukcie pre procesor?
procesor rozumie inštrukciám v strojovom kóde
- to sú tie čísla, ktoré sme videli v exe-čku
Procesor (CPU)
rýchla kalkulačka:
- Intel Core i7 Extreme Edition 3960X (Hex core): 177 miliárd inštrukcií za sekundu
registre na uloženie hodnôt
- superrýchla pamäť priamo na procesore
- 8+8 registrov pri x86/32 architektúre ("v PCčkách")
- 16+16 registrov pri ARM architektúre ("v mobiloch")
cache - rýchla pamäť na procesore, ktorá má eliminovať častý prístup do "pomalej" RAMky
Adresa inštrukcie
osem 32-bitových registrov
adresa vykonávanej inštrukcie
Inštrukcia v jazyku
assemblera
EDX := EAX
Zápis inštrukcie
v strojovom kóde
príznaky (flags) procesor
Zásobník (Stack)
pohľad z vonku:
- spustiteľný program = kopa čísel
- editor čísla zobrazil v hexadecimálnej sústave
- niektoré čísla sú (ASCII?) kódy znakov
- niektoré čísla sú asi nejaké inštrukcie pre počítač
Dátový segment
- exe-čko je rozdelené na kódový segment (inštrukcie) a dátový segment (konštanty a globálne premenné v programe)
- kódový segment je len na čítanie
Zásobník (Stack)
- zásobník slúži pri volaní podprogramov: procedúr a funkcií (=metód v OOP)
- všetky lokálne premenné sa vytvárajú v zásobníku
- pri každom volaní podprogramu (CALL) sa do zásobníka uloží obsah registrov vrátane návratovej adresy, t.j. adresy, kde má vykonávanie programu pokračovať po ukončení podprogramu (RET)
- útok stack-buffer overflow
Čo sa s tým
dá robiť?
reverzné
inžinierstvo
crackovanie
Ďalšie aspekty používania softvéru:
- vlastníctvo vs. licencia
- etický rozmer crackovania
- šírenie malware-u crack-mi
crackovanie
- odstránenie vlastností (funkcionality) programu, ktoré považuje crackujúca osoba za neželané
- zvyčajne odstránenie ochrany proti kopírovaniu
reverzné inžinierstvo
- objavovanie technologických princípov zariadení, systémov alebo programov
- bez súhlasu autora je zákonom dovolené len za účelom zabezpečenia kompatibility (DMCA [1998] , EU Computer Program Directive [2009])
Phoenix Technologies 80-tych rokoch vytvorila reverzným inžinierstvom
BIOS (8kB kódu) kompatibilný s IBM PC
Svet sa mení!
1947
2011
Ako sa zmenili
programy a programovanie?
procedurálne programovanie
logické programovanie
štruktúrované programovanie
funkcionálne programovanie
objektovo-orientované programovanie
Fortran (1956)
Lisp (1958)
Basic (1964)
Pascal (1970)
Smalltalk (1972)
C (1972)
C++ (1980)
Object Pascal (1986)
Perl (1987)
Java (1995)
C# (2001)
Vývoj reaguje na aktuálny svet!
jeho možnosti a potreby
dostupnosť rýchleho hardvéru
Dnes
paralelizácia
bezpečnosť
virtualizácia
rýchly vývoj aplikácii (RAD)
informačná spoločnosť
internet
rôzne platformy (x86, ARM)
vývoj je drahší než hardvér
globalizácia
CIL - ekvivalent
bajt kódu v Jave
CLR - ekvivalent
Java Virtual Machine
.NET Framework
Java je "iná"
Bajt kód (Byte-code)
- pozná OOP (objekty, triedy a referencie)
- pozná premenné
- inštrukcia na vytvorenie objektu
- podporuje viacvláknové programovanie
- zásobníkovo orientovaný (žiadne registre)
ukážka...
- kompiláciou zdrojového kódy v Jave nevzniká strojový kód ale tzv. bajt kód
- bajt kód nevykonáva procesor ale JVM (Java Virtual Machine)
- interpretovaný jazyk (+predkompilácia)
- platformová nezávislosť
Java Virtual Machine
- interpretuje bajt-kód a stará sa o načítavanie tried
- zabezpečuje správu pamäte (alokovanie a uvoľnenie objektov)
- garbage-collector
- optimalizuje vykonávanie (JIT kompilácia)
- viaceré implementácie (Sun/Oracle, Apache Harmony, MicroJvm, ... minimálne 50 ďalších)
Aká je efektívnosť
interpretovaných jazykov?
Akýkoľvek interpretovaný kód musí byť pomalší ako natívny strojový kód:
- interpreter (JVM, CLR) je medzičlánok medzi programom a procesorom
- garbage collector a jeho činnosť je vykonávaná procesorom na úkor behu programu
vs.
Mýty a legendy
- mnohé mýty a legendy o pomalosti a nepoužiteľnosti interpretovaných jazykov vychádzajú z minulosti, ale SVET SA MENÍ!
Rýchlosť
Pamäť
Rýchlosť dnes
- JIT kompilácia - kompilácia do strojového kódu s optimalizáciou pre aktuálny beh programu
- cachovanie kompilovaného kódu
- vykonávanie je priemerne zhruba rovnako rýchle až 2-krát pomalšie než natívny kód
- pomalý štart (štartuje sa interpreter - JVM/CLR) súbežné interpretovanie s predkomplikovaním ďalšieho kódu
Pamäť dnes
- nové algoritmy pre garbage colletion (Concurent Mark-Sweep, generačné GC) - uvoľnenie nepotrebných objektov
- využíva sa, že priemerne 98% vytvorených objektov "žije" krátko (vzniknú a zaniknú medzi cyklami GC)
- alokovanie pamäte (nového objektu) na halde priemerne: 60-100 inštrukcií pre C++ kód vs. 10 inštrukcií pre JVM od Sun/Oracle
- v porovnaní s C++ je garantovaná dobrá kompaktnosť alokovanej pamäte (objekty sa v pamäti presúvajú - referencia nie je adresa)
Za bezpečnú a rýchlu manažovanú pamäť s GC sa platí:
- správa pamäte potrebuje zvyčajne výrazne (násobne) viac pamäte, než by potreboval natívny kód
rýchlosť a efektivita natívneho kódu
vs.
výhody moderných (interpretovaných) jazykov
rôzne úlohy vyžadujú rôzne riešenia
zázračné riešenie na všetko nie je
Ďakujem za pozornosť.
Otázky?