2 hakerstwo helion rozdz podstawy programowania dl (2)

background image

Wydawnictwo Helion

ul. Chopina 6

44-100 Gliwice

tel. (32)230-98-63

e-mail: helion@helion.pl

PRZYK£ADOWY ROZDZIA£

PRZYK£ADOWY ROZDZIA£

IDZ DO

IDZ DO

ZAMÓW DRUKOWANY KATALOG

ZAMÓW DRUKOWANY KATALOG

KATALOG KSI¥¯EK

KATALOG KSI¥¯EK

TWÓJ KOSZYK

TWÓJ KOSZYK

CENNIK I INFORMACJE

CENNIK I INFORMACJE

ZAMÓW INFORMACJE

O NOWOŒCIACH

ZAMÓW INFORMACJE

O NOWOŒCIACH

ZAMÓW CENNIK

ZAMÓW CENNIK

CZYTELNIA

CZYTELNIA

FRAGMENTY KSI¥¯EK ONLINE

FRAGMENTY KSI¥¯EK ONLINE

SPIS TREŒCI

SPIS TREŒCI

DODAJ DO KOSZYKA

DODAJ DO KOSZYKA

KATALOG ONLINE

KATALOG ONLINE

Hack Wars. Tom 1.

Na tropie hakerów

Autor: John Chirillo

T³umaczenie: Pawe³ Koronkiewicz, Leonard Milcin

ISBN: 83-7197-599-6

Tytu³ orygina³u:

Format: B5, stron: 736

Zawiera CD-ROM

Hack Attacks Revealed: A Complete

Reference with Custom Security Hacking Toolkit

Ekspert w dziedzinie zabezpieczeñ, John Chirillo, zachêca Czytelnika do poznania

mrocznego i tajemniczego œwiata hakerów. Czerpi¹c z bogatego doœwiadczenia we

wspó³pracy z firmami Fortune 1000, Chirillo przedstawia ró¿ne sposoby wykorzystania

przez hakerów luk w zabezpieczeniach sieci oraz metody rozpoznawania tego rodzaju

zagro¿eñ. Uzupe³nieniem jest szczegó³owy opis pakietu TigerBox, umo¿liwiaj¹cego

hakerom przeprowadzanie skutecznych w³amañ, a administratorowi sieci — zyskanie

pewnoœci, ¿e jest w³aœciwie chroniona.
W tej prowokacyjnej ksi¹¿ce znajdziemy:

"
"
"
"

Opis protoko³ów sieciowych i technologii komunikacyjnych z punktu widzenia

hakera
Pe³ny opis stosowanych metod w³amañ, wyjaœniaj¹cy, jak dzia³aj¹ hakerzy,

crackerzy, "phreaks" i cyberpunki
Narzêdzia do gromadzenia informacji i skanowania sieci, umo¿liwiaj¹ce wykrycie

i przeanalizowanie przypadków naruszenia bezpieczeñstwa systemu
Dok³adne instrukcje, jak pos³ugiwaæ siê pakietem typu TigerBox

i wykorzystywaæ go do wykrywania ataków.

ZNAJDZ KSI¥¯KÊ

ZNAJDZ KSI¥¯KÊ

LISTA BESTSELLERÓW

LISTA BESTSELLERÓW

INFORMACJE

O WYDAWNICTWIE HELION

INFORMACJE

O WYDAWNICTWIE HELION

background image

O Autorze .............................................................................................................9

Wstęp ................................................................................................................11

Rozdział 1. Protokoły komunikacyjne .................................................................15

Krótka historia Internetu ...................................................................................................15

IP — Internet Protocol ................................................................................................16
Datagramy IP — transportowanie, rozmiar i fragmentacja ........................................18
Adresy IP, klasy i maski podsieci ...............................................................................21
VLSM — krótka instrukcja tworzenia podsieci i odczytywania adresu IP ................22

ARP/RARP — rozpoznawanie adresu sprzętowego.........................................................31

ARP — transportowanie, budowa nagłówka pakietu .................................................31
RARP — transportowanie, dokonywanie transakcji ..................................................33
Usługa RARP..............................................................................................................33

TCP — Transmission Control Protocol ............................................................................33

Sekwencje oraz okna...................................................................................................34
Budowa nagłówka pakietu TCP..................................................................................35
Porty, końcówki, nawiązywanie połączenia ...............................................................37

UDP — User Datagram Protocol ......................................................................................37

Budowa i transportowanie datagramów UDP.............................................................38
Multiplexing, demultiplexing oraz porty UDP ...........................................................39

ICMP — Internet Control Message Protocol....................................................................39

Budowa i transportowanie pakietów ICMP ................................................................39
Komunikaty ICMP, wyszukiwanie maski podsieci ....................................................40
Przykłady datagramów ICMP.....................................................................................42

Rozdział 2. NetWare oraz NetBIOS .....................................................................43

NetWare — wprowadzenie ...............................................................................................43

IPX — Internetwork Packet Exchange .......................................................................44
SPX — Sequenced Packet Exchange .........................................................................48
Budowa i przykłady nagłówków SPX ........................................................................49
Zarządzanie połączeniami, przerywanie .....................................................................49
Algorytm Watchdog....................................................................................................50
Korekcja błędów, ochrona przed zatorami .................................................................51

NetBIOS — wprowadzenie...............................................................................................51

Konwencje nazywania, przykładowe nagłówki..........................................................51
Usługi NetBIOS ..........................................................................................................52

background image

4

Hack Wars. Na tropie hakerów

NetBEUI — wprowadzenie ..............................................................................................53

Związki z NetBIOS.....................................................................................................54
Okna i liczniki.............................................................................................................54

Rozdział 3. Porty standardowe oraz związane z nimi usługi..................................55

Przegląd portów.................................................................................................................55

Porty TCP oraz UDP...................................................................................................56
Luki w bezpieczeństwie związane z portami standardowymi ....................................57

Niezidentyfikowane usługi................................................................................................69

Rozdział 4. Techniki rozpoznania i skanowania ...................................................99

Rozpoznanie ......................................................................................................................99

Katalog Whois ..........................................................................................................100
PING .........................................................................................................................102
Serwisy wyszukiwawcze ..........................................................................................105
Social Engineering ....................................................................................................106

Skanowanie portów .........................................................................................................107

Techniki skanowania portów ....................................................................................107
Popularne skanery portów.........................................................................................108

Przykładowy skan ...........................................................................................................120

Rozdział 5. Niezbędnik hakera..........................................................................127

Pojęcia związane z siecią ................................................................................................127

Model warstwowy — Open Systems Interconnection Model ..................................127
Rodzaje okablowania — przepustowość oraz maksymalna długość........................129
Konwersje pomiędzy postaciami dwójkowymi, dziesiątkowymi

i szesnastkowymi liczb .......................................................................................129

Funkcje wydajnościowe protokołów ........................................................................140

Technologie sieciowe ......................................................................................................141

Adresowanie MAC i kody producentów ..................................................................141
Ethernet .....................................................................................................................141
Token Ring................................................................................................................148
Sieci Token Ring i mostkowanie trasy nadawcy ......................................................149
Sieci Token Ring i translacyjne mostkowanie trasy nadawcy..................................153
Sieci FDDI ................................................................................................................155

Protokoły wybierania tras................................................................................................157

Protokoły wektorowo-odległościowe i protokoły stanów przyłączy........................157
Protokół RIP..............................................................................................................159
Protokół IGRP...........................................................................................................160
Protokół RTMP sieci Appletalk................................................................................161
Protokół OSPF ..........................................................................................................161

Ważne polecenia .............................................................................................................162

append .......................................................................................................................162
assign.........................................................................................................................164
attrib ..........................................................................................................................164
backup .......................................................................................................................165
break..........................................................................................................................166
chcp ...........................................................................................................................166
chdir (cd) ...................................................................................................................167
chkdsk .......................................................................................................................168
cls ..............................................................................................................................168
command...................................................................................................................168
comp..........................................................................................................................169
copy...........................................................................................................................170
ctty.............................................................................................................................171

background image

Spis treści

5

date ............................................................................................................................171
del (erase)..................................................................................................................172
dir ..............................................................................................................................172
diskcomp ...................................................................................................................173
diskcopy ....................................................................................................................174
exe2bin ......................................................................................................................174
exit.............................................................................................................................175
fastopen .....................................................................................................................175
fc ...............................................................................................................................175
fdisk...........................................................................................................................177
find ............................................................................................................................177
format ........................................................................................................................178
graftabl ......................................................................................................................179
Graphics ....................................................................................................................179
join ............................................................................................................................180
keyb...........................................................................................................................181
label...........................................................................................................................182
mkdir (md) ................................................................................................................182
mode..........................................................................................................................183
more ..........................................................................................................................186
nlsfunc.......................................................................................................................186
path............................................................................................................................187
print ...........................................................................................................................187
prompt .......................................................................................................................188
recover.......................................................................................................................189
rename (ren) ..............................................................................................................190
replace .......................................................................................................................190
restore........................................................................................................................191
rmdir (rd)...................................................................................................................192
select .........................................................................................................................192
set ..............................................................................................................................193
share ..........................................................................................................................194
sort.............................................................................................................................194
subst ..........................................................................................................................195
sys .............................................................................................................................196
time ...........................................................................................................................196
tree.............................................................................................................................197
type............................................................................................................................197
ver .............................................................................................................................197
verify .........................................................................................................................198
vol .............................................................................................................................198
xcopy.........................................................................................................................198

Rozdział 6. Podstawy programowania dla hakerów ...........................................201

Język C ............................................................................................................................201

Wersje języka C ........................................................................................................202
Klasyfikowanie języka C ..........................................................................................203

Struktura języka C ...........................................................................................................203

Komentarze ...............................................................................................................205
Biblioteki...................................................................................................................205

Tworzenie programów ....................................................................................................205

Kompilacja ................................................................................................................205
Typy danych..............................................................................................................206
Operatory ..................................................................................................................210

background image

6

Hack Wars. Na tropie hakerów

Funkcje......................................................................................................................212
Polecenia preprocesora C..........................................................................................216
Instrukcje sterujące ...................................................................................................219
Wejście-wyjście ........................................................................................................223
Wskaźniki .................................................................................................................226
Struktury ...................................................................................................................229
Operacje na plikach...................................................................................................234
Ciągi ..........................................................................................................................244
Obsługa tekstu...........................................................................................................250
Data i godzina ...........................................................................................................253
Pliki nagłówkowe......................................................................................................259
Debugowanie programu............................................................................................259
Błędy wartości zmiennoprzecinkowych ...................................................................260
Obsługa błędów ........................................................................................................260
Konwersja typów zmiennych....................................................................................263
Prototypy...................................................................................................................265
Wskaźniki do funkcji ................................................................................................266
Sizeof........................................................................................................................267
Przerwania.................................................................................................................267
Funkcja signal() ........................................................................................................270
Dynamiczne alokowanie pamięci .............................................................................271
Funkcja atexit() .........................................................................................................273
Wydajność.................................................................................................................274
Przeszukiwanie katalogów........................................................................................275
Dostęp do pamięci rozbudowanej .............................................................................278
Dostęp do pamięci rozszerzonej ...............................................................................282
Tworzenie programów TSR......................................................................................290

Rozdział 7. Metody przeprowadzania ataków ....................................................319

Streszczenie przypadku ...................................................................................................319
„Tylne wejścia” (backdoors) ...........................................................................................320

Zakładanie „tylnego wejścia” ...................................................................................322

Typowe techniki „tylnego wejścia” ................................................................................323

Filtry pakietów ..........................................................................................................323
Filtry stanowe............................................................................................................328
Bramy proxy i poziomu aplikacji .............................................................................333

Przeciążanie (flooding) ...................................................................................................333
Zacieranie śladów (log bashing) .....................................................................................342

Zacieranie śladów aktywności online .......................................................................343
Unikanie rejestrowania wciśnięć klawiszy ...............................................................344

Bomby pocztowe, spam i podrabianie korespondencji ...................................................355
Łamanie haseł (password cracking) ................................................................................357

Deszyfrowanie i krakowanie.....................................................................................357

Zdalne przejęcie kontroli.................................................................................................362

Krok 1. Rozpoznanie ................................................................................................363
Krok 2. Przyjazna wiadomość email ........................................................................363
Krok 3. Kolejna ofiara ..............................................................................................364

Monitorowanie komunikacji (sniffing) ...........................................................................366
Podrabianie IP i DNS (spoofing) ....................................................................................374

Studium przypadku ...................................................................................................375

Konie trojańskie ..............................................................................................................382
Infekcje wirusowe ...........................................................................................................388
Wardialing .......................................................................................................................391
„Złamanie” strony WWW (Web page hack)...................................................................392

background image

Spis treści

7

Krok 1. Rozpoznanie ................................................................................................394
Krok 2. Uszczegółowienie danych ...........................................................................394
Krok 3. Rozpoczęcie właściwego ataku ...................................................................397
Krok 4. Poszerzenie wyłomu ....................................................................................397
Krok 5. „Hakowanie” strony.....................................................................................397

Rozdział 8. Bramy, routery oraz demony usług internetowych ............................401

Bramy i routery ...............................................................................................................401

