|
DLL을 만드는 이유중 하나는,
동일 DLL이 차지하는 메모리 공간을 서로 다른 프로세스들이 공유할 수 있기 때문이다. 각 프로세스들이 나름대로의 가상주소 위치로 DLL 코드를 매핑하겠지만 그 가상주소들은 동일한 실 메모리 페이지들을 가리킨다..?? 이렇게 생각하고 있었는데, 실상은 좀 다른 모양이다. Windows DLL은 PE 헤더에 (링크할때 설정 가능한) prefered base address를 담고 있는데, 이 가상메모리 주소로 로드되는 경우에만 다른 프로세스와 메모리 페이지가 공유 가능한 듯 하다. DLL 로드할때 해당 베이스주소가 이미 다른 DLL 등에 의해 사용중이면 어쩔 수 없이 다른 가상주소 위치로 읽어들이는 재배치(relocation)가 일어나게 되고 이 경우 점프명령어 주소수정이 일어나는 코드페이지들은 CoW(Copy on Write) 프로텍션에 의해 새 물리페이지로 복사이전 되므로 해당 코드페이지들은 더이상 타 프로세스와 공유되지 않음. (Windows에서 이렇다는 것이고, 아마 Linux에서는 .so(Shared Object)를 만들때 PIC로 만들어지므로 프로세스마다 서로 다른 가상주소로 매핑된 .so 코드 페이지들도 서로 공유되는 모양이다. 참고: https://en.wikipedia.org/wiki/Position-independent_code position-independent code (PIC) or position-independent executable (PIE) is a body of machine code that, being placed somewhere in the primary memory, executes properly regardless of its absolute address. PIC is commonly used for shared libraries, so that the same library code can be loaded in a location in each program address space where it does not overlap with other memory in use (for example, other shared libraries)) 따라서 DLL을 링크할때 다른 DLL들과 충돌하지 않도록 적절히 베이스주소를 설정해줘야 메모리 공유가 이뤄지겠는데 문제는, 아무 생각없이 사용자 DLL을 만들어 링크하면 베이스 주소가 기본값(0x10000000)으로 설정되므로 사용자 DLL이 여러개 로드될 경우 재배치가 일어날 수밖에 없다는 것. Modify the Base Addresses for a DLL Files Series https://www.codeproject.com/Articles/35829/Modify-the-Base-Addresses-for-a-DLL-Files-Series A Dynamic-link library created in Microsoft Visual C++ has default base address 0x10000000 (Visual C# has default base address 0x400000). That means, when the process starts, the system loader tries to load the DLL to this address in the process memory. However, if a number of DLLs have the same base address, only one of them is loaded to its default address. For all other DLLs, the loader makes the relocation: changes the memory addresses in DLL commands according to the new base address where the DLL is loaded. This process is also known as DLL collisions. Loading Applications and DLLs https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection DLLs are created with a default base address. Every process that uses a DLL will try to load the DLL within its own address space at the default virtual address for the DLL. If multiple applications can load a DLL at its default virtual address, they can share the same physical pages for the DLL. If for some reason a process cannot load the DLL at the default address, it loads the DLL elsewhere. If relocated DLLs cannot share pages, then doesn’t ASLR cause all pages to be non-shared? https://devblogs.microsoft.com/oldnewthing/20160413-00/?p=93301 구식 DLL들은 재배치(relocate)될 경우 프로세스간 메모리 공간 공유가 이뤄지지 않는다. 그럼 ASLR 켜진 상태로 링크된 DLL들은 로드할 때 적재주소가 랜덤화되므로 공유가 불가능한가 하면, 그렇지 않다. DLL을 최초 로드할 때 랜덤화된 상태가 이후 다른 프로세스에서 DLL을 로드할 때 재활용되면서 메모리페이지가 공유되는 모양이다. The solution is that when a DLL is loaded, ASLR chooses a random destination address, but it then remembers that address for future use, and if another process loads the DLL, the kernel will try to use the same destination address for the DLL in that other process. This means that if two processes load a DLL, that DLL will probably get the same destination address in both processes, which establishes one of the prerequisites for sharing. Six Facts about Address Space Layout Randomization on Windows https://www.fireeye.com/blog/threat-research/2020/03/six-facts-about-address-space-layout-randomization-on-windows.html
|
카테고리
이전블로그
최근 등록된 덧글
이곳을 기억하고 있군요...
by 시험さま at 06/18 블로그에 자주 오지 않.. by 시험さま at 01/21 안녕하세요 chroot /mnt.. by k1 at 12/29 오래된 글인가보네요. .. by ㅎㅁㅇㄴㅀ at 11/15 찌아찌아어 모음에는 한.. by 0950261319 at 09/26 찌아찌아어 모음에는 한.. by 0950261319 at 09/26 덕분에 일주일쨰 못풀던.. by mjh at 08/22 감사합니다ㅠㅠㅠㅠㅠ.. by byoul at 07/27 도움이 되었다는 덧글을.. by 시험さま at 05/04 감사합니다! pyinstaller .. by ㅇㅇ at 04/22 다른 가볼 데
| |||