Ne-am mutat !!!

Ne-am mutat pe http://de-ce.net !!!

Anunțuri

[PHP] Expresii regulate

Expresii regulate in PHP

Salut! In aceasta lectie vom invata despre expresiile regulate in PHP, folosite de obicei pentru functiile preg_match si preg_match_all (http://us.php.net/manual/ro/function.preg-match-all.php).Ce este o expresie regulata ? O expresie regulata (regexp) reprezinta un text special, un sablon, care descrie un anumit text. Ce reprezinta aceste functii ? Cauta intr-un anumit string un anumit “substring”, echivalentul expresiei care am format-o daca il pot denumi asa si afiseaza toate “potrivirile” posibile intr-un array. Sintaxa functiei preg_match_all este urmatoarea:

</p>
<p class="MsoNormal"><span class="default">preg_match_all</span><span class="keyword">(“expresia regulata</span><span class="string">”</span><span class="keyword">,</span> <span class="string">"stringul in care cautam echivalentul expresiei"</span><span class="keyword">,</span> <span class="default">$var</span><span class="keyword">, </span><span class="default">PREG_SET_ORDER</span><span class="keyword">);</span></p>
<p class="MsoNormal"><span class="keyword">

Variabila $var primeste rezultatele, iar ele vor fi afisate sub forma unui array. Insa pe noi nu asta ne intereseaza, ci “expresia regulate” in sine.

In primul rand, sa analizam 2 simboluri destul de importante:

“^inceput” – cauta fiecare substring care contine la inceputul acestuia cuvantul: inceput. Deci, practic, ^ semnifica inceputul unui substring (cauta la inceput).

“sfarsit$” – cauta fiecare substring care contine la sfarsitul acestuia cuvantul: sfarsit. Deci, practice, $ semnifica sfarsitul unui substring (cauta la sfarsit).

In concluzie, ca sa cautam un substring care contine la inceputul acestuia grupul “mama”, iar la sfarsit tot grupul “mama”, in interiorul stringului “mamaestemama”, vom folosi expresia regulata: “^mama$”.

Pana sa ajungem sa construim expresii regulate de la cap la coada, trebuie sa mai invatam despre cateva “caractere speciale”, fiecare avand un rol bine stabilit si foarte important. Sa vedem:

“xy*” – gaseste orice substring care are dupa x, 0 sau mai multi de y (ex: “x”, “xy”, “xyy”, “xyyy”, “xyyyy”, etc.).

“xy+” – gaseste orice substring care are dupa x cel putin un y (ex: “xy”, “xyy”, “xyyy”, “xyyyy”, etc.).

“xy{3} – gaseste orice substring care are dupa x, exact 3 de y (“xyyy”).

“xy{2,5}” – gaseste orice substring care contine dupa x, intre 2 si 5 de y (ex: “xyy”, “xyyy”, “xyyyy”, “xyyyyy”).

“xy{3,}” – gaseste orice substring care are dupa x cel putin 3 de y (ex: “xyyy”, “xyyyy”, “xyyyyy”, “xyyyyyy”, etc.).

“xy?” – “poate sa fie sau sa nu fie J”.

De asemenea, putem utiliza si secvente de caractere in interiorul expresiei regulate, aceste secvente fiind puse intotdeauna intre paranteze: (secv) . Exemplu: [b]asd(ex){2,5}[/b]. Acest exemplu gaseste orice substring de forma: asdexex, asdexexex, asdexexexex, asdexexexexex.

Un alt semn foarte important este reprezentat de caracterul | . Exemplu: “eu|tu”, gaseste orice substring care are in componenta eu sau tu. | = OR (la fel ca in C++). Spre exemplu: “^eu|tu” gaseste orice substring care incepe cu eu, sau cu tu.

Punctul: “.” reprezinta un caracter. Orice caracter… Sa consideram urmatorul exemplu: “.(asd){2,5}”. Acesta cauta substringuri care contin caractere de forma: “Xasdasd” sau “Masdasdasd”, etc.

Perechea de paranteze drepte [ ] este asemanatoare cu | . Spre exemplu, “[ab]” este echivalent cu “a|b”. Insa, daca am vrea ca stringul ca contina o cifra, ar trebuie sa scriem o expresie de genul: “0|1|2|3|4|5|6|7|8|9”, insa ia prea mult timp. Acea expresie poate fi inlocuita cu foarte simplista: “[0-9]”. Daca vrem ca substringul sa contina o litera mica de la a la z, folosim: “[a-z]”, daca vrem sa contina o litera mare, tot de la A la Z, folosim: “[A-Z]”. Insa, daca vrem sa folosim si litere mari si litere mici ? Nimic mai simplu: “[a-zA-Z]”. Daca spre exemplu, vrem sa gasim un string care reprezinta un procent (de genul 99%), folosim urmatoarea expresie: “^[1-9][0-9]%$”.

Acum ca am explicat in mare cam ce face fiecare semn important, sa trecem la lucrurile seriose J.

1) [b]Gasirea unei adrese IP valide.[/b] O adresa IP este de forma 172.178.25.43. Mai exact, este formata din 4 grupe de maxim 3 caractere si minim 1, cu valori intre 0 si 255. Evident, in expresia noastra regulate vom folosi si . (punct), caracterul care delimiteaza cele 4 grupe. Dar, cum am precizat mai sus, punctul reprezinta un caracter, de aceea trebuie sa “scapam” oarecum de aceasta notatie. Vom da “escape” la punct, folosind caracterul backslash, ex: “\.” sau “mamaia\.”.