3Com.........................................................................................................................402
Ascend/Lucent ..........................................................................................................409
Cabletron/Enterasys ..................................................................................................416
Cisco .........................................................................................................................423
Intel ...........................................................................................................................431
Nortel/Bay.................................................................................................................438

Demony serwerów internetowych...................................................................................442

Apache HTTP ...........................................................................................................443
Lotus Domino ...........................................................................................................445
Microsoft Internet Information Server......................................................................446
Netscape Enterprise Server .......................................................................................448
Novell Web Server....................................................................................................451
O’Reilly Web Site Professional ................................................................................454

Rozdział 9. Systemy operacyjne .......................................................................459

UNIX.........................................................................................................................460
AIX ...........................................................................................................................462
BSD...........................................................................................................................470
HP-UX ......................................................................................................................484
IRIX ..........................................................................................................................494
Linux .........................................................................................................................497
Macintosh..................................................................................................................522
Microsoft Windows ..................................................................................................527
Novell NetWare ........................................................................................................543
OS/2 ..........................................................................................................................552
SCO...........................................................................................................................566
Solaris .......................................................................................................................568

Rozdział 10. Serwery proxy i zapory firewall........................................................573

Bramy międzysieciowe ...................................................................................................573

BorderWare...............................................................................................................573
FireWall-1 .................................................................................................................577
Gauntlet.....................................................................................................................581
NetScreen ..................................................................................................................585
PIX ............................................................................................................................589
Raptor........................................................................................................................596
WinGate ....................................................................................................................599

Rozdział 11. TigerSuite — kompletny pakiet narzędzi do badania i ochrony sieci ...605

Terminologia ...................................................................................................................605
Wprowadzenie.................................................................................................................607

Instalacja ...................................................................................................................610

Moduły ............................................................................................................................613

Moduły grupy System Status ....................................................................................614

TigerBox Tookit..............................................................................................................619

TigerBox Tools .........................................................................................................619
TigerBox Scanners....................................................................................................624

background image

8

Hack Wars. Na tropie hakerów

TigerBox Penetrators ................................................................................................626
TigerBox Simulators .................................................................................................627

Przykładowy scenariusz włamania..................................................................................628

Krok 1. Badanie celu.................................................................................................629
Krok 2. Rozpoznanie ................................................................................................631
Krok 3. Socjotechnika...............................................................................................633
Krok 4. Atak..............................................................................................................635

Podsumowanie ................................................................................................................635

Dodatek A Klasy adresów IP oraz podział na podsieci.......................................637

Dodatek B Porty standardowe .........................................................................641

Dodatek C Pełna lista portów specjalnych .......................................................645

Dodatek D Porty usług niepożądanych .............................................................685

Dodatek E Zawartość płyty CD .......................................................................691

Skorowidz .........................................................................................................701

background image

Rozdział 6.

Język C

Dla każdego hakera, młodego czy starego, mniej lub bardziej doświadczonego, zna-
jomość języka C jest jednym z fundamentów wiedzy. Niemal wszystkie narzędzia
i programy, stosowane w trakcie analiz sieci i włamań, powstają właśnie w tym języ-
ku. Również w niniejszej książce większość przedstawianego kodu to właśnie kod
źródłowy w języku C. Programy te można modyfikować, dostosowywać do własnych
potrzeb i odpowiednio kompilować.

W pracy nad niniejszym rozdziałem wykorzystano obszerne fragmenty pracy guru
programowania Matthew Proberta. Mają one pełnić funkcję wprowadzenia do pro-
gramowania w języku C i umożliwić stosowanie przedstawianych w książce (i załą-
czonych na CD-ROM-ie) listingów programów. Pełny kurs języka znajdziesz w nie-
jednej książce wydawnictwa Helion.

Język C wyróżniają następujące cechy, które omawiamy niżej.

J

J

J

J

Blokowe konstrukcje sterowania wykonywaniem programu (typowe dla
większości języków wysokiego poziomu).

J

J

J

J

Swobodne operowanie podstawowymi obiektami „maszynowymi” (takimi jak
bajty) i możliwość odwoływania się do nich przy użyciu dowolnej, wymaganej
w danej sytuacji, perspektywy obiektowej (typowe dla języków asemblerowych).

J

J

J

J

Możliwość wykonywania operacji zarówno wysokiego poziomu (na przykład
arytmetyka zmiennoprzecinkowa), jak i niskiego poziomu (zbliżonych
do instrukcji języka maszynowego), co umożliwia tworzenie kodu wysoce
zoptymalizowanego bez utraty jego przenośności.

background image

202

Hack Wars. Na tropie hakerów

Przedstawiony w niniejszym rozdziale opis języka C bazować będzie na funkcjach
oferowanych przez większość kompilatorów dla komputerów PC. Powinien dzięki
temu umożliwić rozpoczęcie tworzenia prostych programów osobom nieposiadają-
cym szerokiej wiedzy o języku (uwzględnimy między innymi funkcje zapisane w pa-
mięci ROM i funkcje DOS-u).

Przyjmujemy założenie, że masz, drogi Czytelniku, dostęp do kompilatora C i od-
powiedniej dokumentacji funkcji bibliotecznych. Programy przykładowe powstały
w Turbo C firmy Borland; większość elementów niestandardowych tego narzędzia
uwzględniono również w późniejszych edycjach Microsoft C.

Wersje języka C

W pierwotnej edycji języka C (jeszcze przed publikacją Kernighana i Ritchie’ego,
The C Programming Language, Prentice-Hall 1988 (polskie wydanie: Język ANSI C,
Wydawnictwa Naukowo-Techniczne 1994)) zintegrowane operatory przypisania (+=,
*= itd.) definiowane były odwrotnie (tj. =+, =* itd.). Znakomicie utrudniało to inter-
pretację wyrażeń takich jak:



co mogłoby znaczyć



lub



Ritchie szybko zauważył dwuznaczność takiego zapisu i zmodyfikował go do postaci
znanej dzisiaj (+=, *= itd.). Mimo to wciąż stosowanych jest wiele odmian będących
rodzajem wypośrodkowania między pierwotną wersją języka C Kernighana i Ritchie’ego
a językiem ANSI C. Różnice między nimi dotyczą przede wszystkim:

J

J

J

J

wprowadzenia prototypów funkcji i zmiany preambuły definicji funkcji,
aby dostosować ją do stylu prototypów,

J

J

J

J

wprowadzenia znaku wielokropka (...) do oznaczenia list argumentów o zmiennej
długości,

J

J

J

J

wprowadzenia słowa kluczowego



(dla funkcji, które nie zwracają wartości)

i typu



dla ogólnych zmiennych wskaźnikowych,

J

J

J

J

wprowadzenie w preprocesorze mechanizmów scalania ciągów, wklejania
elementu (token-pasting) i zamiany na ciąg (string-izing),

J

J

J

J

dodanie w preprocesorze translacji „trygrafów” (trigraph) — trójznakowych
sekwencji reprezentujących znaki specjalne,

J

J

J

J

dodanie w preprocesorze dyrektywy



i formalizacja pseudofunkcji

  

,

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

203

J

J

J

J

wprowadzenie ciągów i znaków wielobajtowych, zapewniających obsługę
języków narodowych,

J

J

J

J

wprowadzenie słowa kluczowego

  

(jako uzupełnienie słowa

  

,

stosowane w deklaracjach liczb całkowitych) i jednoargumentowego
operatora plus (



).

Klasyfikowanie języka C

Szerokie możliwości języka C, dopuszczenie bezpośredniego operowania na adresach
i danych w pamięci oraz strukturalne podejście do programowania sprawiają, że język
ten klasyfikuje się jako „język programowania średniego poziomu”. Znajduje to wyraz
w mniejszej liczbie gotowych rozwiązań niż w językach wysokiego poziomu, takich
jak BASIC, ale wyższym poziomie strukturalnym niż niskopoziomowy Assembler.

Słowa kluczowe

Pierwotna edycja języka C definiuje 27 słów kluczowych. Komitet ANSI dodał do
nich 5 nowych. Wynikiem są dwa standardy języka, choć norma ANSI przejęła więk-
szość elementów od Kerninghana i Ritchie’ego. Oto lista:







  





 

 



 

 

 



 

 

 

 

 

 



   

 



 

 



 

  



  



Warto zwrócić uwagę, że niektóre kompilatory C wprowadzają dodatkowe słowa klu-
czowe, specyficzne dla środowiska sprzętowego. Warto zapoznać się z nimi.

Struktura języka C

Język C wymaga programowania strukturalnego. Oznacza to, że na program składa
się pewna grupa nawzajem wywołujących się bloków kodu. Dostępne są różnorodne
polecenia służące do konstruowania pętli i sprawdzania warunków:

 

Blok programu w języku C ujmowany jest w nawiasy klamrowe (



). Może on być

kompletną procedurą, nazywaną funkcją lub częścią kodu funkcji. Przyjrzyjmy się
przykładowi:

background image

204

Hack Wars. Na tropie hakerów

 !

"

 #

 !#

$

Instrukcje wewnątrz nawiasów klamrowych wykonane zostaną tylko wtedy, gdy speł-
niony zostanie warunek



.

Jako kolejny przykład przedstawimy pełny blok kodu funkcji, zawierający wewnątrz
blok pętli:

 %&'()

"

 #



"

 *+,     !  !*#

*- *.#

$

!//0 !#

 #

$

Zwróćmy uwagę, że każdy wiersz instrukcji zakończony jest średnikiem, o ile nie jest
sygnałem początku bloku kodu (w takim przypadku kolejnym znakiem jest nawias
klamrowy). Język C rozpoznaje wielkość liter, ale nie bierze pod uwagę białych zna-
ków. Odstępy między poleceniami są pomijane, stąd konieczność użycia średnika,
aby oznaczyć koniec wiersza. Tego rodzaju podejście powoduje, że następujące pole-
cenia interpretowane są jako identyczne:

!#

!#

!#

Ogólna postać programu w języku C jest następująca:

J

J

J

J

instrukcje preprocesora kompilacji,

J

J

J

J

globalne deklaracje danych.

J

J

J

J

deklaracje i definicje funkcji (włączając w to zawartość programu):

   

"

  

$

    

"

  

$

  1 

"

  

$

2

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

205

    

"

  

$

Komentarze

Podobnie jak większość języków, C pozwala umieszczać w kodzie programu komen-
tarze. Ich ogranicznikami są symbole



i



:

34' 5   56 743

