hoe belangrijk is het tegenwoordig om ervoor te zorgen dat al mijn DLL ‘ s niet-conflicterende basisadressen hebben?
Raymond
20 januari, 2017
terug in de dag, een van de dingen die je werd aangespoord om te doen was rebase uw dll ‘ s, zodat ze allemaal hadden niet-overlapping adresbereiken, waardoor de kosten van runtime verhuizing te vermijden. Is dit tegenwoordig nog belangrijk?
deze situatie toont opnieuw aan hoe belangrijk het is dat goed advies met een motivering komt, zodat je kunt zien wanneer het slecht advies wordt.
de reden voor het rebasen gaat als volgt: als een DLL wordt geladen op het gewenste basisadres, dan kan de image direct vanuit de backing store worden opgeroepen zonder dat er fixups nodig zijn. Dit betekent dat de pagina ‘ s kunnen worden gedeeld tussen processen, omdat elk proces een identieke kopie krijgt. (Natuurlijk, het delen stopt zodra iemand schrijft naar de pagina en maakt hun kopie anders dan de gedeelde kopie.)
als een DLL niet kan worden geladen op het gewenste adres, dan zal de image worden verplaatst, en de gehele verplaatste DLL wordt nu ondersteund door het paginabestand.1 Dit is een relatief dure operatie, omdat de DLL moet worden gelezen van de schijf en opgeknapt, en een commit lading aan het paginabestand wordt gemaakt om ervoor te zorgen dat er ruimte is om de opgeknapte pagina ‘ s te schrijven. Bovendien, als twee processen verplaatsen van de DLL en gebeuren door een of ander toeval om ze te verplaatsen naar dezelfde plaats, Windows NT probeert niet om de verplaatste afbeeldingen te delen. Er zullen meerdere kopieën in het paginabestand.
de kosten van deze dynamische verhuizing zijn wat rebasen probeert te vermijden. Laten we dit de “verhuizing straf noemen.”
voer ASLR in.
ASLR zorgt ervoor dat de DLL ‘ s worden geladen op pseudo-willekeurige adressen. Bijgevolg zal een DLL alleen laden op het gewenste basisadres in het geval van een verbazingwekkend toeval.
Oké, dus laten we teruggaan naar de reden om te zien of het nog steeds van toepassing is.
heeft een DLL die van het gewenste basisadres wordt geladen, een verplaatsingsverplichting? Als je erover nadenkt, ASLR betekent dat geen DLL ooit laadt op het gewenste adres, maar we zagen ook dat de kernel maakt accommodaties voor dit, zodat DLL ‘s onderworpen aan ASLR nog steeds pagina’ s kunnen delen, en het doet dit zonder dat de hele DLL te worden verplaatst bij de eerste belasting. Er is dus geen delocatiestraf in het geval dat de DLL door ASLR werd verplaatst.
maar wat als de DLL om een andere reden wordt verplaatst? Het zou bijvoorbeeld kunnen zijn dat het ASLR-gekozen basisadres niet beschikbaar is in het proces, omdat het proces al iets anders toegewezen heeft op die locatie. In dat geval moet een traditionele verhuizing plaatsvinden, en u betaalt de verhuizing boete.
Ah, maar hier is het ding: wanneer een DLL wordt geladen, zal ASLR een basisadres willekeurig toewijzen uit de beschikbare basisadressen die nog niet worden gebruikt.2 dus je bent niet van plan om in de “de ASLR-gekozen basis adres is niet beschikbaar” scenario omdat ASLR kiest de basis adres van de DLL uit het basis adres dat beschikbaar zijn.3
Oké, dus je kunt nog steeds in een conflictsituatie komen, maar je moet er echt aan werken. U kunt bijvoorbeeld een DLL in één proces laden en een ASLR-toegewezen basisadres krijgen. Je start dan een tweede proces, wijst opzettelijk geheugen toe op dat adres (om de botsing te forceren), en laadt vervolgens de DLL. In dit geval zal er een verhuizing zijn omdat je gekraakt hebt op de plek waar ASLR de DLL wilde plaatsen. Maar dit is niet erger dan wat je had voor ASLR: in de pre – ASLR wereld, kraken op een DLL ‘ s voorkeur basis adres zou hebben gedwongen een verhuizing boete toch.
laten we eens kijken wat het verhaal is. Rebase of niet rebase?
in aanwezigheid van ASLR heeft het rebasen van uw dll ‘ s geen effect omdat ASLR uw basisadres toch zal negeren en de DLL zal verplaatsen naar een locatie van zijn pseudo-willekeurige keuze.
Let wel, ook al heeft rebasen geen effect, het doet ook geen pijn.
als je op een systeem zit zonder ASLR (omdat het ouder is dan ASLR, of omdat ASLR is uitgeschakeld om welke reden dan ook), dan zal rebasen helpen, om de traditionele redenen.
Let wel, systemen zonder ASLR zijn tegenwoordig erg moeilijk te vinden, dus rebasen levert in de overgrote meerderheid van de gevallen geen voordeel op. Maar in dat verdwijnend kleine percentage gevallen waar je geen ASLR hebt, dan helpt rebasen.
Conclusie: Het kan geen kwaad om te rebasen, voor het geval dat, maar begrijp dat de uitbetaling uiterst zeldzaam zal zijn. Bouw uw DLL met /DYNAMICBASE
ingeschakeld (en met /HIGHENTROPYVA
voor een goede maatregel) en laat ASLR het werk doen om ervoor te zorgen dat er geen basisadresbotsing optreedt. Dat zal vrijwel alle scenario ‘ s in de echte wereld omvatten. Als je toevallig te vallen in een van de zeer zeldzame gevallen waarin ASLR is niet beschikbaar, dan is uw programma zal nog steeds werken. Het kan alleen een beetje langzamer lopen als gevolg van de verhuizing boete.
1 om precies te zijn, alle pagina ‘ s die fixups bevatten worden in het paginabestand gezet. We bespraken dit fijnere punt de vorige keer.
2 Oké, er is een derde geval, dat is waar ASLR gewoon geen basisadressen meer heeft. Maar nogmaals, dit is niet erger dan wat je voor ASLR had: als je geen basisadressen meer hebt, dan is het ieder voor zich. Elke keer dat een nieuwe DLL wordt geladen, moet de kernel een groot genoeg deel van de beschikbare adresruimte verzamelen om de DLL in te laden.
3 hierdoor vermijdt ASLR botsingen beter dan handmatig rebasen, omdat ASLR het systeem als geheel kan bekijken, terwijl handmatig rebasen vereist dat u alle DLL ‘ s kent die in uw proces worden geladen, en het coördineren van basisadressen tussen meerdere leveranciers over het algemeen niet mogelijk is.
Raymond Chen
Volgen
Leave a Reply