Expresia regulata care cauta o adresa IP valida ar fi urmatoarea:

</span></p>
<p class="MsoNormal"><span class="keyword">“</span><tt><span style="font-family:'Times New Roman';">\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b”</span></tt></p>
<p class="MsoNormal"><tt><span style="font-family:'Times New Roman';">

Poate ati observat, aici am folosit caracterul \b, care semnifica backspace.

2) [b]Gasirea unui numar de telefon.[/b] Sa presupunem ca avem un numar de telefon de genul XX-YYYYYY si vrem sa-l gasim. Un astfel de numar este: 11-123456. Expresia regulate ar fi de genul:

</span></tt></p>
<p class="MsoNormal"><tt><span style="font-family:'Times New Roman';">“^[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]$”</span></tt></p>
<p class="MsoNormal"><tt><span style="font-family:'Times New Roman';">

3) [b]Gasirea unei adrese de e-mail. [/b] Nu ma voi complica si voi prezenta un cod simplu de gasire a adresei de e-mail, nu prea complet si prea “sigur”.

</span></tt></p>
<p class="MsoNormal"><code><span class="html">/[-a-z0-9\._]+@[-a-z0-9\._]+\.[a-z]{2,4}/</span></code></p>
<p class="MsoNormal">

Credit: itzone.ro ! De ce spun ca aceasta expresia nu este prea safe ? Pentru ca un string de genul: asdasd@asdasd.asd il va considera ca fiind o adresa valida de e-mail, desi nu prea este J

Cam atat ! Sper ca este de folos cu ceva tutorialul asta ! Cand am scris acest tutorial am invatat si eu, in acelasi timp cu voi, ce sunt alea expresii regulate, deci daca sunt greseli, post them !!!

Bibliografie:

</span></p>
<p class="MsoNormal"><span class="keyword"><a href="http://www.regular-expressions.info/">http://www.regular-expressions.info/</a></span></p>
<p class="MsoNormal"><span class="keyword">

@vladii 2007

Algoritmul Miller-Rabin

