Linuxi failisüsteemi struktuur. OS-i failistruktuur. Mis tüüpi laiendus on käivitatavatel failidel? Kõige tavalisem

Olenemata sellest, kas arvuti on sisse lülitatud või mitte, salvestatakse kõik andmed ja programmid failide kujul arvuti pikaajalisse (välisesse) mällu – kust need täitmise või töötlemise käigus laaditakse.

Fail on teatud koodide kogum, mis kuvab teatud hulga tüübi või eesmärgiga seotud teavet, millele omistatakse kordumatu nimi ja mis salvestatakse pikaajalisse mällu.

Failidena saab salvestada programmide lähtetekste, töövalmis programme, dokumente, graafilisi pilte ja muid andmeid. Organisatsiooni tüübi ja sisu alusel jagatakse failid kahte kategooriasse – tekstiks ja binaarseks (binaarseks). Tekstifailid vastavalt oma eesmärgile salvestavad nad tekstidena tõlgendatud märgijadasid. Käivitavad failid koosnevad täitmiseks valmis programmide programmikoodidest.

Ainulaadsed nimed võimaldavad faile korraldada ja muuta need operatsioonisüsteemidele ja muudele programmidele juurdepääsetavaks. Faili nimi koosneb kahest punktiga eraldatud osast: tegelikult Nimi fail ja pikendamine , määratledes selle tüübi (programm, andmed jne). Failinime määrab kasutaja (mõnikord vaikimisi süsteem). Failitüübi määrab programm tavaliselt selle loomisel automaatselt, mis võimaldab enamikel juhtudel programmide käivitamist automatiseerida. Näiteks, .com, .exe- käivitatavad failid (programmid), .txt, .rtf . dok- tekstifailid, .pas– keeles kirjutatud programmi lähtetekst Pascal .

Failide kettale paigutamise korraldamiseks registreeritakse nende nimed spetsiaalsed failid- kataloogid (kaasaegsetes operatsioonisüsteemides nimetatakse neid faile kaustad) . Kataloog See on tabelifail (salvestatakse failidega samale kettale), mis salvestab failide nimed, teabe nende suuruse, viimase värskenduse aja, faili atribuudid (omadused) jne. Kui kataloog salvestab faili nime, öeldakse sageli, et fail "asub" selles kataloogis. Tegelikkuses asub (salvestatud) fail arvutiketta teatud mälualal, sageli mitme osana, fragmentidena erinevatel radadel ja paketi ketastel (kandja vabadel aladel). Vastav teave on kataloogis.

Igal kettal võib olla palju katalooge – nende arvu määrab otstarbekus ja piirab ainult ketta maht. See kehtib ka kataloogis olevate failide arvu kohta. Kõik kaasaegsed ketaste operatsioonisüsteemid võimaldavad luua failisüsteemi, mis on loodud andmete salvestamise korraldamiseks ja sellele juurdepääsu võimaldamiseks. Failisüsteemi korraldamise põhimõte on tabel. Kõvaketta pinda käsitletakse kolmemõõtmelise maatriksina, mille mõõtmed on pinna, silindri ja sektori numbrid. Silindri all mõistetakse kõigi erinevatele pindadele kuuluvate ja pöörlemisteljest võrdsel kaugusel asuvate radade kogumit. Andmed selle kohta, kus kettale konkreetne fail on salvestatud, salvestatakse ketta süsteemialasse spetsiaalsetes failijaotuse tabelites (FAT-tabelid).

Failide kettale salvestamise järjekorra määrab organisatsioon failisüsteem(kataloogide korraldus ja nendes olevate failide paigutuse ja atribuutide kirjeldamise meetod).

Sajad tuhanded failid on salvestatud ketastele, seega on failid otsimise hõlbustamiseks korraldatud mitmetasandilise failisüsteemi kujul, mille struktuur on joonisel näidatud.

Algne juurkataloog sisaldab 1. taseme alamkatalooge, neist omakorda 2. taseme alamkataloogid jne. Igal kataloogil on nimi (ilma laiendita) ja seda saab registreerida mõnes teises, vanemlik kataloog. Tuleb märkida, et kõigi tasemete kataloogid võivad salvestada mitte ainult katalooge, vaid ka faile.

Kuigi faili asukohaandmed salvestatakse tegelikult tabelina, esitatakse need kasutaja mugavuse huvides järgmiselt hierarhiline puu struktuure ja kõik vajalikud ühendused pakub operatsioonisüsteem.

Failisüsteemi hooldusfunktsioonid hõlmavad järgmisi operatsioonisüsteemi kontrolli all tehtavaid toiminguid:

    failide loomine ja nimetamine;

    kataloogide loomine ja nimetamine;

    failide ja kataloogide ümbernimetamine;

    failide kopeerimine ja teisaldamine arvutidraivide ja sama draivi kataloogide vahel;

    failide ja kataloogide kustutamine;

    failistruktuuris navigeerimine, et pääseda juurde antud failile või kataloogile;

    faili atribuutide haldamine.

Typedef struct _IMAGE_FILE_HEADER ( WORD Machine; WordOfSections; DWORD TimeDatestamp; DWORD PointerTo SymbolTable; DWORD NumberOf Symbols; WORD SizeOfOfOptional Header; WORD Characteristics; ) IMAGE_FILE_HEADER, *_PILE_HEADER;
Kirjeldan neid põlde vaid kuivalt, sest... nimed on intuitiivsed ja esindavad otseseid tähendusi, mitte VA, RVA, RAW ja muid hirmutavaid, intrigeerivaid asju, millest seni oleme kuulnud vaid vanadelt piraatidelt. Kuigi oleme juba kohanud RAW-d - need on lihtsalt nihked faili alguse suhtes (neid nimetatakse ka töötlemata osutiteks või failinihkeks). See tähendab, et kui meil on RAW-aadress, tähendab see, et peame liikuma faili algusest RAW-positsioonidesse ( ptrFile+ RAW). Seejärel saate hakata väärtusi lugema. Ilmekas näide seda tüüpi on e_lfnew- mida arutasime ülalpool Dosi pealkirjas.