(Równie często korzysta się z komentarzy jednoliniowych, otrzymywanych poprzez
sekwencję //, np.:

33'  85   92:2

Biblioteki

Programy w języku C kompiluje się i łączy z funkcjami bibliotecznymi, dostarcza-
nymi wraz z kompilatorem. Na biblioteki składają się funkcje standardowe, których
działanie zdefiniowane zostało w normie ANSI. Ich powiązanie z konkretnym kom-
pilatorem zapewnia dostosowanie do platformy sprzętowej. Wynika stąd, że standardowa
funkcja biblioteczna

 

działa tak samo w systemach DEC VAX i IBM PC,

choć różni się jej, zapisany w bibliotece, kod maszynowy. Programista C nie musi za-
głębiać się w zawartość bibliotek, wymagana jest jedynie umiejętność ich stosowania
i znajomość działania funkcji, które pozostają niezmienne na każdym komputerze.

Tworzenie programów

Kompilacja

Zanim zajmiemy się funkcjami, poleceniami, sekwencjami i innymi zaawansowanymi
zagadnieniami, przyjrzyjmy się praktycznemu przykładowi, w którym doprowadzimy
do skompilowania kodu. Kompilowanie programów C jest stosunkowo prostą czyn-
nością, jednak różni się zależnie od stosowanego kompilatora. Kompilatory wyposażone
w menu umożliwią skompilowanie, skonsolidowanie i uruchomienie programu jed-
nym wciśnięciem klawisza. Podchodząc jednak do zagadnienia możliwie uniwersal-
nie i tradycyjnie, przeprowadzimy poniżej całą procedurę w oparciu o wiersz poleceń.

W dowolnym edytorze wprowadzamy poniższy fragment kodu i zapisujemy plik jako
przyklad.c:

34

;      

43

background image

206

Hack Wars. Na tropie hakerów

<   20

  

"

 *= >+*#

$

Kolejnym krokiem jest skompilowanie kodu do postaci pliku programu — dopiero
wtedy można będzie go uruchomić (czy też wykonać). W wierszu poleceń w tym sa-
mym katalogu, w którym zapisaliśmy plik przyklad.c, wprowadzamy następujące po-
lecenie kompilacji:

 2

Nie wolno zapominać, że składnia polecenia kompilacji zależy od kompilatora. Nasz
przykład opiera się na standardzie języka C. Współcześnie jednak popularne jest sto-
sowanie składni wywodzącej się z kompilatora GNU C:

 2

Po wykonaniu takiego polecenia nasz kod jest już skompilowany i ma postać pliku
programu, który możemy uruchomić. Wynik jego działania łatwo wydedukować
z prostego kodu:

= >

9    

To wszystko! Kompilowanie małych programów w C nie jest trudne, należy jedynie
mieć świadomość szkodliwych niekiedy efektów ich działania. Programy przedsta-
wiane na stronach tej książki i załączone na CD-ROM-ie są oczywiście znacznie bar-
dziej skomplikowane, jednak zasady pozostają te same.

Typy danych

W języku C wyróżnia się cztery podstawowe typy danych: znakowy, całkowity,
zmiennoprzecinkowy i nieokreślony. Odpowiadają im słowa kluczowe:



,



,

 

i



. Dalsze typy danych tworzy się na tej podstawie, dodając modyfikatory:

  

(ze znakiem),

  

(bez znaku),



(długa) i

 

(krótka). Modyfika-

tor

  

jest elementem domyślnym, co sprawia, że jego użycie może się okazać

konieczne jedynie w wypadku gdy zastosowano przełącznik kompilacji nakazujący
domyślne korzystanie ze zmiennych bez znaku. Rozmiar każdego typu danych zależy
od platformy sprzętowej, jednak norma ANSI wyznacza pewne zakresy minimalne,
zestawione w tabeli 6.1.

W praktyce tak określone konwencje oznaczają, że typ danych



nadaje się najle-

piej do przechowywania zmiennych typu znacznikowego, takich jako kody stanu,
o ograniczonym zakresie wartości. Można również korzystać z typu



. Gdy jednak

zakres wartości nie przekracza 127 (lub 255 dla

  

), każda deklarowana

w ten sposób zmienna przyczynia się do niepotrzebnego obciążania pamięci.

Natomiast trudniejsze jest pytanie o to, z którego typu liczb rzeczywistych korzystać

 

,

 

czy

   

. Gdy wymagana jest dokładność, na przykład

w aplikacji stosowanej w księgowości, instynktownie powinniśmy użyć typu

  

,

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

207

Tabela 6.1.

Rozmiary i zakresy typów danych języka C

Typ

Rozmiar

Zakres



8

–128 do 127

 

8

0 do 255



16

–32 768 do 32 767

 

16

0 do 65 535

 

32

–2 147 483 648 do 2 147 483 647

  

32

0 do 4 294 967 295

 

32

precyzja 6-cyfrowa



64

precyzja 10-cyfrowa

  

80

precyzja 10-cyfrowa

wiąże się to jednak z wykorzystaniem przez każdą zmienną 10 bajtów. Obliczenia na
liczbach rzeczywistych nie są tak dokładne jak na liczbach całkowitych, warto więc
zawsze rozważyć użycie typu



i „obejście” problemu. Typ danych

 

nie jest

zbyt dobry, gdyż jego 6-cyfrowa precyzja nie zapewnia dokładności, na której zawsze
będziemy mogli polegać. Ogólną zasadą jest korzystanie z typów całkowitych tak
szeroko, jak tylko jest to możliwe, a gdy pojawia się konieczność użycia liczb rze-
czywistych, wprowadzenie typu

 

.

Deklarowanie zmiennej

Każda zmienna musi zostać zadeklarowana przed użyciem. Ogólną postacią deklara-
cji zmiennej jest:

 #

Aby więc przykładowo zadeklarować zmienną



typu



, przeznaczoną do przecho-

wywania wartości z zakresu od –32 768 do 32 767, użyjemy instrukcji:

 #

Ciągi znakowe deklarować można jako tabele znaków:

 ?   @#

Deklaracja ciągu o nazwie

 !"#

i długości 30 znaków, wyglądać będzie następująco:

 ?A!@#

Tablice danych innych typów mogą mieć więcej niż jeden wymiar. Oto deklaracja
dwuwymiarowej tablicy liczb całkowitych:

 ? !@? !@#

Elementy tablicy wywołujemy jako:

?!@?!@

?!@? @

?@?@

background image

208

Hack Wars. Na tropie hakerów

Wyróżnia się trzy poziomy dostępu do zmiennych: lokalny, na poziomie modułu
i globalny. Zmienna deklarowana wewnątrz bloku kodu będzie dostępna wyłącznie
dla instrukcji wewnątrz tego bloku. Zmienna deklarowana poza blokami kodu funkcji,
ale poprzedzona modyfikatorem

 

, będzie dostępna wyłącznie instrukcjom we-

wnątrz modułu kodu źródłowego. Zmienna deklarowana poza blokami kodu funkcji
i niepoprzedzona modyfikatorem będzie dostępna dla dowolnych instrukcji w dowol-
nym module programu. Na przykład:

   #

   #

  7   5 ;  5 B5

5    B 6  8    B

5 55C5    5 2D    CE8  6

;   56  92:2

"

 #

 #

$

 5

"

34F 5 G!43

!

"

  #

  !# 1!# HH

 *+= ,  *#

$

$

W powyższym przykładzie zmienna

 

jest dostępna dla wszystkich, kompilowa-

nych jako jeden program, modułów kodu źródłowego. Zmienna

jest osiągalna dla

wszystkich instrukcji w funkcjach



i

#$ 

, ale pozostaje niewidoczna

z poziomu innych modułów. Zmienne



i

%

są dostępne wyłącznie instrukcjom we-

wnątrz funkcji



. Z kolei zmienna

może być użyta wyłącznie przez instrukcje

wewnątrz bloku kodu po instrukcji



.

Jeżeli drugi blok kodu faktycznie ma skorzystać ze zmiennej

 

, wymagane będzie

umieszczenie w nim deklaracji zmiennej globalnej

 

:

    #

 5 

"

$

Język C nie stawia szczególnych przeszkód w przypisywaniu do siebie różnych typów
danych. Przykładowo możemy zadeklarować zmienną typu



, co spowoduje przy-

pisanie do przechowywania jej wartości jednego bajtu danych. Można podjąć próbę
przypisania do niej wartości spoza tego zakresu:

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

209

  

"

I!!!#

$

Zmienna



może przechowywać wartości z zakresu od –127 do 128, a więc wartość 5000

nie zostanie przypisana.



przyjmie jednak wartość 136.

Potrzeba przypisania różnych typów danych nie jest niczym oryginalnym. Aby po-
wstrzymać kompilator od generowania ostrzeżeń o takich operacjach, można skorzy-
stać z instrukcji konwersji (cast statement), informując kompilator o tym, że operacja
wykonywana jest świadomie. Instrukcję taką budujemy, umieszczając przed zmienną
lub wyrażeniem nazwę typu danych ujętą w nawiasy:

  

"

  #

 #

 !!31I#

 #

$

Operacja rzutowania



informuje kompilator o konieczności konwersji wartości

zmiennej zmiennoprzecinkowej



do liczby całkowitej, zanim ta zostanie przypisana

do zmiennej

%

.

Parametry formalne

Funkcja w języku C może przyjmować parametry przekazywane przez funkcję wy-
wołującą. Parametry te deklaruje się podobnie jak zmienne, podając ich nazwy we-
wnątrz towarzyszących nazwie funkcji nawiasów:

 JKLM  

"

34MGE   8  43

 4#

$

  

"

 #

  #

 #

I#

 N#

JKLM #

 *- - G6- +* #

$

background image

210

Hack Wars. Na tropie hakerów

Modyfikatory dostpu

Stosuje się dwa modyfikatory dostępu:



i

 

. Wartość zmiennej zadekla-

rowanej jako



nie może zostać zmieniona przez program, wartość zmiennej za-

deklarowanej jako

 

może zostać zmieniona przez program. Dodatkowo, za-

deklarowanie zmiennej jako

 

uniemożliwia kompilatorowi zaalokowanie jej

do rejestru i ogranicza przeprowadzaną na niej optymalizację.

Typy klas przechowywania zmiennych

Język C przewiduje cztery rodzaje przechowywania zmiennych:

 

,

 

,



i



. Typ

 

umożliwia modułowi kodu źródłowego dostęp do zmiennej

zadeklarowanej w innym module. Zmienne

 

dostępne są wyłącznie z poziomu

bloku kodu, w którym zostały zadeklarowane. Dodatkowo, jeżeli zmienna ma zasięg
lokalny, zachowuje swoją wartość między kolejnymi wywołaniami bloku kodu.

Zmienne rejestrowe (



) są, gdy tylko jest to możliwe, przechowywane w reje-

strach procesora. Zapewnia to najszybszy dostęp do ich wartości. Typ



stosuje się

wyłącznie w odniesieniu do zmiennych lokalnych. Nakazuje on zachowywanie war-
tości zmiennej lokalnej. Ponieważ jest to modyfikator domyślny, rzadko można spo-
tkać go w programach.

Operatory

Operatory to elementy kodu, które nakazują wykonanie obliczeń na zmiennych. W ję-
zyku C dostępne są następujące:

.

adres,

4

pośredniość,

H

plus jednoargumentowy,



minus jednoargumentowy,

O

dopełnienie bitowe,

>

negacja logiczna,

HH

jako prefiks — preinkrementacja, jako sufiks — postinkrementacja,

PP

jako prefiks — predekrementacja, jako sufiks — postdekrementacja,

H

dodawanie,



odejmowanie,

4

mnożenie,

3

dzielenie,

-

reszta z dzielenia (modulo),



przesunięcie w lewo,

00

przesunięcie w prawo,

.

bitowa operacja AND,

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

211

/

bitowa operacja OR,

Q

bitowa operacja XOR,

..

logiczna operacja AND,

//

logiczna operacja OR,



przypisanie,

4

przypisanie iloczynu,

3

przypisanie ilorazu,

-

przypisanie reszty (modułu),

H

przypisanie sumy,



przypisanie różnicy,



przypisanie przesunięcia w lewo,

00

przypisanie przesunięcia w prawo,

.

przypisanie wyniku bitowej operacji AND,

/

przypisanie wyniku bitowej operacji OR,

Q

przypisanie wyniku bitowej operacji XOR,



mniejsze niż,

0

większe niż,



mniejsze lub równe,

0

większe lub równe,



równe,

>

różne od,

2

bezpośredni selektor składnika,

0

pośredni selektor składnika,

RS

jeżeli

to prawda, to , w przeciwnym razie %&

?@

definiowanie tablic,



nawiasy oddzielają warunki i wyrażenia,

222

wielokropek wykorzystuje się w listach parametrów formalnych prototypów
funkcji do deklarowania zmiennej liczby parametrów lub parametrów
zmiennych typów.

Aby zilustrować sposób korzystania z podstawowych operatorów, przyjrzyjmy się
krótkiemu programowi:

  

"

 #

  #

 #

I#3495 BI43

 31#3495  B  5143

 41#3495 B   8 5143

34F  CC BE543

background image

212

Hack Wars. Na tropie hakerów

 *M5  *#



 *M5  *#

$

Typowym sposobem zwiększenia wartości zmiennej o 1 jest wiersz:

H

Język C dostarcza operatora inkrementacji, wystarczy więc napisać:

HH

W podobny sposób korzystamy z operatora dekrementacji, czyli zmniejszania war-
tości o 1:



Pozostałe operatory matematyczne wykorzystujemy podobnie. Warto jednak pamię-
tać o wprowadzanych przez język C możliwościach zapisu skróconego:

Zapis typowy

Zapis w j+zyku C

H HH
 
41

41

3

3

-I

-I

Funkcje

Funkcje to procedury kodu źródłowego tworzące program w języku C. Ich ogólną po-
stacią jest:

       

"

  

$

 

to typ zwracanej przez funkcję wartości:



,



,

 

,



itp.

Kod wewnątrz funkcji C pozostaje niewidoczny dla innych funkcji C. Nie można wy-
konywać skoków z jednej funkcji do wnętrza innej. Funkcje mogą jedynie wywoły-
wać inne funkcje. Nie wolno również definiować funkcji wewnątrz innych funkcji.
Definicja musi zostać umieszczona bezpośrednio na poziomie modułu kodu.

Parametry przekazywane są do funkcji jako wartości lub jako odwołania (wskaźniki).
Gdy parametr jest przekazywany jako wartość, funkcja otrzymuje kopię tej wartości.
Parametr przekazywany jako odwołanie jest jedynie wskaźnikiem do właściwego pa-
rametru. Pozwala to na zmianę jego wartości z poziomu wywołanej funkcji. W poniż-
szym przykładzie przekazujemy dwa parametry jako wartość do funkcji

#$ 

,

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

213

która następnie podejmuje próbę zmiany wartości przekazanych zmiennych. Drugim
krokiem jest przekazanie tych samych parametrów do funkcji

#$ 

, która rów-

nież podejmuje próbę zmiany wartości zmiennych:

<   20

  5  

"

34T 55 5  5  B43

41#

41#

 *+, BE 5- 2, BE 5- *#

 #

$

  5  4 4

"

34T 55 5  5   ;43

4441#

4441#

 *+, BE 5 - 2, BE 5 - *44#

 4#

$

  

"

 #

 #

 #

I#

N#

 5#

 5 ..#

 *+, BE-  BE-  BE- *#

$

#$ 

nie zmienia wartości otrzymanych parametrów. Modyfikowana jest za-

wartość wskazywanych parametrami adresów pamięci. O ile

#$ 

otrzymuje

z funkcji



wartości zmiennych



i

%

,

#$ 

otrzymuje z funkcji



ich

adresy w pamięci.

Przekazywanie tablicy do funkcji

Następujący program przekazuje do funkcji tablicę, a funkcja nadaje wartości ele-
mentom tablicy:

background image

214

Hack Wars. Na tropie hakerów

<   20

   5 ?@

"

 #

 !# !!#HH

?@#

$

  

"

   ? !!@#

 #

 5  #

 !# !!#HH

 *+, BE -  - *  ?@#

$

Parametr funkcji,

'(

, jest tablicą dowolnej długości. Deklaracja taka jest możli-

wa, ponieważ kompilator przekazuje jedynie adres początkowy tablicy, a nie wartości
poszczególnych jej elementów. Konsekwencją tego jest fakt, że funkcja może zmie-
niać wartości elementów tablicy. Aby uniemożliwić funkcji wprowadzanie modyfika-
cji, konieczne jest użycie typu



:

 5   ?@

"

$

Przy takiej deklaracji wiersz zmieniający zawartość tablicy wywołałby błąd kompila-
cji. Określenie parametru jako wartości stałej nie likwiduje jednak pośredniości jego
przekazania. Ilustruje to poniższy program:

<   20

   5   ?@

"

 4 #

 #

34' 5  8U      U43

34  5V43

345 V   43

 #

 !# !!#HH

"

4 #

 HH#

$

$

  

"

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

215

   ? !!@#

 #

 5  #

 !# !!#HH

 *+, BE -  - *  ?@#

$

Przekazywanie parametrów funkcji main()

Język C umożliwia przekazanie parametrów do uruchamianego programu z poziomu
systemu operacyjnego. Do ich odczytania wykorzystuje się zmienne



i

'(

:

<   20

   4?@

"

 #

 !##HH

 *+,   -  -*?@#

$

Parametr



przechowuje liczbę przekazanych programowi parametrów. W tablicy

'(

zapisane są ich adresy;

'(

jest zawsze nazwą uruchamianego programu.

Mechanizm ten ma szczególne znaczenie dla aplikacji wymagających dostępu do pli-
ków systemowych i danych. Rozważmy następującą sytuację: mała aplikacja obsługi
baz danych przechowuje swoje dane w pojedynczym pliku dane.dat; aplikacja ta musi
zostać tak zaprojektowana, aby można było uruchomić ją z dowolnego katalogu, czy
to na dysku twardym, czy dyskietce; musi również zapewnić uruchamianie za pośred-
nictwem ścieżki wyszukiwania DOS-u (

 

). Do poprawnej pracy aplikacji jest więc

wymagane, aby zawsze mogła odnaleźć plik dane.dat. Rozwiązanie takie zapewni
przyjęcie założenia, że plik danych jest zawsze w identycznym katalogu co sam pro-
gram. Poniższy fragment ilustruje wykorzystanie parametrów



i



w celu utwo-

rzenia ścieżki do pliku danych aplikacji:

<  20

( ? W!@#

   4?@

"

4( *XD'D2XD'*#

4#

 ( ?!@#

  ( *2*#      ;

å  92:2

KYZZ

"

349    5 27LJ43

background image

216

Hack Wars. Na tropie hakerów

  ( *2 *#

$

34,  5     B43

4 >U++U

#

 ( #

$

Przedstawiony program tworzy i zapisuje w zmiennej

 !" )#

ciąg postaci ścież-

ka\dane.dat. Jeżeli więc przykładową nazwą pliku uruchomieniowego będzie test.exe
i zostanie on umieszczony w katalogu \borlandc, zmiennej

 !" )#

przypisany

zostanie ciąg

*   *  + 

.

Wyj#cie z funkcji

Polecenie

 

powoduje natychmiastowe wyjście z funkcji. Jeżeli w deklaracji

funkcji podano typ zwracanej wartości, w poleceniu

 

należy użyć parametru te-

go samego typu.

Prototypy funkcji

Prototypy funkcji umożliwiają kompilatorowi C sprawdzanie poprawności przekazy-
wanych, do i z funkcji, danych. Ma to istotne znaczenie jako zabezpieczenie przed
przekroczeniem zakresu zaalokowanego dla zmiennej obszaru pamięci. Prototyp funkcji
umieszcza się na początku programu po poleceniach preprocesora (takich jak



)

i przed deklaracjami funkcji.

Polecenia preprocesora C

W języku C w treści kodu źródłowego można umieszczać polecenia dla kompilatora.
Określa się je terminem polecenia preprocesora. Norma ANSI definiuje następujące:

<

< 

< 

<

<

< 

< 

< 

<  

<

< 

<

Wszystkie polecenia preprocesora rozpoczyna znak krzyżyka (hash), czyli #. Każde
wymaga osobnego wiersza kodu (uzupełnionego ewentualnie komentarzem). Poniżej
przedstawiamy krótkie omówienie.

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

217

#define

Polecenie

 

tworzy identyfikator, który kompilator zastąpi podanym ciągiem

w danym module kodu źródłowego. Na przykład:

< TDZF&!

< '[Y&>TDZF&

Kompilator zastąpi wszystkie dalsze wystąpienia ciągu

,-./0

znakiem



, a wszystkie

dalsze wystąpienia ciągu

1230

— ciągiem

4

. Zastępowaniu nie podlegają identyfi-

katory wewnątrz znaków cudzysłowu, a więc wiersz:

 *'[Y&*#

nie zostanie zmieniony, ale

 *- *TDZF&#

podlega modyfikacji.

Polecenie

 

może również zostać użyte do definiowania makr, także makr z pa-

rametrami. Do zapewnienia poprawności zastąpień zaleca się ujmowanie parametrów
w nawiasy. W poniższym przykładzie deklarujemy makro o nazwie

 

, przyj-

mujące dwa parametry i zwracające ten z nich, którego wartość jest większa.

<   20

<  0 RS 

 

"

 *+- 5 6*IN#

$

#error

Polecenie

 

powoduje przerwanie procesu kompilacji i wyświetlenie podanego

tekstu, na przykład:

< F\LJ9]ZL,DK&XLJLXYZY:

powoduje zatrzymanie kompilacji i wyświetlenie:

F\LJ9]ZL,DK&XLJLXYZY:

#include

Polecenie



nakazuje kompilatorowi odczytanie i przetworzenie zawartości

dodatkowego pliku źródłowego. Nazwa pliku musi zostać ujęta w cudzysłów lub
wstawiona między znaki

5

, na przykład:

< * 12*

<   20

Jeżeli nazwa pliku została wpisana między znaki

5

, kompilator wyszukuje go w kata-

logu określonym w konfiguracji. Jest to zasada ogólna.

background image

218

Hack Wars. Na tropie hakerów

#if, #else, #elif, #endif

Grupa poleceń



dostarcza mechanizmu kompilacji warunkowej. Stosowana jest

dość typowa składnia:

<   

  

<

  

< 

Polecenie

 

to skrócona postać

  

:

< 

  

< 

  

< 

#ifdef, #ifndef

Rozwinięciem tych poleceń jest

  

(jeżeli zdefiniowano) i

  

(jeżeli nie zdefiniowano). Konstrukcje składniowe są następujące:

<  

  

<

  

< 

<  

  

<

  

< 

   

to identyfikator utworzony za pomocą deklaracji

 

.

#undef

Polecenie

 

usuwa definicję makra utworzonego przy użyciu wcześniejszej in-

strukcji

 

.

#line

Polecenie



modyfikuje zmienne globalne kompilatora

)).670))

i

)),6.0))