In primul rand, daca gasiti vreo eroare in codul scris de mine sau vreo greseala de algoritm, va rog sa o mentionati, pentru ca nici eu nu sunt 100% sigur de codul pe care l-am facut.
Ok, ce este Algoritmul Miller-Rabin ? Numele sau intreg este: „Testul de primalitate al numerelor Miller-Rabin”. Practic verifica daca un numar este prim sau nu. Insa, nu degeaba se numeste [b]test[/b], pentru ca probabilitatea ca raspunsul returnat de program nu este maxima (pow(4,-k)).
Si poate va intrebati, de ce sa folosesc acest algoritm, cand pot sa impart numarul la toate numerele mai mici decat sqrt(numar) ? Pai da, dar acesta este mult mai rapid si are o complexitate mai mica 🙂
Va prezint in continuare codul scris de mine in C (astept imbunatatiri sau corectari):

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
#include &lt;conio.h&gt;
#include &lt;math.h&gt;
int main()
{
long numar, s=0, a=0, r, d=0, k, aux1=0, aux2=0, i=0, aux3=0, aux4=0;
div_t aux5;
printf("Introdu numarul: ");
scanf("%d", &amp;numar);
printf("\nIntrodu un numar k(probabilitatea este 4 la puterea -k): ");
scanf("%d", &amp;k);
aux1=numar-1;
while(aux1%2 !=1) {
if(aux1%2==0) {
s++; }
aux1=aux1/2; }
printf("%ld", (int)pow(2,s));
aux4=(long)pow(2,s);
aux5=div(numar-1,aux4);
d=aux5.quot;
printf("\nPuterea lui 2 este: %ld iar restul este: %ld", s, (long)d);
if(numar==2 || numar==3 || numar==5 || numar==7 || numar==11) {
printf("\nNumarul este prim"); }
else if(numar=4 || numar==6 || numar==8 || numar==9 || numar==10) {
printf("\nNumarul nu este prim/ este compus"); }
else {
srand(time(NULL));
for(i=0;i&lt;k;i++) {
a=rand() %(numar-1)+1;
aux2=(long)pow(a,d)%numar;
for(r=0;r&lt;=s-1;r++) {
if(aux2 !=1 &amp; (long)pow(a,pow(2,r)*d)%numar !=numar-1) {
aux3=1; } } }
if(aux3==1) { printf("\nNumarul este prim"); }
else { printf("\nNumarul nu este prim/ este compus"); } }
getch();
return 0;
}

Sper sa va fie de folos la ceva (si ma repet, postati eventualele greseli de algoritm ;)).

Bibliografie:

http://en.wikipedia.org/wiki/Miller-Rabin_primality_test
+
https://vladii.wordpress.com

[VIDEO]Cracking TUTs

O sa incerc sa fac cate un astfel de tutorial o data pe saptamana (am foarte, foarte multe pe cap si prea putin timp liber), de la incepator spre avansat.

Prima parte (Absolute Begginer):

Cod:
http://rapidshare.com/files/59259023/primaparte.rar.html

Succes si sa ne revedem cu bine !

––––––––––––––––––––––––––––––

Partea a 2-a (Begginer).

Cod:
http://rapidshare.com/files/60624623/a2-aparte.rar.html

vladii.wordpress.com

P.S. Primul breakpoint trebuia pus pe linia cu JNZ, va dati voi seama. Scuzati-mi eroarea, nu am stat sa refac tutorialul doar pentru asta ^_^

Imagini [Visual Basic]

Salut ! Astazi voi scrie un tutorial legat de programare, mai exact, Visual Basic. Ce vom invata ? Vom invata despre Imagini, Pixeli, R, G, B, GrayScale, etc. Sa incepem !

Ce este o imagine ? O imagine reprezinta mai multe obiecte adunate intr-un tot unitar. O imagine este o insiruire de pixeli. Ce este un pixel ? Pixelul este cea mai mica subdiviziune a unei imagini. Pixelul apare sub forma unui punct [.] si are diferite culori. In concluzie, o imagine este formata din mai multi pixeli cu diferite culori.

Valoarea unei culori este de obicei pe 32 de biti [colorref] (valoarea unei culori este stocata pe 4 bytes, doar 3 sunt importanti -> R, G, B), in format RGB. Ce inseamna format RGB ? R=Red [Rosu], G=Green [Verde], B=Blue [Albastru]. Orice culoare se poate obtine prin amestecul a diferite cantitati din aceste 3 culori.

Acum sa aflam cum putem seta un pixel la o anumita culoare, cum putem scoate R, G, B dintr-o culoare si, mai tarziu [cod sursa], sa folosim GrayScale.

