Loader — executable yoki shared library’ni storage’dan xotiraga joylashtirib, process bajarilishini boshlashga tayyorlaydigan operatsion tizim komponenti.
Linker build vaqtida binary yaratadi. Loader esa runtime’da shu binary’ni virtual address space’ga map qiladi, dependencylarni yuklaydi, relocationlarni bajaradi va entry pointga boshqaruv beradi.
Loader kernel, runtime va dynamic linker bilan hamkorlik qiladi.
Executable ishga tushishi
Unix-like tizimda shell commandni ishga tushirganda umumiy jarayon:
- shell
forkyoki mos process yaratadi; - child
execvesyscall chaqiradi; - kernel executable formatni aniqlaydi;
- program segmentlari memoryga map qilinadi;
- dynamic loader kerak bo‘lsa ishga tushadi;
- shared librarylar yuklanadi;
- stack va argumentlar tayyorlanadi;
- entry pointga o‘tiladi.
Executable format
Loader platforma binary formatini tushunadi.
Misollar:
- ELF;
- PE;
- Mach-O;
- platformaga xos image;
- script shebang.
Format headerida:
- architecture;
- entry point;
- segmentlar;
- permission;
- interpreter path;
- dynamic section
mavjud.
Segment mapping
Loader file sectionlarini shunchaki to‘liq RAMga copy qilishi shart emas.
U file regionlarini virtual memoryga map qiladi.
Segmentlar:
- executable va read-only code;
- read-only constant;
- writable data;
- zero-filled BSS.
Page permission W^X siyosatiga mos belgilanadi.
Demand paging
Programning barcha code sahifalari startupda fizik RAMga o‘qilmaydi.
Virtual mapping yaratiladi. Instruction yoki data birinchi marta kerak bo‘lganda page fault orqali diskdan olinadi.
Bu startup va memory sarfini kamaytiradi.
BSS
BSS executable file’da barcha nol baytlar bilan saqlanmaydi.
Loader kerakli hajmdagi zero-filled memory yaratadi.
Bu global va static zero-initialized variablelar uchun ishlatiladi.
Entry point
Executable header dastlab bajariladigan virtual manzilni ko‘rsatadi.
Bu har doim source’dagi main function emas.
Avval runtime startup code:
- argumentlarni tayyorlaydi;
- library initialization;
- thread-local storage;
- constructor;
- security setup
bajaradi, keyin mainni chaqiradi.
Process stack
Loader yangi process stackida quyidagilarni joylashtiradi:
- argument count;
- argument stringlar;
- environment variable;
- auxiliary vector;
- random data;
- platform metadata.
C runtime shu ma’lumotdan argc, argv va environmentni hosil qiladi.
Auxiliary vector
ELF tizimlarda auxiliary vector kernel va loader orasida qo‘shimcha ma’lumot tashiydi.
Misollar:
Dynamic loader
Dynamically linked executable maxsus interpreter pathni ko‘rsatadi.
Dynamic loader:
- required librarylarni topadi;
- memoryga map qiladi;
- symbol resolve qiladi;
- relocation bajaradi;
- initializerlarni chaqiradi;
- programga boshqaruv beradi.
Linux ELF muhitida ld.so oilasi misol.
Shared library qidirish
Loader libraryni quyidagi manbalardan qidirishi mumkin:
- binary ichidagi RPATH yoki RUNPATH;
- environment variable;
- system cache;
- standard directory;
- platform manifest.
Qidiruv tartibi security va reproducibility uchun muhim.
Current directory’dan ishonchsiz library yuklash xavfli.
SONAME va version
Shared library ichida logical nom mavjud bo‘lishi mumkin.
Misol:
libexample.so.2
Major version ABI compatibilityni bildiradi.
Executable aniq SONAMEga dependency yozadi.
Symlink development va runtime versiyalarni bog‘laydi.
Symbol resolution
Loader tashqi function va global data symbolini loaded objectlardan topadi.
Search order interpositionga imkon berishi mumkin.
Bir library boshqa implementationni override qilishi mumkin.
Bu debugging uchun foydali, ammo security va kutilmagan behavior xavfi bor.
Relocation
Load address build vaqtidagi addressdan farq qilsa, pointer va instruction operandlari tuzatiladi.
Relocation:
- relative;
- symbol-based;
- TLS;
- PLT/GOT;
- architecture-specific
bo‘lishi mumkin.
Ko‘p relocation startupni sekinlashtiradi.
Lazy binding
Tashqi function manzili program boshlanishida emas, birinchi chaqiriqda aniqlanishi mumkin.
Afzalligi — ishlatilmaydigan function resolve qilinmaydi.
Kamchiligi — birinchi call kechikadi va writable table securityga ta’sir qiladi.
Immediate binding barcha symbolni startupda yechadi.
ASLR
Address Space Layout Randomization executable va librarylarni tasodifiy addresslarda joylashtiradi.
Position-independent executable va shared library bunga mos yoziladi.
ASLR exploitationni qiyinlashtiradi.
PIE
Position-Independent Executable executable’ning o‘zi ham turli addressga yuklanishiga imkon beradi.
Shared library kabi relative addressingdan foydalanadi.
Zamonaviy platformalarda security default bo‘lishi mumkin.
Preload
Environment orqali libraryni boshqalardan oldin yuklash mumkin.
Qo‘llanishlar:
- tracing;
- allocator almashtirish;
- testing;
- function interception.
Privileged executable’da bu mexanizm security sabab cheklanadi.
Constructor va destructor
Shared library yoki executable startup constructorlariga ega bo‘lishi mumkin.
Loader maindan oldin ularni ma’lum tartibda chaqiradi.
Process yakunida destructorlar ishlashi mumkin.
Global initialization order murakkab dependencyga sabab bo‘lishi mumkin.
Thread-local storage
Har thread uchun alohida variable regioni loader va runtime tomonidan yaratiladi.
Library TLS layout va relocation ma’lumotini beradi.
Dynamic load qilingan library uchun yangi TLS boshqaruvi kerak.
dlopen
Program runtime’da libraryni explicit yuklashi mumkin.
Amallar:
dlopen;dlsym;dlclose.
Plugin tizimlari bundan foydalanadi.
Library unload xavfli bo‘lishi mumkin, agar callback yoki thread hali uning code’idan foydalansa.
Script loader
Executable file shebang bilan boshlansa:
#!/usr/bin/env python3
kernel yoki launcher ko‘rsatilgan interpreterga script pathni argument sifatida beradi.
Bu native binary loaderdan boshqa yo‘l.
Loader xatolari
Keng tarqalgan xabarlar:
- shared library topilmadi;
- wrong architecture;
- invalid executable format;
- permission denied;
- missing interpreter;
- undefined symbol;
- relocation error;
- executable stack policy;
- version mismatch.
Diagnostika
Loader muammosida:
- binary format;
- architecture;
- interpreter path;
- dependency ro‘yxati;
- library search path;
- SONAME;
- symbol version;
- file permission;
- mount
noexec; - environment;
- dynamic loader trace
tekshiriladi.
Fayl mavjud bo‘lsa ham, uning ichida ko‘rsatilgan dynamic loader mavjud bo‘lmasa “file not found”ga o‘xshash xato chiqishi mumkin.
Bog‘liq tushunchalar
Executable, ELF, Dynamic loader, Shared library, Relocation, Symbol resolution, ASLR, PIE, Linker, Virtual memory