.

Ogólną postacią instrukcji jest:

< *  *

Wartość

 

zostaje umieszczona w zmiennej

)).670))

, a

8   8

— w zmien-

nej

)),6.0))

.

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

219

#pragma

Umożliwia korzystanie z poleceń specyficznych dla kompilatora.

Instrukcje steruj"ce

Jak w każdym języku programowania, również w C, znajdziemy instrukcje spraw-
dzające wartość wyrażenia. Wynikiem takiego sprawdzenia jest wartość

1230

lub

,-./0

.

Wartości

,-./0

odpowiada liczba



, a

1230

— liczba różna od zera.

Instrukcje wykonania warunkowego

Podstawową instrukcją wykonania warunkowego jest



o następującej składni:

 

  



  

gdzie

  

może być instrukcją pojedynczą lub ujętym w nawiasy klamrowe

blokiem kodu. Element



jest opcjonalny. Jeżeli wartością



jest

1230

,

wykonywana jest instrukcja podana bezpośrednio po nim. W pozostałych przypadkach
wykonywana jest instrukcja podana po słowie



(o ile ta część składni została użyta).

Alternatywą dla konstrukcji

+++ 

jest polecenie

9:

w postaci:

      

Jeżeli wartością wyrażenia jest

1230

, wykonywana jest pierwsza instrukcja. W pozo-

stałych przypadkach wykonywana jest instrukcja druga. Ilustruje to przykład:

<   20

  

"

 #

W#

 *+  -*-1!R* *S* *#

$

Język C oferuje również instrukcję

"

, ułatwiającą porównywanie wyrażenia

z pewną listą wartości. Wykonywane są instrukcje powiązane z pierwszą dopasowaną
wartością listy. Składnia polecenia

"

jest następująca:

  

"

 S  

 #

!S  

 #

2

2

background image

220

Hack Wars. Na tropie hakerów

 S  

 #

   S  

$

Użycie instrukcji

#

nie jest wymagane, ale jej pominięcie powoduje dalsze po-

równywanie wyrażenia z kolejnymi elementami listy wartości.

<   20

  

"

 #

W#

 

"

!S *+G6 *#

 #

 S *+G65 *#

 #

1S *+G6 *#

 #

AS *+G6 *#

 #

   S *+5 6  *#

$

$

Instrukcje

"

można zagnieżdżać.

Instrukcje iteracji

W języku C stosuje się trzy instrukcje pętli (iteracji):



,

"

i

;"

. Składnia

pętli



jest następująca:

    # #  

  

Jest ona szczególnie przydatna, gdy korzystamy z licznika, jak w poniższym przykła-
dzie wyświetlającym zestaw znaków ASCII:

<   20

  

"

 #

 A1# 1^#HH

 *- + -+ *#

$

Dopuszczalna jest również nieskończona pętla



:

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

221

 ##

"

  

$

Język C pozwala używać też pustych instrukcji. Poniższa pętla usuwa z ciągu począt-
kowe znaki odstępu:

 #4 UU# HH

#

Warto zwrócić uwagę na średniki odpowiadające inicjalizacji pętli i pustej instrukcji.

Pętla

"

ma konstrukcję nieco prostszą:

 

  

Instrukcja lub blok instrukcji (ujęty w nawiasy klamrowe) będą powtarzane do czasu,
gdy wyrażenie warunku przyjmie wartość

,-./0

. Jeżeli wyrażenie nie jest prawdziwe

jeszcze przed wejściem do pętli, instrukcje nie będą wykonywane w ogóle. Jest to
istotna różnica w stosunku do pętli

;"

, która zawsze zostaje wykonana co naj-

mniej raz. Jej składnia to:

"

  

$

 #

Instrukcje skoku

Instrukcja

 

pozwala powrócić z funkcji wykonywanej do funkcji, z której ta zo-

stała wywołana. W zależności od zadeklarowanego typu wartości zwracanej przez
funkcję instrukcja

 

może wymagać odpowiedniego parametru:

 JYZ'  

"

 4#

$

lub

   5

"

 *+= ,  *#

 #    5  92:2

$

Instrukcja

#

służy do wychodzenia z pętli lub instrukcji

"

. W przypadku pę-

tli powoduje to jej przedwczesne zakończenie, jak w poniższym przykładzie:

<   20

  

"

 #

background image

222

Hack Wars. Na tropie hakerów

 !#1IW#HH

"

 !!

 #

 *- + *#

$

$

Uzupełnieniem

#

jest polecenie



, wymuszające przeprowadzenie następ-

nej iteracji pętli. Kolejną wykonywaną instrukcją jest w tym przypadku instrukcja pę-
tli (dalsze instrukcje w iterowanym bloku są pomijane). Dostępna jest również funk-
cja przedwczesnego zakończenia wykonywania programu —



. Można za jej

pomocą przekazać wartość zwracaną do programu wywołującego:

   #

Continue

Słowo kluczowe



nakazuje skok do instrukcji kontrolnej pętli. W przypadku

pętli zagnieżdżonych jest to instrukcja pętli wewnętrznej (

"

,

+++" 

). To spo-

sób na łagodne zakończenie pętli jak w poniższym przykładzie, gdzie odczytujemy
zapisane w pliku ciągi:

<   20

  

"

T]Z&4#

4#

 ? !!@#

 * 2  ***#

KYZZ

"

  *K 8  E   2  *#

 !#

$



"

   !!#

KYZZ

34, 5B43

   #

 #

$

#

$

W przypadku pętli



instrukcja



powoduje najpierw wykonanie wyrażenia

inkrementacji, a dopiero po nim następuje sprawdzenie warunku zakończenia.

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

223

Wej#cie-wyj#cie

Pobieranie danych

Program w języku C może pobierać dane z konsoli (która jest standardowym urzą-
dzeniem wejściowym), pliku lub portu. Ogólnym poleceniem odczytu danych ze stan-
dardowego strumienia wejściowego



jest

 

. Skanuje ono po jednym znaku

kolejne pola wejściowe. Podlegają one formatowaniu zgodnie z pierwszym z przekaza-
nych funkcji

 

parametrów. Następnie pole zostaje zapisane pod adresem prze-