*Masin: WORD – see arv (2 baiti) määrab protsessori arhitektuuri, millel see rakendus saab sooritada.
Sektsioonide arv: DWORD – jaotiste arv failis. Sektsioonid (edaspidi nimetame neid jaotiste tabeliks) järgnevad vahetult pärast päist (PE-Header). Dokumentatsioon ütleb, et sektsioonide arv on piiratud 96-ga.
TimeDateStamp: WORD – number, mis salvestab faili loomise kuupäeva ja kellaaja.
PointerTo SymbolTable: DWORD on sümbolitabeli nihe (RAW) ja SizeOfOptionalHeader on selle tabeli suurus. See tabel mõeldud ladustamiseks silumisinfo, kuid üksus ei märganud võitleja kaotust juba teenistuse algusest peale. Enamasti tühjendatakse see väli nullidega.
SIzeOfOptionHeader: WORD - valikulise päise suurus (mis järgneb kohe praegusele) Dokumentatsioonis on kirjas, et objektifaili puhul on selleks määratud 0...
*Omadused: WORD - faili omadused.

* - väljad, mis on määratletud väärtusvahemikuga. Võimalike väärtuste tabelid on toodud kontori struktuurikirjelduses. veebisaiti ja seda siin ei loetleta, sest Need ei sisalda midagi eriti olulist vormi mõistmiseks.

Lahkume sellelt saarelt! Peame edasi liikuma. Võrdluspunktiks on riik nimega Optional-Header.

„Kus kaart on, Billy? Mul on kaarti vaja."
(Aarete saar)

Valikuline päis (IMAGE_OPTIONAL_HEADER)

Selle kontinendi pealkiri pole kuigi hea. See päis on nõutav ja sellel on kaks vormingut PE32 ja PE32+ (vastavalt IMAGE_OPTIONAL_HEADER32 ja IMAGE_OPTIONAL_HEADER64). Vorming salvestatakse väljale Maagia: SÕNA. Päis sisaldab vajalikku teavet faili allalaadimiseks. Nagu alati :

IMAGE_OPTIONAL_HEADER

