OK, zakładam tu stronę Windows. Co się dzieje, kiedy załadować plik PE jest to, że ładowarka (zawarte w Ntdll) będzie wykonać następujące czynności:
- Zlokalizuj każdej z bibliotek DLL z wykorzystaniem semantyki wyszukiwania DLL (patch poziomie systemu i specyficzne), dobrze znany DLL są rodzajem zwolnione z tego
- mapie plik do pamięci (MMF), gdzie strony są kopiowanie przy zapisie (krowa),
- Traverse katalogu importu i za każdym uruchomieniu importu (rekurencyjnie) w punkcie 1.
- Dokonaj relokacji, która przez większość czasu jest tylko bardzo ograniczoną liczbą podmiotów, ponieważ sam kod jest niezależny od kodu (PIC)
- (IIRC) załatać EAT od RVA (względny wirtualny adres) do VA (wirtualny adres w bieżącym obszarze pamięci procesowej)
- Łata IAT (tabela adresów importu) w celu odniesienia do importów z ich faktycznym adresem w pamięci procesowej
- przypadku połączenia DLL
DLLMain()
do EXE tworzyć gwint początkowy, którego adres jest na wejściu pliku PE (w tym również uproszczony, ponieważ rzeczywisty adres początkowy znajduje się wewnątrz kernel32.dll procesów Win32)
Teraz podczas kompilacji kodu zależy od linkera, w jaki sposób odwołuje się funkcja zewnętrzna. Niektóre linkery tworzą stubs, więc - w teorii - próba sprawdzenia adresu funkcji przed NULL zawsze powie, że nie jest NULL. To dziwactwo, musisz wiedzieć, czy i kiedy twój linker zostanie naruszony.Inni odnoszą się bezpośrednio do wpisu IAT, w którym to przypadku adres URL funkcji bez odniesienia (myślę o opóźnionym załadowaniu) może mieć wartość NULL, a program obsługi SEH wywoła pomocnika opóźniającego ładowanie i (spróbuje) rozwiązać adres funkcji, zanim wznowi wykonywanie wskaż, że się nie udało.
W powyższy proces zaangażowanych jest wiele formalności, które uprościłem.
Istotą tego, co chciałeś wiedzieć, jest to, że w procesie mapowania dzieje jako MMF, choć można sztucznie naśladować zachowanie z przestrzeni sterty. Jednakże, jeśli pamiętasz o punkcie CoW, jest to sedno idei bibliotek DLL. Właściwie ta sama kopia (większości) stron DLL zostanie udostępniona wśród procesów, które ładują konkretną bibliotekę DLL. Strony, które nie są udostępniane, to te, do których pisaliśmy, na przykład przy rozwiązywaniu przeniesień i podobnych rzeczy. W takim przypadku każdy proces ma teraz - teraz zmodyfikowaną - kopię oryginalnej strony.
I słowo ostrzeżenia dotyczące pakerów EXE na DLL. Oni pokonują dokładnie ten mechanizm CoW, który opisałem, że alokują przestrzeń dla rozpakowanej zawartości DLL na stercie procesu, do którego ładowana jest biblioteka DLL. Tak więc, podczas gdy rzeczywista zawartość pliku jest nadal mapowana jako MMF i współużytkowana, rozpakowana zawartość zajmuje taką samą ilość pamięci dla każdego procesu ładowania biblioteki DLL zamiast jej udostępniania.
@ Mark Bessey. na poziomie maszyny :). Jak ładowarka wykonuje tę magię. Podobało mi się twoje oznaczenie i byłbym wdzięczny, gdyby mógł podać link/przykład zdekodowanego kodu m/c lub kodu asm, aby wyjaśnić bit. Nie spiesz się. :) – mahesh