kazanym jako kolejny parametr wywołania funkcji. Przykładowy program odczytuje
pojedynczą liczbę całkowitą ze strumienia



:

  

"

 #

*- *.#

$

Warto zwrócić uwagę na operator użyty jako prefiks zmiennej



na liście parametrów

wywołania funkcji

 

. Funkcja ta zapisuje bowiem wartość pod określonym ad-

resem, nie posługując się mechanizmem przypisywania wartości zmiennej. Ciągiem
formatującym jest ciąg znakowy, który może zawierać trzy typy danych: znaki odstępu
(spacja, tabulator, przejście do nowego wiersza), znaki właściwe (wszystkie znaki ASCII
z wyjątkiem znaku %) i specyfikatory formatowania. Specyfikatory te mają następu-
jącą składnię:

-?4@? @?//Z@

Oto przykład:

<   20

  

"

 ?A!@#

 #

 *9 5 *#

*-A!- * .#

 *+-- * #

$

Zwróćmy uwagę na wiersz

 +5

— nakazuje on kompilatorowi prze-

twarzanie pliku nagłówkowego stdio.h, w którym zawarte są prototypy funkcji

 

i

 

. Po uruchomieniu tego prostego programu łatwo przekonamy się, że użycie

znaku odstępu przerwie wprowadzanie pierwszego pola danych.

Alternatywną funkcją pobierania danych jest



, odczytująca ciąg znaków ze stru-

mienia



do momentu napotkania znaku nowego wiersza. W ciągu docelowym znak

nowego wiersza zastąpiony zostaje znakiem

73..

. Charakterystyczna dla tej funkcji

jest możliwość odczytywania znaków odstępu. Oto nowa wersja powyższego programu
(korzystająca z



w miejsce

 

):

background image

224

Hack Wars. Na tropie hakerów

<   20

<   20

<  20

  

"

 ?^!@#

4#

 ?A!@#

 #

 *+9 5 *#

34L  C  43

  #

345 V        C 43

. ?   @#

34Y 5 _  6 5C5KYZZ43

4UU"

4!#

#

$

34Z  5   C56C 43

  UU#

34L  5 643

 #

34,  _C    43

4!#

34\  5C  543

   #

34,B  543

 *+K S-S- * #

$

Wyprowadzanie danych

Podstawową funkcją wyprowadzania danych jest

 

. Jest ona podobna do

 

z tą różnicą, że zapisuje dane do standardowego strumienia wyjściowego



.

Funkcja pobiera listę pól danych wyjściowych, odpowiednio stosuje specyfikatory
formatowania i wyprowadza wynik. Można stosować takie same przekształcenia for-
matujące jak w przypadku funkcji

 

, jak również dodatkowe znaczniki:

;

wyrównuje dane wyjściowe do lewej, uzupełniając je z prawej strony
znakami odstępu międzywyrazowego (spacji),



wymusza poprzedzanie liczb znakiem.

Nieco odmienna jest także postać specyfikatora szerokości. Jest on rozbudowany o ele-
ment określający precyzję:

2 

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

225

Aby więc wyświetlić liczbę zmiennoprzecinkową z dokładnością do trzech miejsc
dziesiętnych, piszemy:

 *-2A*#

Poniżej przedstawiamy listę specjalnych stałych znakowych, które mogą pojawić się
na liście parametrów funkcji

 

:

+

nowy wiersz (NL),

+

powrót karetki (CR),

+

tabulator,

+

znak cofania (backspace),

+

znak nowej strony,

+

tabulator pionowy,

++

ukośnik odwrotny (backslash),

+U

apostrof,

+*

cudzysłów,

+R

znak zapytania,

+

ciąg w notacji ósemkowej,

+

ciąg w notacji szesnastkowej.

Kolejny program ilustruje, w jaki sposób wyświetlić liczbę całkowitą w postaci dzie-
siętnej, szesnastkowej i ósemkowej. Liczba

<

po znaku procentów (

=

) w instrukcji

 

nakazuje kompilatorowi dopełnienie wyświetlanej liczby do szerokości co

najmniej czterech cyfr:

349    5  6 43

34     5G 543

<   20

  

"

 #



"

 *+9 5 6 !  _E*#