1. Cum setam o un pixel la o anumita culoare ? Pentru aceasta, folosim 2 functii API din libraria GDI32, foarte importante, si anume:

</p>
<p class="MsoNormal">Public Declare Function GetPixel Lib "GDI32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As Long</p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal">Public Declare Function SetPixel Lib "GDI32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long</p>
<p class="MsoNormal"><span> </span>

Despre Functii API am invatat intr-un tutorial anterior (il gasiti pe vladii.wordpress.com). Sa explicam prima functie. GetPixel preia culoarea pixelului aflat la coordonatele (x,y). ByVal hDC As Long reprezinta handleul canvasului imaginii (am povestit despre Handleuri in acelasi tutorial despre Functii API). Handleul Canvasului imaginii se noteaza astfel: Picture1.hDC, unde Picture1 este o imagine de pe Formularul dumneavoastra. Sa dau un exemplu concret de extragere a culorii unui pixel si o atribuie variabilei color (de tip Long):

</p>
<p class="MsoNormal">Dim color as Long</p>
<p class="MsoNormal">color = GetPixel(Picture1.hDC, 100, 100)</p>
<p class="MsoNormal">

Cum setam unui pixel o anumita culoare ? Simplu, folosind functia API, SetPixel. Cum functioneaza ea ? La fel ca cea de mai sus, spre exemplu: Call SetPixel(Picture1.hDC, 100, 100, color), unde color este culoarea care vrem sa ii fie atribuita pixelului de coordinate (100, 100) din imaginea Picture1.

2. Cum extragem R, G, B dintr-un ColorRef (dintr-o culoare) ? Urmatorul cod sursa face exact acest lucru, sa-l vedem si analizam (bineinteles, eu am exemplificat pana acum codurile, folosind un modul in care am adaugat functiile API. Un modul se adauga in felul urmator: Project -> Add Module -> New (Module) -> Open):

</p>
<p class="MsoNormal">Dim color as Long</p>
<p class="MsoNormal">color = GetPixel(Picture1.hDC, 100, 100)</p>
<p class="MsoNormal">Dim R as Integer</p>
<p class="MsoNormal">Dim G as Integer</p>
<p class="MsoNormal">Dim B as Integer</p>
<p class="MsoNormal">R = <span> </span>color Mod 256</p>
<p class="MsoNormal">G= (color \ &amp;H100) Mod 256</p>
<p class="MsoNormal">B = (color \ &amp;H10000) Mod 256</p>
<p class="MsoNormal">

 

Asa extragem R, G, B dintr-o culoare. Acum sa creem o aplicatie care transforma o imagine (imagine color, bineineles), in una alb-negru (cand spun imaginea alb-negru ma refer la GrayScale, adica la orice nuanta de gri, culorile obtinute prin amestecul non-culorilor alb si negru). GrayScale se obtine atribuind lui R valoarea (R+G+B) \ 3, lui G valoarea (R+G+B) \ 3, iar lui B valoarea (R+G+B) \ 3. Deci, va trebuie sa avem pe Formular 3 butoane, un Common Dialog(care il introducem prin: Project -> Components -> Microsoft common Dialog Control 6.0 -> Ok [acesta ne va folosi pentru a incarca imaginea din calculator]), si un PictureBox, cu denumirea Picture1.De mentionat ca trebuie sa aveti adaugat un modul in care sa declarati functiile API: GetPixel si SetPixel. Imaginea urmatoare sper sa va clarifice lucrurile in minte despre GrayScale:

Inainte [Fara GrayScale] -> Dupa [Cu GrayScale]

Sa transcriem codul:

Codul pentru Load Image, pus pe butonul cu denumirea Command1:

</p>
<p class="MsoNormal">Dim filelocation As String</p>
<p class="MsoNormal">CommonDialog1.Filter = "All images"</p>
<p class="MsoNormal">CommonDialog1.ShowOpen</p>
<p class="MsoNormal">filelocation = CommonDialog1.FileName</p>
<p class="MsoNormal">Picture1.Picture = LoadPicture(filelocation)</p>
<p class="MsoNormal"><span> </span>

