kuinka tärkeää on nykyään varmistaa, että kaikilla DLL: lläni on ei-ristiriitaiset perusosoitteet?
Raymond
tammikuun 20., 2017
ennen vanhaan sinua kehotettiin muun muassa tasapainottamaan DLL: si niin, että niillä kaikilla oli ylitsepääsemätön osoitealue, jolloin vältyttiin ajonaikaisen uudelleensijoittamisen kustannuksilta. Onko tämä vielä tärkeää nykyään?
tämä tilanne on jälleen yksi osoitus siitä, kuinka tärkeää on, että hyvät neuvot tulevat perusteluineen, jotta voi tietää, milloin niistä tulee huonoja neuvoja.
perustelut uudelleenasettamiselle ovat seuraavat: Jos DLL Ladataan haluamassaan perusosoitteessa, kuvan voi ladata suoraan background Storesta ilman korjauksia. Tämä tarkoittaa, että sivut voidaan jakaa prosessien kesken, koska jokainen prosessi saa identtisen kopion. (Jakaminen tietysti loppuu, kun joku kirjoittaa sivulle ja tekee kopiostaan erilaisen kuin jaettu kopio.)
jos DLL: ää ei voi ladata haluamaansa osoitteeseen, levykuva siirretään, ja koko siirretty DLL on nyt sivutiedoston tukena.1 Tämä on suhteellisen kallis operaatio, Koska DLL on luettava levyltä ja korjattava, ja sivutiedostolle on aiheutunut toimitusmaksu sen varmistamiseksi, että korjattujen sivujen kirjoittamiseen on tilaa. Lisäksi, Jos kaksi prosessia siirtää DLL ja sattumalta siirtää ne samaan paikkaan, Windows NT ei yritä jakaa siirrettyjä kuvia. Sivutiedostossa on useita kopioita.
tämän dynaamisen uudelleensijoittamisen kustannukset pyritään välttämään. Kutsutaan tätä ” siirtorangaistukseksi.”
Enter ASLR.
ASLR aiheuttaa DLL-tiedostojen lataamisen pseudo-satunnaisiin osoitteisiin. Näin ollen DLL latautuu ensisijaiseen kantaosoitteeseensa vain, jos kyseessä on hämmästyttävä yhteensattuma.
Okei, joten palataan perusteluihin ja katsotaan, päteekö se vielä.
aiheutuuko DLL: n lataaminen pois sen ensisijaisesta perusosoitteesta uudelleensijoitusseuraamus? Jos ajattelet sitä, ASLR tarkoittaa, että DLL ei koskaan lataudu haluamaansa osoitteeseen, mutta näimme myös, että ydin tekee mukautuksia tähän niin, että ASLR: lle altistetut DLL: t voivat edelleen jakaa sivuja, ja se tekee niin pakottamatta koko DLL: n siirtämistä alkuperäiseen kuormitukseen. Joten ei ole siirtorangaistus tapauksessa, jossa ASLR siirsi DLL: n.
mutta mitä jos DLL siirretään jostain muusta syystä? Voi esimerkiksi olla, että ASLR: n valitsema perusosoite ei ole prosessissa käytettävissä, koska prosessi on jo varannut jotain muuta kyseiseen sijaintiin. Siinä tapauksessa, perinteinen siirto on tapahduttava, ja maksat siirtorangaistus.
Ah, mutta asia on näin: Kun DLL Ladataan, ASLR määrittää perusosoitteen satunnaisesti käytettävissä olevien perusosoitteiden joukosta, joita ei ole vielä käytetty.2 joten et aio päästä” ASLR-chosen base address is not available ” skenaario, koska ASLR valitsee DLL: n base-osoitteen joukosta base-osoite, jotka ovat saatavilla.3
okei, niin voi vielä joutua konfliktitilanteeseen, mutta sen eteen pitää tehdä tosissaan töitä. Voit esimerkiksi ladata DLL: n yhteen prosessiin ja saada ASLR-määritetyn perusosoitteen. Tämän jälkeen käynnistät toisen prosessin, varaat muistin tarkoituksellisesti kyseiseen osoitteeseen (pakottaaksesi törmäyksen) ja lataat sitten DLL: n. Tässä tapauksessa, siellä on Uudelleensijoitus, koska olet kyykyssä paikka, jossa ASLR halusi laittaa DLL. Mutta tämä ei ole huonompi kuin mitä sinulla oli ennen ASLR: vuonna pre-ASLR maailmassa, kyykky on DLL ensisijainen pohja osoite olisi pakottanut uudelleensijoittaminen rangaistus joka tapauksessa.
niin, katsotaan mikä tarina on. Tasapainottaako vai ei?
ASLR: n läsnä ollessa DLL: n uudelleenasettamisella ei ole vaikutusta, koska ASLR aikoo joka tapauksessa sivuuttaa perusosoitteesi ja siirtää DLL: n pseudo-satunnaiseen sijaintiinsa.
Mind you, vaikka rebasing ei vaikuta, se ei myöskään satu.
jos olet järjestelmässä, jossa ei ole ASLR: ää (joko siksi, että se on ASLR: ää edeltänyt tai koska ASLR on jostain syystä poistettu käytöstä), uudelleenasennus auttaa, perinteisistä syistä.
järjestelmiä, joissa ei ole ASLR: ää, on nykyään todella vaikea löytää, joten uusiminen ei hyödytä valtaosassa tapauksista. Mutta että häviävän pieni osa tapauksista, joissa sinulla ei ole ASLR, sitten rebasing auttaa.
johtopäätös: varmuuden vuoksi ei ole pahitteeksi, mutta ymmärtää, että loppuratkaisu tulee olemaan äärimmäisen harvinainen. Rakenna DLL kanssa /DYNAMICBASE
käytössä (ja kanssa /HIGHENTROPYVA
hyvä toimenpide) ja anna ASLR tehdä työtä varmistaa, että ei base osoite törmäys tapahtuu. Se kattaa lähes kaikki reaalimaailman skenaariot. Jos satut pudota yksi hyvin harvinaisia tapauksia, joissa ASLR ei ole käytettävissä, niin ohjelma toimii edelleen. Se vain voi ajaa hieman hitaammin johtuen siirtorangaistus.
1 tarkemmin sanottuna kaikki sivut, jotka sisälsivät korjauksia, laitetaan sivutiedostoon. Keskustelimme tästä hienoudesta viime kerralla.
2 Okei, on kolmas tapaus, jossa ASLR: ltä on yksinkertaisesti loppunut perusosoitteet. Mutta jälleen, tämä ei ole huonompi kuin mitä sinulla oli ennen ASLR: jos loppuu pohja osoitteet, niin se on jokainen mies itselleen. Joka kerta, kun uusi DLL latautuu, ytimen on kyhättävä ympäriinsä riittävän suuren palan käytettävissä olevaa osoiteavaruutta, johon DLL voidaan ladata.
3 Tämän seurauksena ASLR tekee itse asiassa parempaa työtä yhteentörmäysten välttämiseksi kuin manuaalinen uudelleenasennus, koska ASLR voi tarkastella järjestelmää kokonaisuutena, kun taas manuaalinen uudelleenasennus edellyttää, että tiedät kaikki prosessiisi ladatut DLL: t, eikä useiden toimittajien perusosoitteiden koordinointi ole yleensä mahdollista.
Raymond Chen
Follow
Leave a Reply