Hvor viktig er det i dag å sikre at alle Mine Dller har ikke-motstridende baseadresser?
Raymond
20. januar, 2017
Tilbake på dagen var en av tingene du ble oppfordret til å gjøre, rebase Dllene dine slik at de alle hadde ikke-overlappende adresseområder, og dermed unngår kostnadene ved runtime-flytting. Er dette fortsatt viktig i dag?
denne situasjonen er en annen demonstrasjon av hvordan det er viktig for gode råd å komme med en begrunnelse, slik at du kan fortelle når det blir dårlig råd.
begrunnelsen for rebasing går slik: Hvis EN DLL er lastet på sin foretrukne baseadresse, kan bildet veksles direkte fra backing store uten å kreve noen rettelser. Dette betyr at sidene kan deles mellom prosesser, siden hver prosess får en identisk kopi. (Selvfølgelig stopper delingen når noen skriver til siden og gjør kopien forskjellig fra den delte kopien.)
hvis EN DLL ikke kan lastes på sin foretrukne adresse, da bildet vil bli flyttet, og hele flyttet DLL er nå støttet av sidefilen.1 Dette er en relativ dyr operasjon, SIDEN DLL må leses fra disk og festes, og en forplikte kostnad til sidefilen påløper for å sikre at det er plass til å skrive de faste sidene. Videre, hvis to prosesser flytter DLL og skje ved en tilfeldighet for å flytte dem til samme sted, Forsøker Windows NT ikke å dele de flyttede bildene. Det vil være flere kopier i sidefilen.
kostnaden for denne dynamiske flyttingen er hva rebasing forsøker å unngå. La oss kalle dette ” flytting straff.”
Skriv INN ASLR.
aslr fører Til At Dllene lastes på pseudo-tilfeldige adresser. Følgelig vil EN DLL laste på sin foretrukne baseadresse bare i tilfelle av en forbløffende tilfeldighet.
Ok, så la oss gå tilbake til begrunnelsen for å se om den fortsatt gjelder.
medfører EN DLL som lastes bort fra sin foretrukne baseadresse en flyttestraff? Hvis DU tenker på DET, betyr ASLR at INGEN DLL noensinne laster på sin foretrukne adresse, men vi så også at kjernen gjør innkvartering for dette slik at Dller utsatt FOR ASLR fortsatt kan dele sider, og det gjør det uten å tvinge HELE DLL til å bli flyttet på første belastning. Så det er ingen flyttingstraff i tilfelle HVOR DLL ble flyttet AV ASLR.
men hva om DLL er flyttet av en annen grunn? For eksempel kan DET være at den aslr-valgte baseadressen ikke er tilgjengelig i prosessen, fordi prosessen allerede har tildelt noe annet på den plasseringen. I så fall må en tradisjonell flytting finne sted, og du betaler flyttestraffen.
Ah, Men Her er tingen: når EN DLL er lastet, vil ASLR tildele en baseadresse tilfeldig blant de tilgjengelige baseadressene som ikke allerede er i bruk.2 Så du kommer ikke til å komme inn i scenariet “aslr-valgt baseadresse er ikke tilgjengelig” fordi ASLR velger DLS baseadresse blant baseadressen som er tilgjengelig.3
Ok, så du kan fortsatt komme inn i en konfliktsituasjon, men du må virkelig jobbe med det. For eksempel kan du laste INN EN DLL i en prosess, og få EN aslr-tildelt baseadresse. Du starter deretter en annen prosess, tildeler med vilje minne på den adressen (for å tvinge kollisjonen), og laster DERETTER DLL. I dette tilfellet vil det bli en flytting fordi du huket på stedet DER ASLR ønsket Å sette DLL. Men dette er ikke verre enn hva du hadde FØR ASLR: i pre-ASLR verden, huk på EN DLL foretrukne base adresse ville ha tvunget en flytting straff uansett.
så, la oss se hva historien er. Å rebase eller ikke å rebase?
i nærvær AV ASLR har rebasing DLLs ingen effekt fordi ASLR kommer til å ignorere din baseadresse uansett og flytte DLL til et sted med pseudo-tilfeldig valg.
Husk deg, selv om rebasing ikke har noen effekt, gjør det heller ikke vondt.
hvis du er på et system uten ASLR (enten fordi DET foregår ASLR, eller fordi ASLR er deaktivert uansett grunn), vil rebasing hjelpe, av tradisjonelle grunner.
Husk at systemer uten ASLR er veldig vanskelig å finne i dag, så rebasing gir ingen fordel i det overveldende flertallet av tilfellene. Men i den forsvinnende lille prosentandelen tilfeller der DU ikke har ASLR, hjelper rebasing.
Konklusjon: det gjør ikke vondt å rebase, bare i tilfelle, men forstå at utbetalingen vil være ekstremt sjelden. Bygg DIN DLL med /DYNAMICBASE
aktivert (og med /HIGHENTROPYVA
for godt mål) og la ASLR gjøre arbeidet med å sikre at ingen grunnadressekollisjon oppstår. Det vil dekke stort sett alle de virkelige scenariene. Hvis du tilfeldigvis faller inn i et av de svært sjeldne tilfellene DER ASLR ikke er tilgjengelig, vil programmet ditt fortsatt fungere. Det kan bare kjøre litt tregere på grunn av flytting straff.
3 SOM et resultat gjør ASLR faktisk en bedre jobb med å unngå kollisjoner enn manuell rebasing, siden ASLR kan se systemet som helhet, mens manuell rebasing krever at du kjenner alle Dllene som er lastet inn i prosessen din, og koordinering av baseadresser på tvers av flere leverandører er vanligvis ikke mulig.
Raymond Chen
Følg
Leave a Reply