Codul pentru butonul, care daca apasam pe el, se produce transformarea in alb-negru a imaginii incarcate anterior:

</p>
<p class="MsoNormal">Dim a As Integer</p>
<p class="MsoNormal">Dim b As Integer</p>
<p class="MsoNormal">Dim color As Long</p>
<p class="MsoNormal">Dim colorR As Integer</p>
<p class="MsoNormal">Dim colorG As Integer</p>
<p class="MsoNormal">Dim colorB As Integer</p>
<p class="MsoNormal">Dim pixel As Integer</p>
<p class="MsoNormal">For a = 1 To 1000</p>
<p class="MsoNormal">For b = 1 To 1000 ‘aceste 2 Foruri parcurg imaginea</p>
<p class="MsoNormal">color = GetPixel(Picture1.hDC, a, b)</p>
<p class="MsoNormal">colorR = color Mod 256</p>
<p class="MsoNormal">colorG = (color \ &amp;H100) Mod 256</p>
<p class="MsoNormal">colorB = (color \ &amp;H10000) Mod 256</p>
<p class="MsoNormal">pixel = (colorR + colorG + colorB) \ 3</p>
<p class="MsoNormal">Call SetPixel(Picture1.hDC, a, b, RGB(pixel, pixel, pixel))</p>
<p class="MsoNormal">Next</p>
<p class="MsoNormal">Next</p>
<p class="MsoNormal">

Codul pentru butonul de iesire:

</p>
<p class="MsoNormal">Unload Me</p>
<p class="MsoNormal">

 

Cam atat pentru acest tutorial ! Bafta, si nu uitati ! Mai treceti pe la https://vladii.wordpress.com deoarece in fiecare zi acest site va fi updatat cu noi tutoriale facute de mine ! Salut !

 

Bibliografie:

</p>
<p class="MsoNormal"><a href="http://www.devx.com/vb2themax/Tip/18427">http://www.devx.com/vb2themax/Tip/18427</a></p>
<p class="MsoNormal">

 

Adevaratul inteles al: „Imi instalez driverul de la..”

Ok, un nou micut „tutorial” (daca il pot denumi asa :-)) ). De curand, m-am confruntat cu o problema, cand incercam sa scriu un cod in ASM. Vroiam sa setez ceasul la ora 00:00:00 din Windows, folosind BIOSul. Nicio problema, aveam interruptul necesar, dar programul, cand il rulam, imi dadea eroare grava (sau eroare fatala). Avand proasta inspiratie sa nu-l intreb pe Shocker, am cautat pe Google, dar nu am gasit rezolvarea la problema mea. De unde am plecat, pana unde am ajuns este cale lunga ^_^

Shocker mi-a explicat ca eu nu pot accesa direct din windows BIOSul prin intermediul interrupturilor, deoarece eu rulez in UserMode (adica ? Cand misc mouseul pe desktop, accesez un fisier si altele, folosesc modul Userului). In UserMode nu avem acces direct la memoria kernelului, la resursele fizice ale calculatorului. Sa va arat o imagine (preluata de pe wikipedia.org) care sper sa fie edificatoare:

Rings

Clar, noi, cand rulam in User Mode suntem mai putini privilegiati, dar asta ne face si ceva mai secure. De ce ? In UserMode (Ring 3), o eroare se manifesta printr-o eroare predefinita a windowsului, pe cand in KernelMode (cel mai privilegiat, Ring 0), erorile se manifesta prin Blue Screenuri si Restarturi (ceea ce este cam neplacut ;)) )

Sa revenim. Deci ? Am precizat ca interrupturile nu pot fi rulate „simplu si direct” din UserMode (deoarece nu avem acces la resursele fizice ale computerului), atunci unele programe cum fac asta ? Ma refer, spre exemplu, la imaginea de pe desktop (care apare, in special, datorita placii video => direct din windows se poate avea acces la resursele fizice ale calculatorului). Cum, cum, cum, aceasta e intrebarea ? :-))