*- *.#

 *-!` -!`)-!` *#

$

>!#

$

Do funkcji pokrewnych

 

należy

 

, której prototyp ma postać:

 T]Z&44  ?  222@#

Jej zadaniem jest przesyłanie sformatowanych danych wyjściowych do określonego
strumienia plikowego.

background image

226

Hack Wars. Na tropie hakerów

Kolejną tego rodzaju funkcją jest

 

o prototypie:

 44  ?  222@#

Alternatywą dla

 

jest



, funkcja przesyłająca prosty ciąg do strumienia



. Przesyłany ciąg zostaje automatycznie uzupełniony znakiem nowego wiersza.

Jest to rozwiązanie szybsze od

 

, jednak jego możliwości są ograniczone.

Bezpo#rednia wymiana danych z konsol*

Do przesyłania i odczytu danych z konsoli (klawiatury i ekranu) można wykorzysty-
wać również bezpośrednie funkcje we-wy. Wyróżnia je litera „c” na początku — od-
powiednikiem

 

jest więc

 

, a odpowiednikiem



— funkcja



. Różnice między funkcjami bezpośredniej wymiany danych a funkcjami

standardowymi są następujące.

J

J

J

J

Nie są wykorzystywane strumienie predefiniowane, nie można więc przekierować
danych przesyłanych funkcjami komunikacji bezpośredniej.

J

J

J

J

Funkcji bezpośrednich nie można przenosić między różnymi systemami
operacyjnymi (m.in. nie można z nich korzystać w programach dla Windows).

J

J

J

J

Funkcje bezpośrednie są szybsze niż standardowe.

J

J

J

J

Nie zapewniają współpracy ze wszystkimi trybami wyświetlania (zwłaszcza
trybami graficznymi VESA).

Wska%niki

Wskaźnik to zmienna, która przechowuje adres elementu danych w pamięci. Deklara-
cja wskaźnika jest podobna do deklaracji zwykłej zmiennej, ale nazwa poprzedzana
jest znakiem gwiazdki (



), na przykład:

4#

Powyższy wiersz deklaruje zmienną



jako wskaźnik do zmiennej typu



.

Wykorzystanie wskaźników dostarcza szerokich możliwości, wymaga jednak szcze-
gólnej uwagi. Skutki przypisania błędnego adresu są najczęściej nieprzewidywalne.
Oto przykład prostego programu, w którym wykorzystywany jest wskaźnik:

<   20

  

"

 #

 4#

345 V     43

 !!#

.#

 *+M  5 BE-   -2*#

$

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

227

Wartości wskaźników można zwiększać i zmniejszać, dopuszczalne są również inne
operacje matematyczne. Typowym zastosowaniem wskaźników jest zapewnienie dy-
namicznego przydziału pamięci. W trakcie pracy programu często pojawia się potrze-
ba przejściowego (tymczasowego) zaalokowania bloku pamięci. Korzystamy wów-
czas z funkcji



:

 "  #  #

Funkcja



zwraca wskaźnik typu



, co oznacza, że może on wskazywać

dane dowolnego typu —



,



,

 

itd. W poniższym przykładzie alokujemy

pamięć dla tabeli 1000 liczb całkowitych.

<   20

<   20

  

"

 4#

 #

345 V     43

34'   6 !!! C43

34       5  43

34 5 G5  5   43

  !!!4  #

34F  5  ; 43

KYZZ

"

 *+K 8  E6  !!! 5   B

å  *#

 !#

$

349 5 B G 43

 !# !!!#HH

"

4#

HH#

$

349 BE   C     43

 !!!#

34,B  B  43

 !# !!!#HH"

 *+& -   5 BE- *4#

HH#

$

349  8    5  643

#

$

background image

228

Hack Wars. Na tropie hakerów

Wskaźniki wykorzystuje się również w odniesieniu do tablic znaków, czyli ciągów
(strings). Ponieważ wszystkie ciągi w programach C kończy bajt o wartości 0, korzy-
stając ze wskaźnika, możemy policzyć znaki w ciągu:

<   20

<  20

  

"

4#

  ? !!@#

    #

34]5 5CU  U43

   *' 5  *#

34Y  BE5 C   43

  #

34]5 5C ;  BE43

   !#

34M5  43

4

"

   HH#

HH#

$

34,B 43

 *+X      S- *   #

$

Wymaganą do zaadresowania 1 MB pamięci 20-bitową liczbę dzieli się na dwie warto-
ści: przesunięcie (offset) i segment (każdy segment to 64 kB). Do przechowywania nu-
merów segmentów pamięci komputer IBM PC wykorzystuje tzw. rejestry segmentowe.
Konsekwencją takiego rozwiązania są w języku C trzy dodatkowe słowa kluczowe:

J

J

J

J 

— wskaźniki „bliskie” mają rozmiar 16 bitów i umożliwiają dostęp

do danych bieżącego segmentu,

J

J

J

J 

— wskaźniki „dalekie” obejmują wartości określające przesunięcie

i segment, umożliwiając dostęp do dowolnego adresu w pamięci,

J

J

J

J 

— wskaźniki „ogromne” to odmiana wskaźników dalekich, zapewniająca

możliwość zwiększania i zmniejszania wartości w całym zakresie 1 MB
(kompilator generuje odpowiedni kod modyfikujący wartość przesunięcia).

Nie będzie zapewne zaskakujące stwierdzenie, że przetwarzanie programu korzystają-
cego ze wskaźników typu



będzie szybsze niż w przypadku programu, w którym

zastosowano wskaźniki



. Wskaźniki



są oczywiście największym obciążeniem.

Kompilatory C wyposażone są w makro zwracające adres odpowiadający podanym
wartościom numeru segmentu i przesunięcia:

  4J\(T9       #

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

229

Struktury

Język C oferuje technikę grupowania zmiennych pod jedną nazwą, dostarczając w ten
sposób wygodnego sposobu przechowywania powiązanych ze sobą informacji i struktu-
ralizowania ich. Składnia definicji struktury jest następująca:

   

"

     #

     $

2

2

2

$

 #

Używanie zmiennych strukturalnych jest niezbędne przy korzystaniu z plików, w któ-
rych występuje uporządkowanie oparte na rekordach danych. W poniższym przykła-
dzie operować będziemy na prostym pliku z listą adresów. Rozpoczniemy od deklara-
cji struktury

 

, złożonej z sześciu pól:

 !"#

,

 

,

 

,

"$ "!"

,

!

i

   

:

   

"

 ?A!@#

 ?A!@#

 ?A!@#

 5   ?A!@#

 ?W@#

   ? I@#

$

#

Odwołania do pól zmiennej strukturalnej mają postać:

   2  #

Nie ma ograniczenia liczby pól struktury, nie jest również wymagane, aby typy pól
były takie same lub podobne, na przyklad:

   

"

 ?A!@#

 #

4  #

$

#

Jest to poprawna deklaracja struktury obejmująca: pole tablicy znakowej, pole liczby
całkowitej i pole wskaźnika do zmiennej znakowej. Aby przekazać zmienną struktu-
ralną jako parametr, korzystamy z jej adresu — poprzedzamy nazwę zmiennej ope-
ratorem

>

. Oto przykładowy program wykorzystujący struktury w celu wykonania

prostych operacji na pliku listy adresów:

background image

230

Hack Wars. Na tropie hakerów

<   20

<   20

<  20

<  20

<  20

< +  20

34 (   43

<  (1I

   

"

 ?A!@#

 ?A!@#

 ?A!@#

 5   ?A!@#

 ?W@#

   ? I@#

$

#

  #

  #

349  543

  DXX([&7  #

  7ZF  #

  X]F9XD'D  #

  TD'DZ4#

  %&'XD'D  #

  J&KY  #

  L9&KXD'D  #

 F&D[7=  #

  7ZF

"

 #

 !# (#HH

 **#

$

  TD'DZ4  

"

 *+:  S-*  #

 !#

$

  L9&KXD'D

"

34F V 5 2a8 G243

34a8  G     _  243

  * 2  *L([X,[/L(D99&KXF(],[]'&#

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

231

  

"

  * 2  *L([X,[/L(7[&D'F(],[]'&#

  

TD'DZ*K 8  E  *#

$

$

  %&'XD'D

"

349    43

7ZF#

 *K *#

   2 #

 *+D *#

   2 #

 *+J *#

   2 #

 *+, 5G   *#

   2 5   #

 *+\   *#

   2 #

 *+K    *#

   2   #

$

  X]F9XD'D

"

34,B    43

  ?I@#

7ZF#

 *K -*  2 #

 *+D -*  2 #

 *+J -*  2 #

 *+, 5G   -*  2 5   #

 *+\   -*  2 #

 *+K    -++*  2   #

 *,B5&K'&[*#

   #

$

  DXX([&7

"

34X ;C      43

 #

  .    #

 

TD'DZ*M    8*#

$

 F&D[7=

"

background image

232

Hack Wars. Na tropie hakerów

  ? !!@#

 #

 *,  VG *#

   #

4  !

  #

34M  5 C  43

 !F&&\(F&'#



"

34M; 5   643

  .    #

0!

"

349 5  43

    2   >KYZZ

  #

    2   >KYZZ

  #

    2   >KYZZ

  #

    2 5     >KYZZ

  #

    2   >KYZZ

  #

    2     >KYZZ

  #

$

$

0!#

 !#

$

  J&KY

"

  5#

  ? !@#



"

7ZF#

 *++ + + ,  56*#

 *+++ + + X 5   *#

 *+++ + + 19  *#

 *+++ + + A,5B*#

 *+++++*#

   #

 5   #

  5

"

 S%&'XD'D#

349  ;C  5 V  _ 43

 !F&&\(&KX#

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

233

DXX([&7#

 #

1SF&D[7=

X]F9XD'D#



"

 *K]&MKDZ&M]LK&>*#

 *,B5&K'&[*#

   #

$

 #

AS #

$

$

 5>A#

$

  

"

7ZF#

L9&KXD'D#

J&KY#

$

Pola bitowe

Język C przewiduje możliwość korzystania w strukturach ze zmiennych o rozmiarze
mniejszym niż 8 bitów. Określa się je mianem pól bitowych, a ich rozmiar może być
dowolny, od 1 bitu wzwyż. Deklaracja pola bitowego wygląda następująco:

 S  #

Przykładem może być deklaracja kilku jednobitowych znaczników stanu:

   

"

  S #

   S #

  S #

   S #

$

#

#

Zmienna

! !#

będzie zajmować w pamięci tylko 4 bity, mimo że składa się z 4 pól,

z których każde dostępne jest jako osobne pole struktury.

Union

Kolejnym ułatwieniem języka C, pozwalającym zapewnić optymalne wykorzystanie
dostępnej pamięci, jest struktura



, czyli zbiór zmiennych, współużytkujących je-

den adres pamięci. Oznacza to, oczywiście, że w danym momencie dostępna jest tyl-
ko jedna ze zmiennych składowych. Deklaracja



ma następującą postać:

background image

234

Hack Wars. Na tropie hakerów

  

"

   #

   #

2

2

2

   #

$#

Wyliczenia

Wyliczenie (enumeracja) to przypisanie liście symboli rosnących wartości całkowi-
tych. Wyliczenie deklarujemy:

  " $    %#

Przykładem może być definicja listy kolorów:

 \LZL[b

"

7MD[Kb

K]&:]&F\]

M]&ZLKb

7M&[,LKb

:[DML,b

aDFKLFMD[b

7]&JKLFMD[b

aDFKLK]&:]&F\]

aDFKLM]&ZLKb

aDFKL7M&[,LKb

MLZ'b

:]DZb

$#

Operacje na plikach

W operacjach dostępu do plików język C posługuje się buforowanymi strumieniami
plikowymi. Niektóre z platform języka, jak UNIX i DOS, oferują również niebuforo-
wane uchwyty plików.

Strumienie buforowane

Dostęp do strumieni buforowanych realizowany jest za pośrednictwem wskaźnika do
zmiennej typu

,6.0

. Ten szczególny typ danych zdefiniowany został w nagłówku st-

dio.h. Aby więc zadeklarować wskaźnik do pliku, wprowadzamy:

<   20

T]Z&4 #

Aby otworzyć strumień, używamy funkcji

 

. Pobiera ona dwa parametry: na-

zwę otwieranego pliku oraz tryb dostępu. Oto lista trybów dostępu.

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

235

Tryb

Opis



otwórz tylko do odczytu (plik musi istnieć),



utwórz do zapisu; zastąp, jeżeli plik o podanej nazwie istnieje,



otwórz do dołączania danych (dopisywania na końcu pliku); utwórz nowy plik,
jeżeli plik o podanej nazwie nie istnieje,

H

otwórz istniejący plik do odczytu i zapisu (plik musi istnieć),

H

utwórz do odczytu i zapisu; zastąp, jeżeli istnieje,

H

otwórz do czytania i dołączania danych; utwórz nowy plik, jeżeli nie istnieje.

Aby określić tryb tekstowy lub binarny, do opisu trybu można dołączyć



lub

. W przy-

padku pominięcia tego znacznika strumień zostanie otwarty w trybie określanym
zmienną globalną

) 

. Odczyt i zapis danych do strumieni plikowych w trybie tek-

stowym wiąże się z konwersją — podczas zapisu znaki CR i LF zamieniane są na pary
CR LF, a przy odczycie pary CR LF ulegają zamianie na pojedynczy znak LF. Tego
rodzaju operacje nie są wykonywane w trybie binarnym.

Jeżeli funkcja

 

nie będzie mogła otworzyć pliku, zwróci w miejsce wskaźnika

wartość

73..

(zdefiniowaną w stdio.h). Poniższy program utworzy nowy plik dane.txt

i udostępni go do odczytu i zapisu:

<   20

  

"

T]Z&4#

 * 2  **H*#

$

Aby zamknąć strumień, używamy funkcji

 

, wymagającej podania wskaźnika

do pliku.

 #

Jeżeli podczas zamykania strumienia wystąpi błąd, funkcja

 

zwróci wartość

niezerową (znacznik EOF — End Of File). Do przesyłania i odbierania danych ze
strumieni służą cztery podstawowe funkcje:

 

,



,

 

i



.

Funkcja

 

odczytuje pojedynczy znak z określonego strumienia wejściowego

(przekształcany do liczby całkowitej):

  T]Z&4#

Jej odwrotnością jest



, zapisująca pojedynczy znak do określonego strumienia

wyjściowego:

    T]Z&4#

Funkcja

 

odczytuje ze strumienia wejściowego ciąg:

4 4   T]Z&4#

background image

236

Hack Wars. Na tropie hakerów

Odczyt zostaje przerwany po pobraniu

  

znaków lub znaku nowego

wiersza (również wstawianego do tablicy). Do odczytanego ciągu



dołączany jest koń-

czący znak

73..! % #?  @A*A

. W przypadku wystąpienia błędów

funkcja zwraca

73..

.

Funkcja



zapisuje do strumienia ciąg zakończony znakiem

73..

(inaczej

A*A

):

    4 T]Z&4#

Wszystkie opisywane funkcje zwracają w przypadku błędów wartość

0B,

(zdefinio-

waną w stdio.h) z wyjątkiem funkcji

 

, która w przypadku wystąpienia błędu

zwraca

73..

. Poniższy program tworzy kopię pliku dane.dat, o nazwie dane.old, ilu-

strując zarazem użycie wszystkich czterech funkcji:

<   20

 

"

T]Z&4#

T]Z&4 #

 *  2  ***#

KYZZ

"

 *+K 8  E     2  *#

 !#

$

  * 2  **H*#

 KYZZ

"

 *+K 8  E  2  *#

 !#

$

349  5   5  5 G43

348  &LT43

> 

   #

34M5   43

 #

  #

 !#

$

W kolejnym przykładowym programie używamy funkcji



do kopiowania tekstu

ze strumienia



(zazwyczaj oznacza to znaki wprowadzane z klawiatury) do no-

wego pliku dane.txt:

<   20

 

"

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

237

T]Z&4#

  ? !!@#

 * 2  **H*#



"

   #

   #

$

4  #

 #

$

Swobodny dostp do danych strumieni

Dostęp swobodny do danych dostarczanych za pośrednictwem strumieni zapewnia
funkcja

 #

o prototypie:

 T]Z&4     #

Funkcja zmienia pozycję wskaźnika pliku skojarzonego ze strumieniem otwartym
wcześniej przez

 

. Wskaźnik ustawiany jest na

  

za (lub przed

w przypadku wartości ujemnej) pozycją

 

. Tą ostatnią może być początek

pliku, bieżące położenie wskaźnika lub koniec pliku. Pozycje te symbolizują stałe

/00C)/01

,

/00C)D32

i

/00C)07E

. Udaną operację

 #

sygnalizuje zwrócenie warto-

ści



. Uzupełnieniem

 #

jest funkcja

 

, zwracająca wartość bieżącej pozy-

cji wskaźnika pliku:

   T]Z&4#

Funkcja zwraca pozycję wskaźnika pliku, określoną jako ilość bajtów od początku
pliku, lub

;

w przypadku błędu.

Uchwyty

Uchwyty plików (handles) otwiera funkcja

 

o prototypie:

  4    &?  @#

Udaną operację sygnalizuje zwrócenie numeru uchwytu. W pozostałych przypadkach
zwracane jest

F

. Na wartość

 

składają się połączone bitową operacją OR stałe

symboliczne, odpowiadające deklaracjom w pliku fcntl.h. Różnią się one w zalezności
od kompilatora. Do typowych należą:

L(D99&KX

przed każdym zapisem wskaźnik pliku będzie ustawiany na końcu pliku,

L(7[&D'

jeżeli plik nie istnieje, zostanie utworzony,

L('[YK7

obcina istniejący plik do długości 0 bajtów,

L(&)7Z

używane w połączeniu z

B)D20-1,

L(:]KD[b

otwiera plik w trybie binarnym,

L('&)'

otwiera plik w trybie tekstowym.

background image

238

Hack Wars. Na tropie hakerów

Po przypisaniu uchwytu pliku za pomocą polecenia

 

można korzystać z funkcji



i

"  

. Prototyp



jest następujący:

   %    4   #

Funkcja podejmuje próbę odczytu podanej liczby bajtów i zwraca liczbę bajtów fak-
tycznie pobranych przez uchwyt pliku. Odczytane dane umieszczane są w bloku pa-
mięci określonym parametrem



. Funkcja

 

działa podobnie, nie różni się

również jej prototyp i sposób generowania wartości zwracanej. Zapisuje ona podaną
ilość bajtów z określonego wskaźnikiem bloku pamięci. Pliki otwierane funkcją

 

zamykamy funkcją

 

:

   %  #

Funkcja

 

zwraca



w przypadku operacji udanej, a

F

w przypadku wystąpie-

nia błędów.

Dostęp swobodny zapewnia funkcja

 #

, bardzo podobna do

 #

, ale pobie-

rająca jako parametr numer uchwytu, a nie wskaźnik strumienia

,6.0

. W poniższym

przykładzie wykorzystujemy uchwyt pliku do zapisu danych z



(czyli klawiatu-

ry) do nowego pliku o nazwie dane.txt:

<  20

<  20

< +  20

 

"

  #

  ? !!@#

  * 2  *L([X,[/L(7[&D'/L('[YK7F(],[]'&#



"

   #

  .     #

$

4  #

  #

$

Przegl*d funkcji plikowych

Norma ANSI definiuje związane z plikami operacje we-wy przy użyciu strumieni,
opisując różnorodne funkcje. Prototyp funkcji

 

ma postać:

T]Z&4   4   4#

Funkcja podejmuje próbę otwarcia strumienia łączącego z plikiem o podanej nazwie
w określonym trybie. Udana operacja kończy się zwróceniem wskaźnika typu

,6.0

.

W przypadku niepowodzenia funkcji zwraca

73..

. Na wcześniejszych stronach przed-

stawiony został opis parametru



.

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

239

Funkcja

 

służy do zamykania strumienia otwartego wcześniejszym wywoła-

niem

 

:

  T]Z&4#

Udana operacja

 

kończy się opróżnieniem wszystkich buforów pliku i zwró-

ceniem wartości



. W przypadku błędów zwracana jest wartość

0B,

.

Wiele komputerów korzysta z buforowanego dostępu do plików. Oznacza to, że dane,
zapisywane do strumienia, wstępnie umieszczane są w pamięci, a faktyczny zapis na-
stępuje dopiero po przekroczeniu pewnej granicznej ilości bajtów. Jeżeli w czasie,
gdy dane nie zostały jeszcze faktycznie zapisane do strumienia, nastąpi awaria zasila-
nia, dane zostaną utracone. Zabezpiecza przed tym funkcja



, wymuszająca

zapisanie wszystkich danych oczekujących:

  T]Z&4#

Jeżeli wywołanie



jest udane, związane ze strumieniem bufory zostają opróż-

nione i zwracana jest wartość



. W przypadku błędów funkcja zwraca wartość

0B,

.

Kolejną funkcją jest

 

zwracająca lokalizację wskaźnika pliku:

   T]Z&4#

Funkcja zwraca przesunięcie wskaźnika pliku w stosunku do początku pliku lub

F.

w przypadku błędów. Przesunięcie wskaźnika pliku do nowej pozycji umożliwia

 #

:

 T]Z&4     #

Funkcja podejmuje próbę przesunięcia wskaźnika pliku o



bajtów od pozycji

 

, określonej jedną ze stałych:

F&&\(F&'

początek pliku,

F&&\(7Y[

bieżąca pozycja wskaźnika pliku,

F&&\(&KX

koniec pliku.

Przesunięcie (



) może być wartością dodatnią (przesuwanie wskaźnika w stronę

końca pliku) lub ujemną (przesuwanie wskaźnika w stronę początku pliku). Aby
szybko przenieść wskaźnik do początku pliku i usunąć wcześniejsze odwołania do
błędów, C dostarcza funkcji

"

:

   T]Z&4#

Funkcja ta działa podobnie jak

 #&.&/00C)/01

. Jednak

 #

usuwa znacz-

nik

0B,

, a

" #"

wszystkie sygnały błędów. Informacje o błędach funk-

cji plikowych można pobrać przy użyciu funkcji

  

:

  T]Z&4#

Funkcja zwraca wartość niezerową, jeżeli w określonym strumieniu wystąpił błąd. Po
sprawdzeniu wartości

  

należy zadbać o usunięcie sygnałów błędów za po-

mocą funkcji

 

:

  T]Z&4#

background image

240

Hack Wars. Na tropie hakerów

Sprawdzenie, czy spełniony jest warunek osiągnięcia końca pliku, realizuje predefi-
niowane makro

 

:

  T]Z&4#

Makro zwraca wartość niezerową, gdy dla danego strumienia stwierdzono osiągnięcie
końca pliku. W pozostałych przypadkach zwracaną wartością jest



.

Dostępnych jest kilka funkcji realizujących odczyt danych ze strumienia plikowego.
Pojedyncze znaki można odczytywać funkcją

 

:

  T]Z&4#

 

zwraca wartość ASCII pobranego znaku lub znak

0B,

w przypadku wystąpie-

nia błędu. Odczyt ciągu danych umożliwia funkcja

 

, odczytująca ciąg zakoń-

czony znakiem nowego wiersza:

4 '   T]Z&4#

W wyniku udanego wywołania funkcji w zmiennej



umieszczany jest ciąg zakoń-

czony znakiem nowego wiersza lub zawierający



znaków. Funkcja zachowuje

kończący ciąg znak nowego wiersza, dołączając do ciągu



bajt

73..

. W przypadku

nieudanego wywołania zwracany jest wskaźnik pusty. Ciągi zapisujemy do strumie-
nia funkcją



:

    4 T]Z&4#

Funkcja



zapisuje wszystkie znaki ciągu



, z wyjątkiem końcowego bajtu

73..

, do strumienia



. Standardowo funkcja zwraca ostatni zapisany znak, a w przy-

padku wystąpienia błędów —

0B,

. Dostępna jest również funkcja zapisująca do stru-

mienia pojedynczy znak



:

    T]Z&4#

Funkcja zwraca zapisany znak lub, w przypadku wystąpienia błędów, znak

0B,

.

Aby odczytać ze strumienia duży blok danych lub rekord, można posłużyć się funkcją

 

:

(    4(  (  T]Z&4#

Funkcja podejmuje próbę odczytu



elementów, z których każdy ma długość

 

,

ze strumienia plikowego



do bloku pamięci określonego wskaźnikiem



. Aby

ustalić, czy operacja przebiegła bez zakłóceń, korzystamy z funkcji

  

.

Siostrzaną funkcją

 

jest

"  

:

(      4(  (  T]Z&4#

Funkcja zapisuje



elementów o długości

 

z obszaru pamięci określonego

wskaźnikiem



do strumienia



.

Funkcja

 

umożliwia odczyt danych formatowanych:

 T]Z&4  4? 222@#

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

241

Funkcja zwraca liczbę faktycznie odczytanych pól, a

0B,

w przypadku końca pliku.

Poniższy przykład ilustruje użyteczność funkcji

 

podczas odczytywania ze

strumienia liczb:

<   20

  

"

T]Z&4#

 #

  #

 #

  #

 #

  ? !!@#

 * 2  **H*#

>

"

 *K 8  E *#

 !#

$

 * 1A`I+*, +**#

 #

 