typedef struct _IMAGE_OPTIONAL_HEADER ( WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfWORDDaf; DWORDDafO Base; Base ; DWORD SectionAlignment; DWORD SizeOfRvaAndSizes , *PIMAGE_OPTIONAL_HEADER;


*Nagu alati, uurime ainult peamisi välju, millel on kõige suurem mõju allalaadimise mõistmisele ja failiga edasi liikumisele. Lepime kokku - selle struktuuri väljad sisaldavad väärtusi VA (virtuaalne aadress) ja RVA (suhteline virtuaalne aadress) aadressidega. Need aadressid ei ole samad, mis RAW ja sa pead suutma neid lugeda (või õigemini lugeda). Kindlasti õpime seda tegema, kuid kõigepealt analüüsime üksteisele järgnevaid struktuure, et mitte segadusse sattuda. Praegu pidage meeles – need on aadressid, mis pärast arvutusi osutavad failis kindlale asukohale. Samuti kohtate uut kontseptsiooni – joondus. Vaatleme seda koos RVA aadressidega, sest need on üsna tihedalt seotud.

AddressOfEntryPoint: DWORD – sisenemispunkti RVA aadress. Saab osutada mis tahes punktile aadressiruumis. exe-failide puhul vastab sisestuspunkt aadressile, kust programm täitmist alustab, ja see ei saa olla võrdne nulliga!
BaseOfCode: DWORD - programmi koodi alguse RVA (koodiosa).
BaseOfData: DWORD - programmi koodi alguse RVA (andmeosad).
ImageBase: DWORD – eelistatud baasaadress laadige programm alla. Peab olema 64 kb kordne. Enamikul juhtudel on see võrdne 0x00400000.
Sektsioonide joondamine: DWORD – jaotise joondussuurus (baitides) asukohta üleslaadimisel Virtuaalne mälu.
Failide joondamine: DWORD – faili sees oleva sektsiooni joondussuurus (baitides).
SizeOfimage: DWORD – faili suurus (baitides) mälus, sealhulgas kõik päised. Peab olema jaotise SectionAligment kordne.
SizeOfHeaders: DWORD – kõigi päiste (DOS, DOS-Stub, PE, Section) suurus, mis on joondatud FileAligmentiga.
NumberOfRvaAndSizes: DWORD - kataloogide arv kataloogitabelis (tabel ise on allpool). Peal Sel hetkel see väli on alati võrdne sümboolse konstandiga IMAGE_NUMBEROF_DIRECTORY_ENTRIES, mis on võrdne 16-ga.
DataDirectory: IMAGE_DATA_DIRECTORY – andmekataloog. Lihtsamalt öeldes on see massiiv (suurusega 16), mille iga element sisaldab 2 DWORD-väärtuse struktuuri.

Vaatame, milline on IMAGE_DATA_DIRECTORY struktuur:

Typedef struct _IMAGE_DATA_DIRECTORY ( DWORD VirtualAddress; DWORD Size; ) IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
Mis meil on? Meil on 16 elemendist koosnev massiiv, mille iga element sisaldab aadressi ja suurust (mida? kuidas? miks? kõik minutis). Tekib küsimus, mis need omadused täpsemalt on. Microsoftil on selleks sobitamiseks spetsiaalsed konstandid. Neid saab näha struktuurikirjelduse lõpus. Samal ajal:

// Kataloogikirjed #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Kataloogi eksportimine #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Kataloogi importimine #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Ressursikataloog #define IMAGE_DIRECTORY_ENTRY_DIRECTORY TORY_ENTRY _SECURITY 4 // Turvakataloog #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 / / Baasümberpaigutamise tabel #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Kataloog silumise 8 // GP RVA #define IMAGE_D IRECTORY_ENTRY_TLS 9 // TLS kataloog # define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Laadi konfiguratsioonikataloog #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Seotud impordikataloog päistes #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Impordi aadress TIMAGE_1 laadi importimise deskriptorid #define IMAGE_DIRECTORY_ENTRY_ COM_DESCRIPTOR 14 // COM Runtime deskriptor
Jah! Näeme, et massiivi iga element vastutab sellele lisatud tabeli eest. Aga paraku ja ah, need kaldad on meile ikkagi kättesaamatud, sest... me ei tea, kuidas VA ja RVA aadressidega töötada. Ja selleks, et õppida, peame uurima, millised on lõigud. Nad räägivad teile oma struktuurist ja tööst, pärast mida saab selgeks, miks on vaja VA, RVA ja joondusi. Käesolevas artiklis käsitleme ainult eksporti ja importi. Ülejäänud väljade otstarbega saab tutvuda kontoris. dokumentides või raamatutes. Nii et siin see on. Tegelikud väljad:

Virtuaalne aadress: DWORD – RVA tabeli jaoks, millele massiivi element vastab.
Suurus: DWORD – tabeli suurus baitides.

Nii et! Et jõuda sellistele eksootilistele randadele nagu impordi, ekspordi, ressursside ja muu tabelid, peame läbima sektsioonide otsingu. Noh, kajutipoiss, vaatame üldist kaarti, teeme kindlaks, kus me praegu oleme, ja liigume edasi:

Ja me asume otse sektsioonide laiade avatud ruumide ees. Peame kindlasti välja selgitama, mida nad varjavad, ja lõpuks välja mõtlema teist tüüpi adresseerimise. Soovime tõelisi seiklusi! Tahame kiiresti minna sellistesse vabariikidesse nagu impordi- ja eksporditabelid. Vanad piraadid räägivad, et kõigil ei õnnestunud nendeni jõuda, kuid need, kes jõudsid, naasid kulla ja naistega pühade teadmistega ookeani kohta. Asume teele ja suundume Sektsiooni päise poole.

„Sa oled vallandatud, Silver! Tulge tünnilt maha!"
(Aarete saar)

Jaotise päis (IMAGE_SECTION_HEADER)


Otse massiivi taga DataDirectory sektsioonid järgnevad üksteisele. Sektsioonitabel tähistab suveräänset riiki, mis on jagatud Sektsioonide arv linnad. Igal linnal on oma käsitöö, oma õigused ja ka suurus 0x28 baiti. Sektsioonide arv on märgitud väljale Sektsioonide arv, mis on salvestatud faili päisesse. Niisiis, vaatame struktuuri:

Typedef struct _IMAGE_SECTION_HEADER ( BYTE nimi; liit ( DWORD PhysicalAddress; DWORD VirtualSize; ) Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToRelocations; DWORD PointerToRelocations; DWORD PointerToLine Number; toimingud ) IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
Nimi: BAIT – sektsiooni nimi. Praegu on see 8 tähemärki pikk.
Virtuaalne suurus: DWORD – sektsiooni suurus virtuaalmälus.
SizeOfRawData: DWORD – jaotise suurus failis.
Virtuaalne aadress: DWORD – RVA sektsiooni aadress.
SizeOfRawData: DWORD – jaotise suurus failis. Peab olema kordne Failide joondamine.
PointerToRawData: DWORD – RAW nihe jaotise algusesse. Peab olema ka mitmekordne Failide joondamine
Omadused: DWORD - juurdepääsu atribuudid jaotisele ja reeglid selle virtuaalsesse laadimiseks. mälu. Näiteks atribuut jaotise sisu määratlemiseks (algandmed, mittealgandmed, kood). Või pääsete juurde atribuutidele – lugege, kirjutage, käivitage. See ei ole kogu nende valik. Karakteristikud määravad sama WINNT.h konstandid, mis algavad tähega IMAGE_SCN_. Sektsioonide atribuutidega saab lähemalt tutvuda. Ka Chris Kaspersky raamatute atribuudid on hästi kirjeldatud – viidete loetelu on artikli lõpus.

Nimega seoses tuleks meeles pidada järgmist – ressurssidega sektsioonis peaks alati olema nimi.rsrc. Vastasel juhul ressursse ei laadita. Ülejäänud jaotiste nimi võib olla ükskõik milline. Tavaliselt on seal tähendusrikkad nimed, näiteks .data, .src jne... Aga juhtub ka:

Sektsioonid on ala, mis laaditakse virtuaalmällu ja kogu töö toimub otse nende andmetega. Virtuaalses mälus olevat aadressi ilma nihketeta nimetatakse virtuaalseks aadressiks, lühendatult VA. Eelistatud aadress rakenduse allalaadimiseks, määratud väljale ImageBase. See on nagu punkt, kust rakendusala virtuaalmälus algab. Ja RVA (suhtelise virtuaalse aadressi) nihkeid mõõdetakse selle punkti suhtes. See tähendab, VA = ImageBase+ RVA; ImageBase me teame alati ja kui meie käsutuses on VA või RVA, saame väljendada üht läbi teise.

Tundub, et oleme siin harjunud. Aga see on virtuaalmälu! Ja me oleme füüsilises. Virtuaalne mälu on meie jaoks praegu nagu reis teistesse galaktikatesse, mida suudame vaid ette kujutada. Nii et me ei pääse praegu virtuaalmällu, kuid saame teada, mis seal on, sest see on võetud meie failist.

Joondamine


Virtuaalsesse üleslaadimise õigeks esitamiseks. mälu, on vaja mõista sellist mehhanismi nagu joondamine. Kõigepealt vaatame diagrammi, kuidas jaotised mällu lapitakse.

Nagu näete, ei laadita jaotist mällu selle suuruse järgi. Siin kasutatakse joondusi. See on väärtus, mis peab olema mälus oleva jaotise suuruse kordne. Kui vaatame diagrammi, näeme, et jaotise suurus on 0x28 ja jaotise suurus on 0x50. See on tingitud joonduse suurusest. 0x28 "ei ulatu" 0x50-ni ja selle tulemusena laaditakse sektsioon maha ja ülejäänud ruum suuruses 0x50-0x28 nullitakse. Ja kui sektsiooni suurus oli suurem kui joonduse suurus, siis mis? Näiteks jaotise suurus= 0x78, a jaotis Joondamine= 0x50, st. jäi muutumatuks. Sel juhul hõivaks sektsioon mälus 0xA0 (0xA0 = 0x28 * 0x04) baiti. See tähendab, et väärtus, mis on kordne jaotis Joondamine ja katab täielikult jaotise suurus. Tuleb märkida, et faili jaotised on joondatud sarnaselt, ainult suuruse järgi Failide joondamine. Olles saanud vajaliku baasi, saame välja mõelda, kuidas RVA-st RAW-i teisendada.

"See pole tasandik, siinne kliima on erinev."
(V.S. Võssotski)

Väike aritmeetikatund


Enne täitmise alustamist tuleb osa programmist saata protsessori aadressiruumi. Aadressiruum on töötleja poolt füüsiliselt adresseeritud andmete hulk. muutmälu. Kutsutakse välja "tükk" aadressiruumis, kuhu programm maha laaditakse virtuaalselt(virtuaalne pilt). Pilti iseloomustavad põhi allalaadimisaadress (Image base) ja suurus (Image size). Seega on VA (virtuaalne aadress) aadress virtuaalmälu alguse suhtes ja RVA (Relative Virtual Address) on suhteline selle kohaga, kus programm maha laaditi. Kuidas teada saada rakenduse allalaadimise põhiaadressi? Selleks on valikulises päises eraldi väli nimega ImageBase. See oli väike eelmäng teie mälu värskendamiseks. Vaatame nüüd erinevate adressaatide skemaatilist esitust:

Niisiis, kuidas saate ikkagi failist teavet lugeda ilma seda virtuaalmällu salvestamata? Selleks peate aadressid teisendama RAW-vormingus. Seejärel saame astuda faili sisse vajalikku ala ja lugeda vajalikud andmed. Kuna RVA on virtuaalse mälu aadress, kuhu andmed failist projitseeriti, saame teha vastupidise protsessi. Selleks vajame lihtsat aritmeetikat üheksa korda kuusteist. Siin on mõned valemid:

VA = ImageBase + RVA; RAW = RVA - sektsioonRVA + rawSection; // rawSection - nihe jaotisele faili algusest // sektsioonRVA - jaotise RVA (see väli salvestatakse jaotise sees)
Nagu näete, peame RAW arvutamiseks määrama jaotise, kuhu RVA kuulub. Selleks peate läbima kõik jaotised ja kontrollima järgmisi tingimusi:

RVA >= jaotisVituaalneAadress && RVA< ALIGN_UP(sectionVirtualSize, sectionAligment) // sectionAligment - выравнивание для секции. Значение можно узнать в Optional-header. // sectionVitualAddress - RVA секции - хранится непосредственно в секции // ALIGN_UP() - функция, определяющая сколько занимает секция в памяти, учитывая выравнивание
Kui kõik mõistatused kokku panna, saame järgmise loendi:

Typedef uint32_t DWORD; typedef uint16_t WORD; typedef uint8_t BYTE; #define ALIGN_DOWN(x, joondus) (x & ~(joonda-1)) #define ALIGN_UP(x, joondus) ((x & (joonda-1))?ALIGN_DOWN(x,joonda)+joonda:x) // IMAGE_SECTION_HEADER jaotised; // init massiivi lõigud int defSection(DWORD rva) ( for (int i = 0; i< numberOfSection; ++i) { DWORD start = sections[i].VirtualAddress; DWORD end = start + ALIGN_UP(sections[i].VirtualSize, sectionAligment); if(rva >= start && rva< end) return i; } return -1; } DWORD rvaToOff(DWORD rva) { int indexSection = defSection(rva); if(indexSection != -1) return rva - sections.VirtualAddress + sections.PointerToRawData; else return 0; }
*Ma ei lisanud koodi tüübideklaratsiooni ega massiivi lähtestamist, vaid andsin ainult funktsioonid, mis aitavad aadresse arvutada. Nagu näete, polnud kood väga keeruline. Lihtsalt veidi segane. See kaob... kui veedate natuke rohkem aega .exe-failiga demonteerimisseadme kaudu.

HURRAA! Me mõtlesime selle välja. Nüüd saame minna ressursside maale, impordi- ja ekspordiraamatukogudesse ja üldiselt kuhu iganes süda ihkab. Õppisime just, kuidas töötada uut tüüpi adresseerimisega. Asume teele!

"- Pole paha, pole paha! Ometi said nad tänaseks oma toiduportsjoni kätte!”
(Aarete saar)

Ekspordi tabel


Massiivi kõige esimeses elemendis DataDirectory RVA salvestatakse eksporditabelis, mida esindab struktuur IMAGE_EXPORT_DIRECTORY. See tabel on ühine dünaamilise teegi (.dll) failidele. Tabeli peamine eesmärk on seostada eksporditud funktsioonid nende RVA-ga. Kirjeldus esitatakse kontoris. Tehnilised andmed:

Typedef struct _IMAGE_EXPORT_DIRECTORY ( DWORD karakteristikud; DWORD-i ajatempel; WORD-peaversioon; WORD-alaversioon; DWORD-nimi; DWORD-alus; DWORD-i funktsioonide arv; DWORD-i nimede number; ) IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
See struktuur sisaldab kolme viidet kolmele erinevale tabelile. See on nimede (funktsioonide) tabel ( AddressOfNames), järgarvud ( AddressOfNamesOrdinals), aadressid ( Funktsioonide aadress). Väljale Nimi salvestatakse nime RVA dünaamiline raamatukogu. Ordinaal on nagu vahelüli nimetabeli ja aadressitabeli vahel ning on indeksite massiiv (indeksi suurus on 2 baiti). Suurema selguse huvides vaadake diagrammi:

Vaatame näidet. Oletame, et nimede massiivi i-s element näitab funktsiooni nime. Seejärel saab selle funktsiooni aadressi saada aadressi massiivi i-nda elemendi poole pöördudes. Need. ma olen ordinaal.

Tähelepanu! Kui võtate näiteks järgarvude tabeli 2. elemendi, ei tähenda see 2. - see on järgarv nimede ja aadresside tabelite jaoks. Indeks on järgarvude massiivi teise elemendi salvestatud väärtus.

Väärtuste arv nimetabelites ( Nimede arv) ja järgarvud on võrdsed ega kattu alati aadressitabelis olevate elementide arvuga ( Funktsioonide arv).

"Nad tulid mulle järele. Tänan tähelepanu eest. Nüüd nad vist tapavad!"
(Aarete saar)

Impordi tabel


Imporditabel on kõigi dünaamilisi teeke kasutavate rakenduste lahutamatu osa. See tabel aitab korreleerida dünaamiliste teegi funktsioonide kõnesid vastavate aadressidega. Import võib toimuda kolmes erinevad režiimid: standardne, seotud import ja viivitusega import. Sest Impordi teema on üsna mitmetahuline ja väärib eraldi artiklit, kirjeldan ainult standardmehhanismi ja ülejäänu kirjeldan ainult kui "skeletti".

Standardne import- V DataDirectory Imporditabel on salvestatud indeksi IMAGE_DIRECTORY_ENTRY_IMPORT(=1) alla. See on IMAGE_IMPORT_DESCRIPTOR tüüpi elementide massiiv. Imporditabel salvestab (massiivina) funktsioonide/järgarvude nimed ja kuhu laadija peaks kirjutama selle funktsiooni efektiivse aadressi. See mehhanism ei ole väga tõhus, sest Ausalt öeldes taandub see kõik iga vajaliku funktsiooni otsimisele kogu eksporditabelist.

Seotud import- selle põldudel töötamise skeemiga (esimeses elemendis standardne tabel import) TimeDateStamp ja ForwardChain on seatud väärtusele -1 ja sidumisteave salvestatakse lahtrisse DataDirectory indeksiga IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT(=11). See tähendab, et see on laadija jaoks omamoodi lipp, mida peate seotud importimiseks kasutama. Samuti on "seotud impordiahelal" oma struktuurid. Tööalgoritm on järgmine - rakenduse virtuaalmälu laaditakse maha vajalik raamatukogu ja kõik vajalikud aadressid on koostamise etapis “köidetud”. Üks puudusi on see, et dll-i uuesti kompileerimisel peate rakenduse ise uuesti kompileerima, kuna funktsiooni aadressid muudetakse.

Impordi viivitus- kell seda meetodit Eeldatakse, et .dll-fail on lisatud käivitatavale failile, kuid seda ei laadita mällu kohe (nagu kahe eelmise meetodi puhul), vaid alles siis, kui rakendus esmakordselt juurdepääsu sümbolile (see laadib dünaamiliste teekide elemendid maha kutsutakse). See tähendab, et programm käivitatakse mälus ja niipea, kui protsess on jõudnud funktsiooni kutsumiseni dünaamilisest teegist, kutsutakse välja spetsiaalne töötleja, mis laadib dll-i ja jagab selle funktsioonide tõhusad aadressid. Edasilükatud impordi puhul võtab laadija ühendust DataDirectoryga (üksus number 15).

Olles impordimeetodeid veidi käsitlenud, liigume otse imporditabeli juurde.

„See on meremees! Tema riided olid merelised. - Jah? Kas sa arvasid, et leiad siit piiskopi?”
(Aarete saar – John Silver)

Impordi deskriptor (IMAGE_IMPORT_DESCRIPTOR)


Imporditabeli koordinaatide väljaselgitamiseks peame ligipääsu massiivile DataDirectory. Nimelt elemendile IMAGE_DIRECTORY_ENTRY_IMPORT (=1). Ja lugege tabeli RVA aadressi. Siin on üldine skeem, mis tuleb läbida:

Seejärel saame RVA-st vastavalt ülaltoodud valemitele RAW ja seejärel “sammume” failist läbi. Nüüd oleme otse struktuuride massiivi ees, mida nimetatakse IMAGE_IMPORT_DESCRIPTOR. Massiivi lõppu tähistab struktuur "null".

Typedef struct _IMAGE_IMPORT_DESCRIPTOR ( liit ( DWORD omadused; DWORD OriginalFirstThunk; ) DUMMYUNIONNAME; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; ) IMAGE_IMPORT_MCRIPTORIM,*_PICRIPTORIM,*_PICRIPTORIM;*
Ma ei leidnud linki msdn-i struktuuri kirjeldusele, kuid näete seda failis WINNT.h. Hakkame seda välja mõtlema.

OriginalFirstThunk: DWORD – impordi nimetabeli (INT) RVA.
TimeDateStamp: DWORD – kuupäev ja kellaaeg.
ForwarderCain: DWORD – esimese edastatud märgi indeks.
Nimi: DWORD – RVA string teegi nimega.
FirstThunk: DWORD – impordi aadressitabeli (IAT) RVA.

Kõik siin sarnaneb mõneti ekspordiga. Samuti nimede tabel (INT) ja sellel ka aadresside lapp (IAT). Samuti raamatukogu nime RVA. Ainult INT ja IAT viitavad IMAGE_THUNK_DATA struktuuride massiivile. See on esitatud kahel kujul - 64 ja 32 süsteemi jaoks ning erinevad ainult väljade suuruse poolest. Vaatame näitena x86:

Typedef struct _IMAGE_THUNK_DATA32 ( liit ( DWORD ForwarderString; DWORD Function; DWORD Ordinaal; DWORD AddressOfData; ) u1; ) IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
Oluline on sellele vastata edasisi tegevusi sõltuvad struktuuri kõige olulisemast osast. Kui see on määratud, esindavad ülejäänud bitid imporditava märgi numbrit (import numbri järgi). Vastasel juhul (kõige olulisem bitt kustutatakse) määravad ülejäänud bitid imporditava sümboli RVA (import nime järgi). Kui meil on nimeline import, salvestab kursor aadressi järgmisesse struktuuri:

Typedef struct _IMAGE_IMPORT_BY_NAME ( WORD vihje; BYTE nimi; ) IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
Siin Vihje on funktsiooni number ja Nimi- Nimi.

Mille jaoks see kõik on? Kõik need massiivid, struktuurid... Selguse huvides vaatleme imelist diagrammi

3. loeng. Faili struktuur

Kirjandus

o Kaasaegsed operatsioonisüsteemid, E. Tanenbaum, 2002, Peterburi, Peterburi, 1040 lk, (djvu-s 10,1 MB) rohkem>>

o Võrgu operatsioonisüsteemid N. A. Olifer, V. G. Olifer (zip-arhiiv 1,1 MB)

o Võrgu operatsioonisüsteemid N. A. Olifer, V. G. Olifer, 2001, Peterburi, Peter, 544 lk, (djvu-s 6,3 MB)veel>>

Failid

Teabe säilitamise nõuded:

o võime salvestada suuri andmemahtusid

o teave tuleb säilitada pärast protsessi lõpetamist

o peab olema mitu protsessi samaaegne juurdepääs teabele

2.1.1 Failidele nime andmine

Faili nime pikkus sõltub operatsioonisüsteemist, see võib olla 8 (MS-DOS) kuni 255 (Windows, LINUX) tähemärki.

OS suudab eristada suurtähti ja väiketähti. Näiteks WINDOWS ja Windows MS-DOS-i jaoks on samad, kuid UNIX-i jaoks on need erinevad failid.

Paljudes operatsioonisüsteemides koosneb failinimi kahest osast, mis on eraldatud punktiga, näiteks windows.exe. Punktijärgset osa nimetatakse faililaiendit. Süsteem kasutab seda failitüübi eristamiseks.

MS-DOS-i puhul on laiend 3 tähemärki. Seda kasutades eristab süsteem faili tüübi ja selle, kas seda saab käivitada või mitte.

UNIX-is on laiend piiratud failinime suurusega 255 tähemärki ja UNIXil võib olla mitu laiendit, kuid laiendusi kasutavad rohkem rakendusprogrammid, mitte OS. UNIX ei saa selle laiendi põhjal kindlaks teha, kas fail on käivitatav või mitte.

2.1.2 Faili struktuur

Kolm peamist failistruktuuri:

1. Baitide jada- OS ei ole faili sisust huvitatud, ta näeb ainult baite. Sellise süsteemi peamine eelis on selle kasutamise paindlikkus. Kasutatakse Windowsis ja UNIXis.

2. Kirjete jada- fikseeritud pikkusega kirjeid (näiteks perfokaart) loetakse järjestikku. Praegu pole kasutusel.

3. Sissepääsupuu- igal kirjel on võti, kirjeid loetakse võtme abil. Sellise süsteemi peamine eelis on otsingu kiirus. Kasutatakse endiselt suurarvutitel.

Kolme tüüpi failistruktuurid.

2.1.3 Failitüübid

Peamised failitüübid:

o Regulaarne- sisaldab kasutajateavet. Kasutatakse Windowsis ja UNIXis.

o Kataloogid - süsteemifailid, pakkudes tuge failisüsteemi struktuurile. Kasutatakse Windowsis ja UNIXis.

o Iseloom- sisend-väljund modelleerimiseks. Kasutatud ainult UNIX-is.

o Blokeeri- ketaste modelleerimiseks. Kasutatud ainult UNIX-is.

Tavaliste failide peamised tüübid:

o ASCII failid- koosneb tekstistringid. Iga rida lõpeb käru tagastamisega (Windows), reavahetusega (UNIX) ja mõlemaga (MS-DOS). Seega, kui avate tekstifail kirjutatud UNIX-is, Windowsis, siis liidetakse kõik read üheks suureks reale, kuid MS-DOS-is neid ei liideta ( see on üsna tavaline olukord). ASCII-failide peamised eelised:
- saab kuvada ekraanil ja väljastada printerisse ilma teisendamiseta
- saab redigeerida peaaegu iga toimetajaga

o Binaarfailid- muud failid (mitte-ASCII). Reeglina on neil sisemine struktuur.

Peamised binaarfailide tüübid:

o Täidetav- programmid, neid saab töödelda operatsioonisüsteem ise, kuigi need on kirjutatud baitide jadana.

o Mittekäivitav- muu.

Näited käivitatavatest ja mittekäivitatavatest failidest

"Maagiline number"- faili tuvastamine käivitatavana.

2.1.4 Juurdepääs failidele

Peamised failijuurdepääsu tüübid:

o Järjepidev- baite loetakse järjekorras. Kasutatakse siis, kui olid magnetlindid.

2.1.5 Faili atribuudid

Peamised failiatribuudid:

o Kaitse – kes ja kuidas pääseb failile juurde (kasutajad, rühmad, lugemine/kirjutamine). Kasutatakse Windowsis ja UNIXis.

o Parool – faili parool

o Looja – kes faili lõi

o Omanik – faili praegune omanik

o Kirjutuskaitstud lipp - 0 - lugemine/kirjutamine, 1 - kirjutuskaitstud. Kasutatakse Windowsis.

o "Peidetud" lipp - 0 - nähtav, 1 - nähtamatu kataloogifailide loendis (vaikimisi). Kasutatakse Windowsis.

o Lipp "süsteem" - 0 - normaalne, 1 - süsteem. Kasutatakse Windowsis.

o Märkige "arhiiv" - arhiveerimiseks valmis või mitte (mitte segi ajada tihendamisega). Kasutatakse Windowsis.

o Märkige "tihendatud" - fail on tihendatud (sarnaselt zip-arhiivid). Kasutatakse Windowsis.

o Märkige "krüpteeritud" – kasutatakse krüpteerimisalgoritmi. Kui keegi proovib lugeda faili, millel pole selleks luba, ei saa ta seda lugeda. Kasutatakse Windowsis.

o ASCII/binaarne lipp - 0 - ASCII, 1 - binaarne

o Juhusjuurdepääsu lipp – 0 – ainult järjestikune, 1 – juhuslik juurdepääs

o Märkige "ajutine" - 0 - tavaline, 1 - faili kustutamiseks protsessi lõpus

o Blokeerimislipp – failile juurdepääsu blokeerimine. Kui ta on toimetamistega hõivatud.

o Loomise aeg – loomise kuupäev ja kellaaeg. Kasutusel on UNIX.

o Viimase juurdepääsu aeg – viimase juurdepääsu kuupäev ja kellaaeg

o Viimase muudatuse aeg – viimase muudatuse kuupäev ja kellaaeg. Kasutatakse Windowsis ja UNIXis.

o Praegune suurus – faili suurus. Kasutatakse Windowsis ja UNIXis.

2.1.6 Toimingud failidega

Põhiline süsteemikõned failidega töötamiseks:

o Loo – faili loomine ilma andmeteta.

o Kustuta – faili kustutamine.

o Open – faili avamine.

o Close – faili sulgemine.

o Loe – failist lugemine, faili praegusest asukohast.

o Kirjuta - faili kirjutamine praegusesse faili asukohta.

o Lisa – lisamine faili lõppu.

o Otsi – seab failikursori failis kindlasse kohta.

o Hangi atribuudid – failiatribuutide hankimine.

o Määra atribuudid – määra faili atribuudid.

o Rename – faili ümbernimetamine.

mälu operatsioonisüsteemi laadija poolt ja seejärel käivitatakse. Operatsiooniruumis Windowsi süsteem Käivitatavatel failidel on tavaliselt laiendid ".exe" ja ".dll". Laiendus ".exe" sisaldab programme, mida kasutaja saab otse käivitada. Laiendil ".dll" on niinimetatud dünaamiliselt lingitud teegid ( dünaamiline link raamatukogud). Need teegid ekspordivad teiste programmide kasutatavaid funktsioone.

Operatsioonisüsteemi alglaaduri korrektseks laadimiseks käivitatav fail mällu, peab selle faili sisu vastama selles operatsioonisüsteemis aktsepteeritavale käivitatavale failivormingule. Erinevates operatsioonisüsteemides eri aegadel oli ja on siiani palju erinevaid formaate. Selles peatükis vaatleme kaasaskantava käivitatava (PE) vormingut. PE-vorming on Windowsi operatsioonisüsteemis käivitatavate failide salvestamise esmane vorming. Assambleed. NET-faile salvestatakse ka selles vormingus.

Lisaks saab esitamiseks kasutada PE-vormingut objektifailid. Objektifaile kasutatakse programmi eraldi kompileerimise korraldamiseks. Eraldi kompileerimise mõte seisneb selles, et programmi osad (moodulid) kompileeritakse iseseisvalt objektifailideks, mis seejärel linkeri poolt üheks lingitakse. käivitatav fail.

Ja nüüd – väike ajalugu. PE-vormingu lõid Windows NT arendajad. Varem kasutas Windowsi operatsioonisüsteem täitmisfailide esitamiseks ja salvestamiseks vorminguid New Executable (NE) ja Linear Executable (LE). objektifailid Kasutati Object Module Format (OMF) vormingut. NE-vorming oli mõeldud 16-bitise jaoks Windowsi rakendused, ja algselt OS/2 jaoks välja töötatud LE-vorming oli juba 32-bitine. Tekib küsimus: miks? Windowsi arendajad NT otsustas loobuda olemasolevad vormingud? Vastus saab ilmseks, kui pöörata tähelepanu asjaolule, et enamik meeskonda, kes töötasid Windowsi loomine NT, varem töötas Digital Equipment Corporationis. Nad töötasid DEC-is välja tööriistu VAX/VMS operatsioonisüsteemi jaoks ning neil olid juba oskused ja oskused valmis kood vormingus esitatud käivitatavate failidega töötamiseks Ühine objekt Failivorming (COFF). Sellest lähtuvalt viidi COFF-vorming veidi muudetud kujul üle Windows NT-sse ja sai nimeks PE.

".NET Frameworki sõnastik" ütleb, et PE on rakendus Microsofti vorming COFF. Samas öeldakse, et PE on käivitatav failivorming ja COFF on formaat objektifailid. Üldiselt võime täheldada segadust Microsofti dokumentatsioon vormingu nimetuse kohta. Mõnes kohas kutsuvad nad seda COFF-iks ja mõnes kohas PE. Tõsi, võib märgata, et uutes tekstides kasutatakse nime COFF üha vähem. Lisaks areneb PE-vorming pidevalt. Näiteks lõpetas Microsoft mitu aastat tagasi silumisteabe salvestamise käivitatavas failis ja seetõttu ei kasutata nüüd paljusid COFF-vormingus struktuurides olevaid välju. Lisaks on COFF-vorming 32-bitine ja viimane väljaanne PE-vormingut (nimetatakse PE32+) saab kasutada 64-bitistel riistvaraplatvormidel. Seetõttu ilmselt liiguvad asjad sinnapoole, et COFF nime enam üldse ei kasutata.

Huvitav on märkida, et Windows toetab endiselt pärandvormingus NE ja LE käivitatavaid faile. NE-vormingus käivitatavaid faile saab käivitada NTVDM-is (NT Virtual DOS Machine) ja LE-vormingut kasutatakse virtuaalsete seadmedraiverite jaoks (

Paljud kasutajad arvutisüsteemid Tõenäoliselt olete ühel või teisel määral kokku puutunud käivitatava programmifaili mõistega. Käivitatavatel failidel ei ole alati, kuid üsna sageli laiend EXE, mis on operatsioonisüsteemide jaoks tavaline Windowsi perekond. Laienduste probleemi selgitamiseks vaatame Üldine informatsioon nende objektide kohta ja kaaluge ka mõnda tüüpi põhilaiendeid.

Kuidas käivitatavad failid erinevad teistest objektidest

Enne kui väita, et programmi käivitataval failil võib olla ainult ühte kindlat tüüpi laiendit, tuleb mõista, kuidas sellist objekti teistest eristada. Peamised erinevused käivitatavate failide ja muude teabeandmete vahel hõlmavad järgmisi tegureid: laiend ise, mis näitab kas masinkoodi või baitkoodi sisu failis Virtuaalne masin,signatuur, atribuudid failisüsteemis. Kuid isegi kui kasutaja teab, et käivitatavatel failidel on EXE-tüüpi nimelaiend, ei saa sisu tavaliste vahenditega vaadata, kuna sellistel objektidel on koostatud sisu, mis kuvatakse mõttetu märgikomplektina. . Üldiselt peab kasutaja kasutama Disassembleri tööriista või midagi sarnast, mis võimaldab dekompileerimist. Aga see pole see, millest me räägime.

Käivitavad failid: struktuur

Mis puutub täitmisfailide ülesehitusse, siis need peavad sisaldama päiseid (käskude kavandatud täitmine, parameetrid ja koodivormingud) ja käske ennast (allika, masina või baitkoodid). Mõnel juhul võib struktuur sisaldada silumisandmeid, keskkonna kirjeldusi, operatsioonisüsteemi nõudeid, asjakohaste teekide loendeid, heli, graafikat, pilte, otseteeikoone jms. Paljud teist ilmselt märkasid, et enamasti on igal sellisel failil operatsioonisüsteemis algselt ikoon.

Toimimispõhimõte

Kuigi käivitatavatel failidel võib olla laiend erinevat tüüpi, töötavad nad samal põhimõttel. Käivitamisel laaditakse käivitatav fail arvuti mällu. Samal ajal seadistatakse ja lähtestatakse keskkond ning täiendavad raamatukogud, kui nende kasutamine on programmis ette nähtud. Samuti sisse selles etapis konfigureeritakse mõned lisatoimingud ja juhised ise täidetakse meetoditega, mis on otse faili kirjutatud.

Käivitavad programmifailid: mis laiendus neil on?

Nüüd jätkame laiendustega seotud probleemi käsitlemisega. Loomulikult ei ole võimalik arvestada absoluutselt kõigi tüüpidega, see võtab palju aega. Toome esile ainult kõige levinumad ja populaarsemad valikud. Seega määratakse laiendus sõltuvalt sisu tüübist. Näiteks operatsioonisüsteemis Windowsi tüüp kõige levinumad käivitatavad failid EXE laiendus. See kehtib kõigi programmide kohta, mis on loodud nende operatsioonisüsteemide keskkonnas töötamiseks. Sellised objektid sisaldavad masinakoodid. BIN-failid on väga sarnased. Pakettfailid, nagu CMD, BAT ja COM, on teist tüüpi käivitatavad failid. Esimesena sisestage sel juhul on partiifail Windows. Teist ja kolmandat tüüpi failid kuuluvad DOS-i perekonna operatsioonisüsteemidesse. Paljud teist on ilmselt juba MSI- ja MSU-failidega kokku puutunud. See võib olla süsteemivärskenduste installiprogramm või Windowsi opsüsteemi installiprogramm. Eraldi failide kategooria koosneb makrodest ja skriptidest. Need on failid laienditega JSE, JS, SCR, VBE, VBS, VB. Tihti leidub ka JAD- ja JAR-faile, mis on mõeldud rakenduste installimiseks mobiilseadmetesse või nendes kasutamiseks JAVA keskkond. Oma sisult ei sisalda sellised objektid enam masinkoode, vaid virtuaalmasina koode.

Milline laiend on käivitatavatel failidel erinevates operatsioonisüsteemides?

Kui vaatate tähelepanelikult, märkate, et mõnel operatsioonisüsteemil on üsna spetsiifilised komponendid. Näiteks Windowsi operatsioonisüsteemil on käivitatavate failide erikategooria. Üldiselt leiate igast operatsioonisüsteemist nii standardseid kui ka spetsiaalsed komponendid. Siiski on ka mõned levinumad vormingud, näiteks HTA, käivitatav HTML dokument. Need töötavad peaaegu kõikjal, olenemata kasutatavast operatsioonisüsteemist. Mis puutub muud tüüpi süsteemidesse, siis näiteks Mac-arvutites on käivitatavatel failidel programmide jaoks laiend APP ja distributsioonide jaoks PKG. Operatsioonisüsteemides Linuxi perekond asjad on natuke teistmoodi. Probleem on selles, et sellistes operatsioonisüsteemides puudub laienduse kontseptsioon. Täitmisfaili tunnete ära selle atribuutide järgi, nagu süsteem, peidetud, kirjutuskaitstud jne. Selle tulemusena kaob probleem laienduse muutmisel vajaliku faili käivitamiseks või lugemiseks. Kuid igas operatsioonisüsteemis, isegi sisse lülitatud mobiilseadmed võite leida tohutul hulgal objekte seda tüüpi. Sa ei pea kaugele minema. Androidi perekonna samas operatsioonisüsteemis on installija käivitatav fail APK laiendus. Apple'i seadmetes on täitmisfailidel IPA laiend.

Järeldus

Teeme kokkuvõtte meie väike ülevaade käivitatavate failide laienduse kohta. Antud juhul oli rõhk peamiselt objektidel, mis on Windowsi perekonna operatsioonisüsteemides. Teisi operatsioonisüsteeme puudutati vaid möödaminnes üldine areng. Nagu juba selgunud, on käivitatavate failide valik väga suur. Ühtegi on võimatu anda pöördetabel mis näitab absoluutselt igat tüüpi laiendusi. Seetõttu piirdusime selles artiklis ainult kõige levinumate vormingutega.