Aceste aplicatii comunica cu resursele fizice ale calculatorului prin intermediul unui [b]Driver[/b]. Deci, practic, ce este un driver ? Este o aplicatie, care ruleaza in Kernel Mode [ring 0 – modul cel mai privilegiat]. Ca o mica schema, „comunicarea” dintre acestea se realizeaza astfel: aplicatia [ruleaza in usermode ring 3 – windows] -> driver [ruleaza in kernelmode ring 0] -> resursele fizice ale computerului.

Cum comunica ? Aplicatia care ruleaza in usermode apeleaza anumite rutine(sau subrutine -> http://en.wikipedia.org/wiki/Subroutine) in driver, iar driverul comunica mai departe cu componenta hardware prin [b]computer bus[/b] (http://en.wikipedia.org/wiki/Computer_bus) !

Acum poate va intrebati, ok, dar eu am imagine pe desktop chiar daca nu am instalat driverul (software) de la placa video. Pai aveti, dar nu se foloseste placa video la capacitatile ei maxime, pentru ca si Windowsul are anumite drivere (pentru placa video, placa de sunet, etc.) incorporate, insa nu poate folosi toate modelele la capacitatile maxime, de aceea este nevoie de softwareul special realizat de firmwareul placii dumneavoastra !!

Cam atat am avut de spus ! Astept critici de la voi, deoarece nici eu nu sunt prea sigur de ceea ce am scris si vreau sa imi fixez cat mai bine aceste lucruri in minte, mai ales ca in viitor (cateva luni de invatat) vreau sa ma apuc de programare de drivere.

Bibliografie:

http://en.wikipedia.org/wiki/Ring_(computer_security)
http://en.wikipedia.org/wiki/Device_driver
http://en.wikipedia.org/wiki/Subroutine
http://en.wikipedia.org/wiki/Computer_bus

Al vostru, vladii !!!

Despre ShellCoding

Cum obtinem un ShellCode?

Ce este un ShellCodingul ? In principiu, cand ne gandim la ShellCoding ne gandim la orice cod care returneaza un remote shell cand este executat. Intelesul cuvantului ShellCode a evoluat, acum intelegand prin acest cuvant orice byte code care este introdus intr-un exploit pentru a indeplini o anumita sarcina. ATENTIE! Un shellcode nu trebuie sa contina Null Bytes si este ideal ca acesta sa aiba o dimensiune in bytes cat mai mica. Un alt amanunt destul de important este faptul ca in acest tutorial voi prezenta doar Window ShellCoding, nu si Linux ShellCoding. Multumiri multe ii sunt aduse lui SlicK.
Sa incepem! Toolurile de care aveti nevoie pe parcursul tutorialului:
1. NASM [Compilarea programelor ASM o vom face in NASM]
Download Link: [url] http://nasm.sourceforge.net/ [/url]
2. ALINK [Programul .exe il vom realize folosind acest tool]
Download Link: [url] http://alink.sourceforge.net/download.html [/url]
3. ARWIN [Cu acest program C, care trebuie compilat, putem gasi adresele functiilor API in respectivul dll in care ele se afla]
Download Link: [url] http://www.vividmachines.com/shellcode/arwin.c [/url]
4. W32DASM [Dezasamblator, va recomand versiunea 8.93]
5. WDHEX [Un program util care copiaza ShellCodeul dintr-o lista .alf salvata anterior cu W32DASM].
Download Link: [url] http://rapidshare.com/files/46936025/wdhex.exe.html [/url]

Avand aceste tooluri si niste cunostine decente de ASM, sa vedem cum se poate extrage ShellCodeul, iar, mai apoi, sa optimizam codul ASM pentru ca ShellCodeul sa fie de dimensiune cat mai mica si sa nu contina Null Bytes (\x00).

Sa consideram un mic cod ASM, care nu face nimic altceva decat sa produca un Beep ! ATENTIE! Un amanunt destul de important pe care eu nu il voi atinge in acest tutorial [poate intr-o versiune ulterioara] este faptul ca orice program vine incarcat in decat cu kernel32.dll, deci utilizarea altor functii api din alte dlluri (user32.dll, etc.) necesita incarcarea librariei respective (2 functii API sunt foarte importante aici: LoadLibraryA si GetProcAddress). Un alt amanunt important, cand vom extrage shellcodeul, il vom extrage doar din zona ..start a programului realizat in ASM, de aceea declararea variabilelor este INTERZISA, iar importarea functiilor API deasupra acestei sectiuni este iarasi incorecta. Un astfel de exemplu de cod incorrect este urmatorul:

Cod:
%include „win32n.inc”extern SetCursorPos
import SetCursorPos user32.dll
title db „hello”,0
message db „hello world”,0


Ideea este alta, va prezint un mic cod, cum ar fi corect, apoi lasam balta aceasta idee si trecem la dezvoltarea bazelor ShellCodingului.

Cod:
segment .code USE32
..start
xor eax, eax
xor ebx, ebx
xor ecx, ecx
xor edx, edx
jmp short functie ; sari la labelul @functie
functie2:
pop eax ;scoate din stack ultima valoare si baga in eax
mov byte [eax+10], dl ;scriem 10 caractere: user32.dll, ignoram N
mov ebx, 0x77e7d961 ;adresa functiei LoadLibraryA
push eax ;echivalent cu push user32.dll
call ebx ;callam LoadLibraryA
mov ecx, eax
xor eax, eax
jmp short functie3
functie4:
pop eax
mov byte [eax+12], dl
mov ebx, 0x77e7b332 ;adresa functiei GetProcAddress
push eax
push ecx
call ebx
restul:
push byte 1
push byte 1
call eax ;SetCursorPos
mov ebx, 0x77e798fd ;adresa functiei ExitProcess
push byte 1
call ebx
functie:
call functie2
db ‘user32.dllN’
jmp short functie2 ; sari (intoarce-te la labelul @functie2)
functie3:
call functie4
db ‘SetCursorPosN’


Daca am fi realizat un cod in FASM care sa faca acest lucru era mult mai simplu, deoarece am fi putut utiliza direct variabilele, iar in NASM nu putem scrie ceva genul: push ceva Call [functieapi], decat daca ceva este numar. De aceea, inainte de a executa labelul specific unei functii API am sarit la un alt label care calleaza labelul initial, dar in care se afla un element foarte important: db ‘SetCursorPosN’, unde SetCursorPos este numele “variabilei” care trebuie utilizata, iar N vine de la Null Byte. Traind cu speranta ca ati inteles ceva din codul de mai sus, trec la lucruri mai simple. Sa consideram micul nostru cod care face Beep.

Cod:
;beep.asm
segment .code USE32
..start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx
mov ebx, 0x77eac910 ;adresa functiei Beep din kernel32.dll
mov ax, 750 ;frecventa sunetului in Hertzi
mov cx, 3000 ;durata Beepului
push eax
push ecx
call ebx ;Callam functia Beep
mov ebx, 0x77e798fd ;adresa functiei ExitProcess din kernel32.dll
mov ax, 1
push eax
call ebx


Mai multe despre functia api Beep gasiti aici: [url] http://msdn2.microsoft.com/en-us/library/ms679277.aspx [/url].
Un alt lucru care trebuie sa vi-l spun este faptul ca in Windows, un cod NASM incepe cu segment .code USE32 ..start:, pe cand pe Linux incepe: [SECTION .text] global _start _start:
ATENTIE! Adresele functiilor api in dllurile lor pot diferi de la un utilizator de Windows la altul, datorita versiunii de Windows, versiunii Service Packului si datorita diferitelor updateuri care se aduc zi de zi. De aceea vom utiliza ARWIN pentru aflarea adreselor functiilor in dllurile din windowsul nostru.
Intram in fisierul in care am salvat arwin.exe folosind CMD ! Dupa ce am ajuns, tastam urmatoarea comanda: arwin.exe NumeleDllului NumeleFunctiei. Spre exemplu, putem introduce: arwin.exe kernel32.dll Beep. Poate imaginea urmatoare va fi de folos:

Dupa ce inlocuim in codul de mai sus adresele dumneavoastra ale functiilor API, poate incepe distractia! Copiati codul [cu tot cu modificarea dumneavoastra] in notepad si apoi salvati cu extensia .asm (File -> Save As -> Filename: beep.asm). Deci fisierul nostru se va numi beep si va avea extensia .asm. Ideal ar fi sa salvati toate toolurile care le-am prezentat mai sus [compilate-cele care au nevoie de asa ceva] impreuna cu beep.asm intr-un folder. Acum deschideti iar CMD pentru a compila codul ASM si pentru a-l face .exe ! Intrati din cmd in folderul in care ati salvat toate cele de mai sus. Apoi tastati urmatoarea comanda: nasmw.exe -fobj beep.asm. Asa verificam daca programul are erori, daca nu are, putem trece mai departe la crearea executabilului. Introduceti in CMD: alink -c -oPE -subsys gui beep, iar daca operatiunea a decurs fara nicio problema, atunci puteti rula executabilul tastand in CMD: beep ! Sper ca imaginea urmatoare sa fie edificatoare:

Acum ca am reusit crea executabilul, sa extragem ShellCodeul. Pentru aceasta, deschideti .exele cu w32dasm.

In imaginea de mai sus, observam ca sunt prezente 3 coloane: adresele, shellcodeul si codul ASM (de la stanga la dreapta). Putem sa extragem acest shellcode manual, adica, spre exemplu, din 31C031DB obtinem: “\x31\xC0\x31\xDB”, sau folosind wdhex, care extrage ShellCodeul automat pentru noi. Pentru a face acest lucru, trebuie mai intai sa salvam ceea ce am vazut in W32DASM. Cum facem asta ? Simplu: File -> Save Disassembly Text File and Create Project File -> FileName: beep.ALF -> Ok. Atentie, fisierul trebuie sa aiba extensia .ALF, nu .ELF (care este specific Linuxului). Intrati in CMD in foldeul in care ati salvat beep.alf si in care [sper] aveti si wdhex.exe, si tastati urmatoarea comanda: wdhex beep.alf ! Programul va va arata shellcodeul deja extras.

In concluzie, shellcodeul nostrum este urmatorul:

Cod:
char shellcode[]=
„\x31\xC0\x31\xDB\x31\xC9\xBB\x10\xC9\xEA\x77\x66\xB8\xEE\x02”
„\x66\xB9\xB8\x0B\x50\x51\xFF\xD3\xBB\xFD\x98\xE7\x77\x66\xB8”
„\x00\x00\x50\xFF\xD3”;


Cum putem verifica daca ShellCodeul functioneaza ? Foarte simplu! Sa consideram urmatorul “schelet” al unui program in C:

Cod:
/*shellcodetest.c*/
char code[] = „bytecode will go here!”;
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) code;
(int)(*func)();
}