"

 *:;C   * #

  #

$

 #

 

"

 *:;C 5   * #

  #

$

*- - - - - -*.. .. .  #

 

"

 *:;C     * #

  #

$

 *+T 5G;- - - - - -*    #

$

Jak łatwo zauważyć, zapis formatowanych danych realizuje funkcja

 

. Gdy

pojawia się potrzeba zapisania położenia wskaźnika pliku i późniejszego jego przy-
wrócenia, można skorzystać z funkcji

 

i

 

. Pierwsza z nich odczy-

tuje bieżącą pozycję wskaźnika pliku:

   T]Z&4 ( 4 #

background image

242

Hack Wars. Na tropie hakerów

Funkcja

 

ustawia wskaźniki pliku na określonej pozycji:

   T]Z&4   ( 4 #

Typ

)

zdefiniowany został w nagłówku stdio.h. Funkcje te są wygodniejsze

w użyciu niż

 

i

 #

.

Z otwartym już strumieniem można skojarzyć nowy plik. Umożliwia to funkcja

  

:

T]Z&4   4   4T]Z&4#

Funkcja zamyka strumień istniejący i podejmuje próbę jego ponownego otwarcia przy
użyciu podanej nazwy pliku. Znajduje to zastosowanie przy przekierowywaniu stru-
mieni predefiniowanych



,



i



do pliku lub urządzenia. Przykłado-

wo, gdy pojawia się potrzeba przekierowania wszystkich danych wyjściowych kiero-
wanych do



na drukarkę, można użyć polecenia:

 *Z9' *** #

Predefiniowane strumienie we-wy

Wstępnie zdefiniowane zostały trzy strumienie we-wy:



,



i



. Do-

myślnie



i



odpowiadają klawiaturze i monitorowi. Na wielu platformach,

w tym systemów DOS i UNIX, dostępna jest możliwość ich przekierowania. Stru-
mień



domyślnie powiązany jest z monitorem (wyświetlaczem). Praktyka jego

przekierowywania nie jest raczej stosowana. Jego podstawowym zadaniem jest za-
pewnienie możliwości wyświetlania komunikatów błędów, nawet w sytuacji gdy po-
wiązanie standardowego wyjścia (



) zostało zmienione:

 *\     ;6 * #

Funkcje

 

i



przekazują dane do strumienia



. Funkcje

 

i



pobierają dane ze strumienia



. Przekierowanie tych strumieni zmienia

sposób działania funkcji.

Jako przykład plikowych operacji we-wy na platformie PC, korzystających z możli-
wości przekierowania strumieni, przedstawimy prosty program przesyłający do stru-
mienia



zawartość określonego pliku, przedstawioną jako wartości szesnastko-

we. Polecenie w postaci:

