Muisti ja .data-segmentti
Muisti ja .data-segmentti
Rekisterit ovat nopeita mutta vähissä. Oikeat ohjelmat tarvitsevat myös pysyvämpää muistia: taulukoita, merkkijonoja, vakioita. Tätä varten ohjelmassa on .data-segmentti, eli muistialue, johon ohjelma määrittelee alkuarvoiset muuttujansa.
![.data-segmentin asettuminen muistiin, dword-taulukon osoitteet ja yleinen [kanta + indeksi × skaalaus + siirto] -osoitteenmuodostus.](https://cdn.sanity.io/images/3unppnk2/ha-content/5b04505d60c7b7a0e41e202def77985fcb93253b-1536x1024.png?w=3840&q=75&fit=clip&auto=format)
Datan määrittely: db, dw, dd
Datan määrittelykäskyt nimetään datan koon mukaan:
db: yksi tavu (8 bittiä), arvoväli 0..255 tai -128..127.dw: sana eli kaksi tavua (16 bittiä).dd: kaksoissana eli neljä tavua (32 bittiä). Tämä on yleisin tällä kurssilla.
Määrittelyn vasemmalla puolella oleva nimi on label: viite muistipaikkaan, jossa data sijaitsee. Labelin avulla viittaat dataan koodissasi.
Datan lukeminen ja kirjoittaminen
Hakasulkeet [ ] merkitsevät "hae muistista tästä osoitteesta". Ilman hakasulkeita arvo on osoite itse, hakasulkeiden kanssa se on muistissa oleva sisältö.
Koon ilmaisu (DWORD, WORD, BYTE) kertoo prosessorille, kuinka monta tavua luetaan tai kirjoitetaan. 32-bittisille luvuille käytä DWORDia, 16-bittisille WORDia ja yksittäisille tavuille BYTEa.
Taulukon läpikäynti
Taulukko on peräkkäin muistissa olevia samankokoisia alkioita. Niitä käydään läpi laskemalla osoitin alkion kokoon perustuen. DWORD-taulukon alkio i sijaitsee osoitteessa taulukon_alku + i * 4.
Tässä esimerkissä osoittimen laskenta tapahtuu suoraan käskyssä. [taulukko + ECX*4] on x86:n osoitteen muodostus: ottaa labelin osoitteen, lisää ECX-rekisterin arvon kerrottuna neljällä ja käyttää tulosta muistiosoitteena.
Osoitteenmuodostuksen kokoonpano
x86 tukee yleisesti monimutkaisempaa osoitteenmuodostusta muodossa:
1[ kanta + indeksi * skaalaus + siirto ]
2
3esim:
4[EBX] ; pelkkä kantarekisteri
5[EBX + 8] ; kanta + vakiosiirto
6[EBX + ECX*4] ; kanta + skaalattu indeksi
7[label + ECX*4] ; label kantana + skaalattu indeksiSkaalaus on yleensä alkion koko: byte-taulukoille 1, word-taulukoille 2, dword-taulukoille 4. Tämä yhdistelmä on hyvin yleinen reverse engineeringin näkymässä ja kannattaa oppia tunnistamaan.
Yksittäisten tavujen ja merkkijonojen lukeminen
Merkkijonot ovat assemblyssä yksinkertaisesti taulukoita tavuja. ASCII-arvoja vastaavat luvut tallennetaan tavu kerrallaan.
AL on EAX-rekisterin alin tavu. Kun luet yhden tavun muistista, kohteena pitää olla 1-tavuinen rekisteri (AL, BL, CL, DL) tai vastaavasti BYTE-kokoinen muistipaikka.
Yleisiä sudenkuoppia
- Ilman koon ilmaisua (DWORD/WORD/BYTE) prosessori ei tiedä, montako tavua luetaan. Lisää se eksplisiittisesti, jos saat oudoja tuloksia.
- Skaalaajan (1, 2, 4) on vastattava alkion tavukokoa. 4 byte-taulukolle hyppää neljän alkion yli kerralla.
- Indeksi alkaa nollasta, ei yhdestä. Taulukon viimeinen alkio on indeksillä (pituus − 1).
- Jos ohjelma kaatuu "Invalid dereference" -virheeseen, olet luultavasti laskenut osoitteen yli muistialueen reunan.
Hakkeroinnin oppiminen alkaa tästä
Sadat interaktiiviset kurssit, virtuaalilabrat ja CTF-haasteet selaimessasi. Aloita ilmainen kokeilu ilman korttitietoja.