Dumneavoastra trebuie sa inlocuiti „bytecode will go here!” cu shellcodeul dumneavoastra, sa compilati programul, sa-l faceti .exe, iar apoi sa vedeti daca functioneaza.

Optimizarea ShellCodeului
Cum am precizat la inceput, este ideal ca ShellCodeul sa nu contina Null Bytes, dar, din pacate, codul nostru contine deja 2 nullbytes (“\x00\x00”). Ideea este sa verificam de unde acestia provin si sa incercam, daca se poate, sa ii eliminam. Daca ne uitam in imaginea din W32DASM, NullBytes provin de pe linia mov ax, 1. Se stie ca registrul eax are 3 parti -> ax, ah, al. al reprezinta partea inferioara a registrului. Sa incercam sa schimbam linia mov ax, 1 cu mov al, 1. Pe langa faptul ca vom scapa de NullBytes, programul va avea 32 de bytes !!!

Cam atat am avut de prezentat, o sa rectific eventualele greseli in caz ca acestea exista (si daca exista, imi cer din tot sufletul iertare pentru ele, mai ales ca am incercat sa creez ceva util si folositor). Asa ca tineti aproape!

Linkuri Utile:
– [url] http://www.vividmachines.com/shellcode/shellcode.html [/url]
– [url] http://en.wikipedia.org/wiki/Shellcode [/url]
– [url] http://www.bradleybeast.com/content/view/84/ [/url]

Enjoy it!

@vladii 2007