( 20 (5B 2

pozwoli zmienić domyślne powiązanie strumienia



z monitorem.

<   20

<  20

<  20

<  20

 4?@

"

  #

   ?1!@#

  #

 #

 #

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

243

>1

"

 *+:cdX29 ;  ;S  +* #

  #

$

  ? @L([XLKZb#

  

"

  *+:cdX2K 8  E-+*? @#

  #

$

  *+MD,D['Lef9Z]\Y-++*  ? @#

!#

 

"

34,;  43

  !1!#

349      43

(  .  W#

34! &LT   ;C 43

 

 #

34,  V   43

  *-!W -!I*#

H W#

34,  V   B 5 G  43

 !# W#HH

  *-!1* ?@#

34,  V BDF7]] 5 G  43

 !# W#HH

"

 ?@0A .. ?@ 1^

  *-* ?@#



 *2* #

$

34M _  43

 *+* #

$

34 _ 43

 !#

$

background image

244

Hack Wars. Na tropie hakerów

Ci"gi

Język C należy do najlepiej wyposażonych w funkcje obsługi ciągów pośród uniwer-
salnych języków programowania. Ciąg to jednowymiarowa tablica znaków zakoń-
czona bajtem zerowym. Ciągi można inicjować dwoma sposobami. Pierwszym jest
nadanie im stałej wartości w kodzie programu:

 

"

4*F I*#

?@*9   *#

 !#

$

Drugi to utworzenie ciągu w czasie wykonywania programu za pomocą funkcji

 %

:

4 4    4"#

Funkcja

 %

kopiuje ciąg źródłowy do lokalizacji docelowej, na przykład:

<   20

 

"

?I!@#

 *FF  *#

 *+, BEC UU -*#

 !#

$

Język C umożliwia bezpośredni dostęp do każdego bajtu ciągu:

<   20

 

"

?I!@#

 *FF  *#

 *+, BEC UU -*#

34M C  5  CUU43

?!@UU#

 *+, BEC UU -*#

 !#

$

Niektóre kompilatory C wyposażone zostały w funkcje konwersji ciągów do wielkich
i małych liter, nie obejmuje ich jednak norma ANSI. W specyfikacji pojawiają się za
to funkcje

 

i

" 

, zwracające pojedynczy znak ( w postaci wartości



)

zamieniony na literę wielką lub małą. Łatwo na tej podstawie utworzyć własne funk-
cje konwersji ciągów:

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

245

<   20

    4  

"

4#

  #

4

"

40gN..4 11

4 4#

HH#

$

$

   4  

"

4#

  #

4

"

40WI..4g!

4  4#

HH#

$

$

 

"

?I!@#

 *FF  *#

 *+, BEC UU -*#

  #

 *+, BEC UU -*#

 #

 *+, BEC UU -*#

 !#

$

'  ; 2T 5     C ;

 5C55   EVG ; 2\ 5 6     

56    B A1  5 G8 6    5C

  ;2aB   5  6 5 8 C

C 5 86  2,   hFi   

hAi2, 5      ; 6 

; 2S

4

"

40gN..4 11

4 4#

HH#

background image

246

Hack Wars. Na tropie hakerów

$



4

"

40WI..4g!

4  4#

HH#

$

X      ; 92:22

W przeciwieństwie do innych języków programowania C nie narzuca ograniczenia dłu-
gości ciągu. Jednak w przypadku niektórych procesorów (CPU) pojawia się ogranicze-
nie wielkości bloku pamięci. Oto prosty program odwracający kolejność znaków w ciągu:

<   20

<  20

4 4

"

34L  5 BEGC    5C5 43

34 _ KYZZ43

4 #

4 #

 #

34Y VU U   C 43

 H  #

34M V  C  C 43

 #

34M43

 0

"

 4 #

4 4#

4 #

 #

HH#

$

  #

$

  

"

  ? !!@#

4#

   *' 5 C*#

   #

 *+-*#

$

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

247

strtok()

Funkcja

 #

jest istotną funkcją języka C, służącą do wyłączania fragmentów

ciągu. Stosuje się ją, gdy poszczególne podciągi rozdzielone są znanymi ograniczni-
kami, na przykład przecinkami:

<   20

<  20

  

"

 ?I!@#

4#

  *7M&[,LKb9LJD[Dj7ML,bklc'bM]&ZLKbK]&:]&F\]*#

   **#



"

 #

  KYZZ**#

$#

$

Program można oprzeć też na pętli

 

:

<   20

<  20

  

"

 ?I!@#

4#

  *7M&[,LKb9LJD[Dj7ML,bklc'bM]&ZLKbK]&:]&F\]*#

    **##  KYZZ**

"

 #

$#

$

W pierwszym wywołaniu funkcji

 #

podajemy nazwę zmiennej ciągu oraz

ogranicznik. Funkcja zwraca wówczas wskaźnik do początku pierwszego podciągu
i zastępuje pierwszy ogranicznik zerem. Kolejne wywołania

 #

wykonywane są

w pętli. Pierwszym parametrem jest wówczas

73..

, a funkcja zwraca kolejne podcią-

gi. Ponieważ dopuszczalne jest podanie listy ograniczników, funkcja

 #

może

posłużyć do utworzenia prostego programu zliczającego słowa:

<   20

<   20

<  20

   4?@

"

T]Z&4#

  ?1IW@#

background image

248

Hack Wars. Na tropie hakerów

4#

 #

>1

"

 *+:cdX29 ;  ;S    +* #

 !#

$

34L G   43

 ? @**#

34F V  ;  43

>

"

 *+:cdX2K 8  E VG ;  +* #

 !#

$

34]5 543

!#



"

34L  5  43

   1II#

34F V C; ;C  &LT43

 // 

   #

34M;   43

34F; G865     43

34+   + #S2>R543

    *+ +#S2>R*#



"

HH#

  KYZZ*+ +#S2>R*#

$

$

> ..> #

34L   _ 2:;C R43

 

"

 *+:;C   VG ;  +* #

 #

 !#

$

34L   _  &LT43

34,   6;G43

 *+9-- ;G; +*? @#

 #

$

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

249

Zamiana liczb na ci*gi i ci*gów na liczby

Wszystkie kompilatory C zapewniają możliwość konwertowania liczb na ciągi przy
użyciu takich funkcji jak

 

. Funkcja ta ma jednak wiele zastosowań, co po-

woduje, że jest rozbudowana i mało wydajna. Może ją zastępować funkcja

61B/

,

korzystająca z dwóch parametrów: liczby całkowitej ze znakiem i wskaźnika do ciągu
znakowego. Funkcja kopiuje liczbę do określonego wskaźnikiem miejsca w pamięci.
Podobnie jak

 

, funkcja

61B/

nie sprawdza, czy ciąg docelowy ma wystar-

czającą do przechowania wyniku konwersji długość. Oto przykładowa funkcja, która
kopiuje liczbę

  

do ciągu znakowego.

  ]'LF 4 

"

34M_ 6 C 6;  CCG43

  ?g@" !!!!!!!! !!!!!!! !!!!!! !!!!! !!!! !!! !! ! $#

 #

34F V43

!

"

4 HHUU#

34M_ BE 6 C43

!#

$

 !#g#HH

"

0 ?@

"

4 HHU!UH3 ?@#

- ?@#

$

$

4 U+!U#

 _;_     ;   

å    68     592:2

 #

$

9 8  ; ;   5 5 5C6

å 29 85     C C5692:2S

  ]'LF 4 

"

34M_ 6 C 6;  CCG43

  ?g@" !!!!!!!! !!!!!!! !!!!!! !!!!! !!!! !!! !! ! $#

 #

 !#33    C  C

34F V43

!

"

4 HHUU#

HH#

34M_ BE 6 C43

!#

$

background image

250

Hack Wars. Na tropie hakerów

 !#g#HH

"

HH#

4 HHU!UH3 ?@#

- ?@#

$

4 U+!U#

  #33 G V C C

!#

4 UU33 6  C  5B5 

 HH#

4 U!U"33 5 C  

HH#

 HH#

$

4 >U+!U"

4 4 #33C 5 8  C 

 HH#

$

4 U+!U#

 #

$

Język C oferuje dwie funkcje do zamiany ciągów znakowych na liczby zmiennoprze-
cinkowe:



i

 

. Prototyp funkcji



ma postać:

   4 #

a prototyp funkcji

 

:

    4 44 #

Obie funkcje przeglądają ciąg i przeprowadzają konwersję aż do momentu natrafienia
na niezrozumiały znak. Różnica między nimi polega na tym, że

 

pobiera do-

datkowy parametr, wskaźnik



ustawiany na pierwszy znak ciągu, który nie został

objęty konwersją. Znacznie zwiększa to wygodę sprawdzania poprawności wykona-
nia operacji.

Aby zamienić ciąg na wartość całkowitą, można użyć funkcji



:

    4 #

Należy pamiętać, że funkcja



nie zapewnia żadnej kontroli przepełnienia zmien-

nej. Nie jest zdefiniowana wartość zwracana w takiej sytuacji. W podobny sposób
działa funkcja



, zwracająca wartość



. Odpowiedniki z dodatkowym para-

metrem noszą nazwy

 

i

 

.

Obsługa tekstu

Człowiek zapisuje informacje jako pewien „tekst”, złożony ze słów, liczb i znaków
przestankowych. Słowa złożone są z liter wielkich i małych, odpowiednio do wyma-
gań gramatyki. Wszystko to sprawia, że komputerowe przetwarzanie tekstu nie jest

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

251

zadaniem prostym. Norma ANSI definiuje wiele funkcji przetwarzania ciągów zna-
kowych, które z natury rozpoznają wielkość liter. Oznacza to, że litera „A” rozpo-
znawana jest jako różna od „a”. Jest to pierwsze zagadnienie, którego rozwiązanie
musi znaleźć programista pracujący nad programem przetwarzającym tekst. Na szczę-
ście, zarówno kompilatory Borlanda, jak i Microsoftu wyposażone zostały w funkcje
obsługi ciągów, które nie rozpoznają wielkości liter.

Taką odmianą funkcji

  

jest

  

, a

  

  

. Gdy jed-

nak pojawia się kwestia przenośności kodu, niezbędna jest zgodność z ANSI C, co
pociąga za sobą napisanie własnych funkcji.

Poniżej przedstawiamy prostą implementację nierozróżniającej wielkości liter odmia-
ny funkcji

  

. Tworzy ona kopie ciągów, zamienia je na wielkie litery i wyko-

nuje standardową operację

  

. Pozwala to określić poszukiwaną wartość prze-

sunięcia i utworzyć wskaźnik do ciągu źródłowego.

4  4 41

"

 ? !!!@#

1? !!!@#

4#

   #

 11#

   #

  1#

   1#



  H #

 KYZZ#

$

Kolejna funkcja przegląda ciąg



, wyszukując słowo podane jako

G

. Aby funkcja

zwróciła wartość

1230

, znalezione musi zostać odrębne słowo, a nie jedynie sekwen-

cja znaków. Wykorzystujemy przygotowaną wcześniej funkcję

  

.

   (4 41

"

34 BE C5815 ;   43

4#

4m#

  #

 !#

m #



"

34Z  5 C5G1 43

  m1#



"

background image

252

Hack Wars. Na tropie hakerów

34M 43

  #

0 

"

34F V  C43

4 0UDU..4 UU

 !#

$

34K 5 C 43

H 1#

4

"

34F V C43

40UDU..4UU

 !#

$

$

m#

$

..> #

  #

$

Szerokie zastosowanie znajdzie kilka dalszych prostych funkcji znakowych.

  

obcina ciąg znakowy:

     4  

"

34L U UGC UU43

  

?  @!#

$

  

usuwa końcowe znaki spacji (odstępu międzywyrazowego) w ciągu:

   4  

"

34  5 _ 43

4#

.  ?    @#

4A1..0  

4!#

$

  

zmienia długość ciągu:

   4  

"

34M ;  BEC  ;C5C   5C43

 0!

 H  H #



"

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

253

 ! #

 H  H #

$

$

 

umieszcza jeden ciąg w innym:

   44m

"

34, Cm C 43

  m#

 m m#

$

  

zastępuje wszystkie wystąpienia pewnego podciągu innym podciągiem:

   4 4 41

"

34M 6 5  C C143

4#

 #



"

 !#

    #



"

34Y _C 43

 !  #

34, C43

 1#

  #

$

$

 #

$

Data i godzina

Język C wyposażony jest w funkcję

 

, która odczytuje zegar systemowy kom-

putera i podaje informację o dacie i godzinie w postaci liczby sekund, która upłynęła
od północy 1 stycznia 1970 roku. Wartość ta może zostać zamieniona na czytelny dla
człowieka ciąg znaków za pomocą funkcji

 

:

<   20

<  20

 

"

34F         243

 (  #

349   6 6  43

  KYZZ#

 *:8C   S-+* . #

$

background image

254

Hack Wars. Na tropie hakerów

Na ciąg zwracany przez

 

składa się siedem pól:

J

J

J

J

dzień tygodnia,

J

J

J

J

miesiąc roku,

J

J

J

J

dzień miesiąca,

J

J

J

J

godzina,

J

J

J

J

minuty,

J

J

J

J

sekundy,

J

J

J

J

rok.

Uzupełnieniem jest znak nowego wiersza i końcowe 0. Ponieważ pola mają stałą sze-
rokość, ciąg zwracany przez

 

idealnie nadaje się do operacji wymagających

wyodrębnienia elementów daty lub godziny. W poniższym programie definiujemy
strukturę

!

oraz funkcję

  !) ! 

, której zadaniem jest wypełnienie

struktury treścią pól ciągu

 

:

<   20

<  20

<  20

    

"

 (#34J 43

 ( #34% 43

 (#34F  43

$#

   (     4 

"

 (  #

 ?1W@#

4 #

349   6 6  43

  KYZZ#

349    6 6  C 43

   . #

34L  5    43

 ? g@!#

 . ? @#

349 5C  5     43

 *-1 S-1 S-1 *. 0( . 0(. 0(#

$

 

"

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

255

     #

 ( . #

 *+a  -!1 S-!1 S-!1 *. 2( . 2(. 2(#

$

Norma ANSI przewidziała również funkcję konwertującą wartość zwracaną przez
funkcję

 

do postaci struktury. Przedstawiony poniżej przykład zawiera deklara-

cję struktury



z nagłówka

 +

:

<   20

<  20

 

"

 (  #

    4 #

349   43

  KYZZ#

34M_ BE    6 43

   . #

 *+a  -!1 S-!1 S-!1 * 0 (  0 ( 0 (#

 !#

$

Struktura



(zawarta w pliku

 

) ma następującą postać:

    

"

  (#

  (#

  ( #

  ( #

  ( #

  (#

  ( #

  ( #

  (  #

$#

'    8 E6BC  5     5 5 8

å    ;G 2, 5 5  B  ;C 2

å J 85C  E 5    G ;G6 

å BE  6I 92:2

Liczniki czasu

Programy często korzystają z możliwości pobrania daty i czasu z nieulotnej pamięci
RAM komputera. Norma ANSI przewiduje kilka różnych funkcji, które mogą zostać
do tego celu wykorzystane. Pierwszą jest funkcja

 

, zwracająca liczbę sekund od

1 stycznia 1970 roku:

(   ( 4 #

background image

256

Hack Wars. Na tropie hakerów

Funkcja wypełnia przekazaną jej jako parametr zmienną typu

 )



jeśli nie jest to

73..

, zwracając tę samą wartość również jako wartość wyjściową. Można więc wywo-

ływać funkcję

 

z parametrem

73..

i korzystać z wartości zwracanej:

<  20

  

"

 (  #

  KYZZ#

$

Funkcja

 

zamienia strukturę



na 26-znakowy ciąg (przedstawiony przy

opisie funkcji

 

):

4       4 #

Funkcja

 

zamienia wartość czasu (zwracaną przez

 

) na 26-znakowy ciąg:

<   20

<  20

<  20

  

"

 (  #

  ?A!@#

  KYZZ#

    . #

$

Kolejna funkcja,

 

, zwraca, liczoną w sekundach, różnicę między dwoma

wartościami typu

 )

. Służy więc do wyznaczania ilości czasu, jaki upłynął mię-

dzy dwoma zdarzeniami, czasu wykonywania funkcji lub generowania przerw w pra-
cy programu, na przykład:

<   20

<  20

  X&ZDb  

"

 (  #

  KYZZ#

 KYZZ H 

#

$

  

"

 *+[   222I  *#

X&ZDbI#

 *+L _ 2*#

$

background image

Rozdział 6.

¨

¨

¨

¨ Podstawy programowania dla hakerów

257

Funkcja

 

zamienia lokalną wartość czasu

 )

na wartość GMT o postaci

struktury



. Działanie tej funkcji zależy od ustawienia globalnej zmiennej strefy cza-

sowej. Struktura



została wstępnie zdefiniowana w nagłówku

 +

. Przedstawili-

śmy ją kilka stron wcześniej.

    

"

  (#

  (#

  ( #

  ( #

  ( #

  (#

  ( #

  ( #

  (  #

$#

Element struktury

 )  %

przechowuje dzień miesiąca (od 1 do 31), a

 )" %

— dzień

tygodnia (gdzie niedzieli odpowiada 0). Czas jest mierzony od 1900 roku. Wartość

 )

to znacznik, który informuje o tym, czy stosowany jest czas letni. Stosowa-

ne nazwy struktury i jej elementów mogą różnić się w zależności od kompilatora,
jednak sama struktura zasadniczo pozostaje niezmieniona.

Funkcja

# 

zamienia strukturę



na wartość

 )

, uzupełniając wartości pól

 )" %

i

 )% %

:

(      4#

W kolejnym przykładzie umożliwiamy wprowadzanie daty i używamy funkcji

# 

do ustalenia dnia tygodnia. Należy pamiętać, że funkcje związane z czasem rozpo-
znają wyłącznie daty późniejsze niż 1 stycznia 1970:

<   20

<  20

<  20

  

"

        #

  #

  ? !!@#

4#

4 ?@

"* **  ;** **B ** **C ** **

å   gN!*$#



"

 !#

 *+,  V  6  33*#

   g #

    *3*#

>KYZZ

    2 (  #



   #

background image

258

Hack Wars. Na tropie hakerów

  KYZZ*3*#

>KYZZ

    2 (  #



   #

  KYZZ*3*#

>KYZZ

    2 ( #



   #

  #

$

> #

    2 ( !#

    2 (!#

    2 ( #

    2 (   #

34'   _  43

 .     

    2 ( N#

 *' _ -+* ?    2 ( @#

$

Funkcja

# 

zapewnia również wprowadzenie odpowiednich poprawek dla warto-

ści przekraczających swój dopuszczalny zakres. Można to wykorzystać do ustalenia do-
kładnej daty, odległej o



dni:

<   20

<  20

<  20

  

"

    4    #

 (  5#

 5 KYZZ#

      . 5#

    0 ( H !#

     #

    0 (0gg



    0 (- !!#

   5CB   ;6       5

å  ;C;    g!!5  ; 8 gg 92:2

 *M 6E  6 -!1 3-!1 3-!1 +*    0 (     0 ( H

å      0 (#

$


Wyszukiwarka

Podobne podstrony:
Nowa podstawa programowa WF (1)
1 Podstawy programowania dialogowego
nowa podstawa programowa sp
11-nkb~1, wisisz, wydzial informatyki, studia zaoczne inzynierskie, podstawy programowania, l2
2-eukl~1, wisisz, wydzial informatyki, studia zaoczne inzynierskie, podstawy programowania, l2
Zmiany w podstawie programowej w zakresie edukcji matematycznej, Wczesna edukacja, Materiały do prac
1-algo~1, wisisz, wydzial informatyki, studia zaoczne inzynierskie, podstawy programowania, l2
c-zadania-w3, wisisz, wydzial informatyki, studia zaoczne inzynierskie, podstawy programowania, kol
Wychowanie w nowej podstawie programowej katechezy, szkoła, Rady Pedagogiczne, wychowanie, profilakt
PP temat6, Podstawy programowania
PODSTAWA PROGRAMOWA WYCHOWANIA PRZEDSZKOLNEGO
Laboratorium Podstaw Programowania 2
Podstawa programowa dla gimnazjum
Pytania na egzamin nowa podstawa programowa, sem I
Podstawy programowania (wykład III)
Podstawy Programowania Lab 1 dod
Podstawa programowa –?lów wychowania przedszkolnego oraz obszarów?ukacyjnych

więcej podobnych podstron