| MAGIC(5) | File Formats Manual | MAGIC(5) |
magic — plik
wzorców magicznych polecenia file
Ta strona podręcznika systemowego opisuje format pliku magicznego, używanego przez polecenie file(1) w wersji 5.46. Polecenie file(1) rozpoznaje typ pliku, korzystając (poza innymi metodami) z testu, polegającego na sprawdzeniu, czy plik nie rozpoczyna się od pewnego „wzorca magicznego”. Baza „wzorców magicznych” znajduje się zwykle w pliku binarnym /usr/share/misc/magic.mgc lub w katalogu z plikami zawierającymi fragmenty źródłowe tekstów wzorców magicznych /usr/share/misc/magic. Baza określa jakie wzorce sprawdzać i jakie komunikaty lub typy MIME wypisywać w przypadku znalezienia określonego wzorca magicznego oraz dodatkowe dane, które mają zostać pobrane z pliku.
Format plików z fragmentami źródeł służącymi do zbudowania tej bazy danych jest następujący: Każdy wiersz pliku fragmentarycznego określa test, które ma być wykonany. Test porównuje dane, rozpoczynające się przy określonym przesunięciu względem początku pliku z wartością bajtową, numeryczną lub łańcuchem. Jeśli test zakończy się pomyślnie, wypisywany jest komunikat. Wiersz składa się z następujących pól:
offset&).typebyteshortlongquadfloatdoublestringn kolejnych białych
znaków, cel musi mieć przynajmniej
n kolejnych białych znaków,
aby zostać dopasowanym.pstringdateqdateldateqldateqwdatemsdosdatemsdostimebeid3beshortbelongbequadbefloatbedoublebedatebeqdatebeldatebeqldatebeqwdatebemsdosdatebemsdostimebestring16leid3leshortlelonglequadlefloatledoubleledateleqdateleldateleqldateleqwdatelemsdosdatelemsdostimelestring16melongmedatemeldateindirectindirect jest domyślnie
przesunięciem absolutnym w pliku, ale można podać
/r aby wskazać, że
przesunięcie jest względne wobec początku
wpisu.nameuse, jak wywołanie podfunkcji.
Przesunięcia nazwanych wystąpień
bezpośrednich magii są względem
przesunięcia poprzednio dopasowanego wpisu, natomiast
niebezpośrednie przesunięcia są liczone
względem początku pliku, jak zwykle. Nazwane wpisy magii
są zawsze dopasowywane.use^, to zamieniana jest kolejność
bajtów magii; jeśli magia wspominała np.
leshort, jest traktowana jako
beshort i na odwrót. Jest to przydatne,
aby uniknąć duplikowania reguł dla
różnych kolejności bajtów.regex/<długość>, aby
uniknąć problemów z wydajnością
przy skanowaniu długich plików. Po określeniu
typu można opcjonalnie dodać
/[c][s][l]. Flaga „c” czyni
dopasowanie niewrażliwym na wielkość
znaków, natomiast „s” aktualizuje
przesunięcie na początek przesunięcia
dopasowania, zamiast jego koniec. Modyfikator „l”
zmienia limit długości, aby oznaczał on
liczbę wierszy zamiast liczbę bajtów. Wiersze
są rozgraniczane przez ogranicznik zależny od platformy.
Gdy poda się liczbę wierszy, obliczana jest też
niejawnie liczba bajtów zakładając, że
każdy wiersz ma 80 znaków. Jeśli nie poda
się liczby bajtów ani wierszy, wyszukiwanie jest
automatycznie ograniczane do 8KiB. ^ i
$ dopasowują początek i koniec
poszczególnych wierszy, a nie początek i koniec
pliku.search/liczba, tj. liczbę pozycji, na
której dokonane będą próby dopasowania,
zaczynając od początkowego przesunięcia. Jest to
właściwe przy wyszukiwaniu większych
wyrażeń binarnych z różnymi
przesunięciami, korzystając z cytowania znaków
specjalnych za pomocą \.
Kolejność modyfikatorów i liczb nie ma
znaczenia.defaultclear można
wyczyścić dopasowane testy dla poziomu kontynuacji.cleardefault.dereoc, bool,
int, bit_str,
octet_str, null,
obj_id, obj_desc,
ext, real,
enum, embed,
utf8_str, rel_oid,
time, res2,
seq, set,
num_str, prt_str,
t61_str, vid_str,
ia5_str, utc_time,
gen_time, gr_str,
vis_str, gen_str,
univ_str, char_str,
bmp_str, date,
tod, datetime,
duration, oid-iri,
rel-oid-iri. Po typach tych może
wystąpić opcjonalny rozmiar numeryczny, który
oznacza szerokość pola w bajtach.guidoffset-0 offset x ten plik ma %lld bajtów
-0 offset <=100 musi mieć więcej niż 100 \
bajtów, a ma tylko %lld
octalZe względu ma kompatybilność z Single
UNIX Standard, określenia typu
dC i d1 są
równoważne byte, określenia
typu uC i u1 są
równoważne ubyte,
określenia typu dS i
d2 są równoważne
short, określenia typu
uS i u2 są
równoważne ushort,
określenia typu dI,
dL, i d4 są
równoważne long, określenia
typu uI, uL, i
u4 są równoważne
ulong, określenie typu
d8 jest równoważne
quad, określenie typu
u8 jest równoważne
uquad, a określenie typu
s jest równoważne
string. Dodatkowo określenie typu
dQ jest równoważne
quad, a określenie typu
uQ jest równoważne
uquad.
Każdy wzorzec magiczny najwyższego poziomu (poniżej wyjaśniono znaczenie poziomów) jest klasyfikowany jako tekstowy lub binarny, w zależności od użytego typu. Typy „regex” i „search” są klasyfikowane jako tekstowe, chyba że we wzorcu użyto znaków niedrukowalnych. Wszystkie inne testy są klasyfikowane jako binarne. Wzorzec najwyższego poziomu uważa się za test tekstowy, jeśli wszystkie jego wzorce są wzorcami tekstowymi; w innym przypadku jest uważany za wzorzec binarny. Przy dopasowywaniu pliku, jako pierwsze próbowane są wzorce binarne; jeśli żaden nie zostanie dopasowany, a plik wygląda na tekstowy, to określane jest jego kodowanie i próbowane są wzorce tekstowe.
Po typach numerycznych może opcjonalnie
wystąpić & i
wartość numeryczna aby określić, że
wartość ma być zsumowana (AND) z
wartością numeryczną przed dokonaniem
jakiegokolwiek porównania. Wstawienie u
przed typem oznacza, że uszeregowane porównania
mają być dokonywane bez względu na znak.
testWartości numeryczne mogą być
poprzedzone znakami określającymi operację, jaka ma
zostać wykonana. Znakiem operacji może być
=, określający, że
wartość z pliku musi się równać
wartości podanej, <,
określający, że wartość z pliku musi
być mniejsza od podanej, >,
określający, że wartość z pliku musi
być większa od podanej, &,
określający, że wartość z pliku musi
mieć wszystkie bity, które są ustawione w podanej
wartości, ^, określający,
że wartość z pliku musi mieć wyzerowane
wszystkie bity, które są ustawione w podanej
wartości, lub ~,
określający, że podana wartość ma
zostać zanegowana przed przetestowaniem.
x, określa, że pasować
może dowolna wartość. Jeśli znak operacji
jest pominięty, używany jest =.
Operatory &, ^ i
~ nie działają z liczbami
zmiennoprzecinkowymi i typu double. Operator !
określa, że wiersz zostanie dopasowany jeśli test
nie powiedzie
się.
Wartości numeryczne są podawane w postaci
zgodnej z językiem C, np. 13 to liczba
dziesiętna, 013 to liczba
ósemkowa, a 0x13 to liczba
szesnastkowa.
Operacje numeryczne nie są przeprowadzane na typach daty; wartość numeryczna jest zamiast tego interpretowana jako przesunięcie.
Dla wartości łańcuchowych,
łańcuch z pliku musi odpowiadać podanemu
łańcuchowi. Do łańcuchów mogą
być stosowane operatory =,
< i > (lecz nie
&). Długość,
używana do porównywania jest
długością argumentu łańcuchowego z
pliku magicznego. Znaczy to, że wiersz można
dopasować do dowolnego niepustego łańcucha (zwykle
używane do późniejszego wypisania
łańcucha), stosując >\0
(ponieważ wszystkie łańcuchy są
większe od łańcucha zerowego).
Daty są traktowane jako wartości numeryczne w odpowiedniej wewnętrznej reprezentacji.
Specjalny test x zawsze daje prawdę.
messageTwórcę i typ APPLE w formacie 4+4 znaków można podać jako:
!:apple CREATYPE
Listę powszechnych rozszerzeń plików, rozdzieloną ukośnikiem, można podać jako:
!:ext rozsz[/rozsz...]
tj. jako dosłowny łańcuch “!:ext”, po którym następuje lista powszechnych rozszerzeń plików, rozdzielona ukośnikiem; np. dla obrazów JPEG:
!:ext jpeg/jpg/jpe/jfif
Typ MIME jest podawany w osobnym wierszu, który musi wystąpić jako następny niepusty wiersz niebędący komentarzem po wierszu magii identyfikującym typ pliku; ma on następujący format:
!:mime TYPMIME
tj. dosłowny łańcuch “!:mime”, po którym następuje typ MIME.
W osobnym wierszu można podać opcjonalną siłę, która odnosi się do aktualnego opisu magii; korzysta z następującego formatu:
!:strength ARG WARTOŚĆ
Argumentem ARG może być:
+, -,
* lub /; natomiast
WARTOŚĆ jest stałą z
przedziału 0-255. Na aktualnie obliczonej domyślnej sile magii
przeprowadzane jest działanie podane w argumencie, którego
drugim elementem jest podana stała.
Niektóre formaty pliku zawierają dodatkowe informacje, które będą wypisane razem z typem pliku lub wymagają dodatkowych testów aby określić prawdziwy typ pliku. Te dodatkowe testy są wprowadzane za pomocą jednego lub wielu znaków > poprzedzających przesunięcie. Liczba znaków > w wierszu określa poziom testu; wiersz bez > na początku jest na poziomie 0. Testy są ułożone w hierarchii drzewiastej: jeśli test w wierszu na poziomie n powiedzie się, wykonywane są wszystkie kolejne testy na poziomie n+1, a komunikaty są wypisywane jeśli testy powiodą się, do momentu pojawienia się wiersza na poziomie n (lub niższym). W przypadku bardziej złożonych plików, można używać pustych komunikatów, aby uzyskać efektywną składnię „jeżeli/to”, w następującej postaci:
0 string MZ >0x18 uleshort <0x40 pl. wykonywalny MS-DOS >0x18 uleshort >0x3f rozsz. pl. wyk. PC (np. MS Windows)
Przesunięcia nie muszą być stałe, mogą być też odczytywane ze sprawdzanego pliku. Jeśli pierwszym znakiem po ostatnim > jest ( to łańcuch po nawiasie jest interpretowany jako niebezpośrednie przesunięcie. Oznacza to, że liczba po nawiasie jest używana jako przesunięcie w pliku. Wartość na jakiej przesunięcie jest odczytane, jest używana ponownie jako przesunięcie w pliku. Przesunięcia niebezpośrednie mają postać (x [[.,][bBcCeEfFgGhHiIlmosSqQ]][+-][ y ]). Wartość x służy jako przesunięcie w pliku. Bajt, długości id3 short lub long jest odczytywany na tym przesunięciu, w zależności od określenia typu [bBcCeEfFgGhHiIlLmsSqQ]. Wartość jest traktowana jako ze znakiem, jeśli podano „,” lub bez znaku, jeśli podano „.”. Typy pisane wielką literą są interpretowane jako wartość big endian, a małe litery reprezentują wartość liczbową little endian; typ m interpretuje liczbę jako wartość middle endian (PDP-11). Do tej liczby dodawana jest wartość y, a wynik służy jako przesunięcie w pliku. Domyślnym typem, jeśli się go nie określi, jest long. Rozpoznawane są poniższe typy:
| Typ | Skrót od | Kol. baj. Rozmiar | |
| bcBC | Byte/Char | N/A | 1 |
| efg | Double | Little | 8 |
| EFG | Double | Big | 8 |
| hs | Half/Short | Little | 2 |
| HS | Half/Short | Big | 2 |
| i | ID3 | Little | 4 |
| I | ID3 | Big | 4 |
| l | Long | Little | 4 |
| L | Long | Big | 4 |
| m | Middle | Middle | 4 |
| o | Octal | Tekstowa | Zmienny |
| q | Quad | Little | 8 |
| Q | Quad | Big | 8 |
W ten sposób można sprawdzić struktury o zmiennej długości:
# Pliki wykonywalne MS Windows są też prawidłowymi pl. wyk. MS-DOS 0 string MZ >0x18 uleshort <0x40 Wykonywalny MZ (MS-DOS) # pomiń poniższy blok, jeśli nie jest rozszerzonym pl. wykonywalnym >0x18 uleshort >0x3f >>(0x3c.l) string PE\0\0 Wykonywalny PE (MS-Windows) >>(0x3c.l) string LX\0\0 Wykonywalny LX (OS/2)
Ten sposób ma swoje wady: trzeba się upewnić, że na końcu coś się wypisze albo użytkownicy mogą otrzymać puste wyjście (np. gdy w powyższym przykładzie nie jest to ani PE\0\0 ani LE\0\0).
Jeśli nie da się bezpośrednio zastosować tego niebezpośredniego przesunięcia, możliwe są proste obliczenia: dołączenie [+-*/%&|^]liczba wewnątrz nawiasów pozwala na modyfikację wartości odczytanej z pliku, zanim zostanie użyta jako przesunięcie:
# Pliki wykonywalne MS Windows są też prawidłowymi pl. wyk. MS-DOS 0 string MZ # czasem, wartość na 0x18 ma mniej niż 0x40 lecz wciąż jest to rozsz. # plik wykonywalny, zatem po prostu dodajemy do pliku >0x18 uleshort <0x40 >>(4.s*512) leshort 0x014c Wykonywalny COFF (MS-DOS, DJGPP) >>(4.s*512) leshort !0x014c Wykonywalny MZ (MS-DOS)
Czasem dokładne przesunięcie nie jest znane, ponieważ zależy ono od długości lub pozycji (tam gdzie wcześniej używano przesunięć niebezpośrednich) poprzednich pól. Można podać przesunięcie względem końca ostatniego pola wyższego poziomu za pomocą ‘&’ stosowanego jako przedrostek przesunięcia:
0 string MZ >0x18 uleshort >0x3f >>(0x3c.l) string PE\0\0 Wykonywalny PE (MS-Windows) # po którym występuje podpis PE będący typem procesora >>>&0 leshort 0x14c dla Intel 80386 >>>&0 leshort 0x8664 dla x86-64 >>>&0 leshort 0x184 dla DEC Alpha
Przesunięcia niebezpośrednie i względne można łączyć:
0 string MZ >0x18 uleshort <0x40 >>(4.s*512) leshort !0x014c Wykonywalny MZ (MS-DOS) # jeśli to nie COFF, cofnij się o 512 bajtów i dodaj przesunięcie # z bajtu 2/3, które stanowi inny sposób znalezienia początku # rozszerzonego pliku wykonywalnego >>>&(2.s-514) string LE Wykonywalny LE (ster. MS Windows VxD)
Lub na odwrót:
0 string MZ >0x18 uleshort >0x3f >>(0x3c.l) string LE\0\0 Wykonywalny LE (MS-Windows) # na przesunięciu 0x80 (-4, ponieważ przesun. względne zaczynają się od # końca dopasowania wyższego poziomu) wewnątrz nagłówka LE, znajdujemy # absolutne przes. do kodu obszaru, gdzie szukamy określonego podpisu >>>(&0x7c.l+0x26) string UPX \b, skompresowany UPX
Lub podać oba!
0 string MZ >0x18 uleshort >0x3f >>(0x3c.l) string LE\0\0 Wykonywalny LE (MS-Windows) # na przesunięciu 0x58 w nagłówku LE, znajdujemy przesunięcie względne do # obszaru danych, gdzie szukamy określonego podpisu >>>&(&0x54.l-3) string UNACE \b, samorozp. się archiwum ACE
Jeśli w pliku zachodzi konieczność radzenia sobie z duetami przesunięcie/długość, z samego pliku można pobrać nawet drugą wartość w wyrażeniu w nawiasie, za pomocą kolejnego zestawu nawiasów. Proszę zauważyć, że to dodatkowe przesunięcie niebezpośrednie jest zawsze względem początku głównego przesunięcia niebezpośredniego.
0 string MZ >0x18 uleshort >0x3f >>(0x3c.l) string PE\0\0 Wykonywalny PE (MS-Windows) # szukamy sekcji PE o nazwie ".idata"... >>>&0xf4 search/0x140 .idata # ...i przechodzimy na jej koniec, obliczony jako początek+długość; # są one zlokalizowane 14 i 10 bajtów po nazwie sekcji >>>>(&0xe.l+(-4)) string PK\3\4 \b, archiwum samorozp. ZIP
Jeśli ma się listę znanych wartości na określonym poziomie kontynuacji i chce się udostępnić domyślny przypadek w postaci przełącznikowej:
# wyczyść dopasowania danego poziomu kontynuacji >18 clear x >18 lelong 1 jeden >18 lelong 2 dwa >18 default x # wypisz domyślne dopasowanie >>18 lelong x niedopasowane 0x%x
file(1) - polecenie odczytujące ten plik.
Formaty long,
belong, lelong,
melong, short,
beshort i leshort nie
zależą od długość typów danych C
short i long na platformie,
choć Single UNIX Specification implikuje,
że zależą. Jednak ponieważ OS X Mountain Lion
przeszedł zestaw walidacji Single UNIX
Specification i dostarcza wersję file(1) w
której brak jest zależności od rozmiarów
typów danych C oraz która jest zbudowana dla środowiska
64-bitowego, w którym long ma 8
bajtów, a nie 4, być może zestaw walidujący nie
sprawdza czy np. long odnosi się to elementu
o tym samym rozmiarze, co typ danych C long.
Prawdopodobnie powinny występować nazwy
type takie jak int8,
uint8, int16,
uint16, int32,
uint32, int64 i
uint64 oraz warianty o określonej
kolejności bajtów tychże, aby było jasne,
że typy te mają określoną
szerokość.
Tłumaczenie niniejszej strony podręcznika: Przemek Borys <pborys@dione.ids.pl>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net
| 27 listopada 2024 r. | Debian |