Binary फ़ाइल formats के भीतर: PNG, ZIP, और Mach-O headers की व्याख्या
हर फ़ाइल format जिसे आप रोज़ इस्तेमाल करते हैं, image, archive, executable, की एक संरचना होती है जो byte तक परिभाषित होती है, और उस संरचना का लगभग कुछ भी उन उपकरणों के ज़रिए दिखाई नहीं देता जिनसे आप आमतौर पर वे फ़ाइलें खोलते हैं। Preview आपको एक तस्वीर दिखाता है। Archive Utility आपको निकाली गई फ़ाइलें दिखाता है। इनमें से कोई भी वे bytes नहीं दिखाता जिन्होंने उन परिणामों को संभव बनाया। यहाँ बताया गया है कि तीन आम formats नीचे से वास्तव में कैसे दिखते हैं, और आप उन्हें खुद कैसे देख सकते हैं।
PNG: labeled chunks का एक अनुक्रम
हर PNG फ़ाइल उन्हीं आठ bytes से शुरू होती है: 89 50 4E 47 0D 0A 1A 0A। वह image data नहीं है, वह एक signature है, जानबूझकर एक ऐसे byte को शामिल करने के लिए चुनी गई जो फ़ाइल के गलती से text के रूप में ट्रांसफ़र होने पर अनुपयोगी हो जाता है (0x0A और 0x0D newline अक्षर हैं, इसलिए एक टूटा हुआ text-mode ट्रांसफ़र उन्हें इस तरह दूषित करता है जिसे पहचानना आसान है)।
Signature के बाद, एक PNG में सब कुछ एक chunk है, और हर chunk उसी चार-भाग वाले लेआउट का पालन करता है:
- Length (4 bytes): इसके बाद कितने bytes का data आता है, type या CRC को छोड़कर।
- Type (4 bytes, हमेशा ASCII): एक चार-अक्षरों वाला कोड जैसे
IHDR(image header, हमेशा पहला),IDAT(compressed pixel data, कई हो सकते हैं), याIEND(फ़ाइल के अंत को चिह्नित करता है)। - Data: जो कुछ भी वह chunk type निर्दिष्ट करता है।
IHDRका data चौड़ाई, ऊँचाई, bit depth, और color type है, हमेशा वही निश्चित लेआउट। - CRC (4 bytes): type और data का एक checksum, ताकि एक decoder किसी दूषित chunk को चुपचाप गलत पढ़ने के बजाय पहचान सके।
यही पूरा format है। एक PNG decoder बस एक के बाद एक chunk चलता है, यह जानने के लिए length पढ़ता है कि कितनी दूर छोड़ना है, जब तक कि वह IEND तक न पहुँचे।
ZIP: local headers, फिर अंत में एक directory
एक ZIP archive हर फ़ाइल को उसके अपने local file header के साथ संग्रहीत करता है, जो signature 50 4B 03 04 से चिह्नित होता है (शुरुआत में PK format के निर्माता Phil Katz का एक संदर्भ है)। उस header में फ़ाइल का नाम, compression method, और compressed तथा uncompressed दोनों आकार शामिल होते हैं, जिसके तुरंत बाद फ़ाइल का compressed data आता है।
जो हिस्सा लोगों को उलझाता है: local header में वे प्रति-फ़ाइल आकार और checksums कभी-कभी शून्य होते हैं, जिनके असली मान बाद में एक “data descriptor” में संग्रहीत होते हैं, क्योंकि ZIP को streaming writes का समर्थन करने के लिए डिज़ाइन किया गया था जहाँ अंतिम आकार तब तक ज्ञात नहीं होता जब तक data पहले से लिखा न जा चुका हो। archive में वास्तव में क्या है इसकी निश्चित सूची फ़ाइल के बिल्कुल अंत में एक central directory में रहती है, यही वजह भी है कि कुछ दूषित या कटे हुए ZIP ऐसे दिख सकते हैं जैसे शुरुआत से स्कैन करने पर उनमें सामग्री हो, लेकिन खुलने में विफल रहते हैं, क्योंकि आप जो उपकरण इस्तेमाल कर रहे हैं वह पहले central directory पढ़ता है और वह गायब या क्षतिग्रस्त है।
Mach-O: magic number, फिर load commands
Mach-O वह executable format है जिसे macOS compiled binaries के लिए इस्तेमाल करता है। यह एक magic number से शुरू होता है जो एक loader को एक साथ दो बातें बताता है: यह 32-bit है या 64-bit, और फ़ाइल का बाकी हिस्सा किस byte order का उपयोग करता है। 0xFEEDFACE 32-bit है, 0xFEEDFACF 64-bit है, और अगर आप bytes को उलटा देखते हैं (0xCEFAEDFE या 0xCFFAEDFE), तो इसका मतलब है कि फ़ाइल उस मशीन से विपरीत byte order में लिखी गई थी जो उसे पढ़ रही है।
Magic number के बाद एक निश्चित header आता है (CPU type, file type, और load commands की एक गिनती), जिसके बाद उतने ही load commands क्रम में आते हैं। Load commands वह तरीका हैं जिससे एक Mach-O फ़ाइल वह सब कुछ वर्णित करती है जो loader को चाहिए: कौन से segments memory में map करने हैं, कौन सी dynamic libraries link करनी हैं, entry point कहाँ है। यह PNG के chunks जैसा ही विचार है: एक निश्चित header, फिर स्वयं-वर्णन करने वाले records का एक अनुक्रम, हर एक पाठक को बताता है कि अगले तक पहुँचने के लिए कितना छोड़ना है।
इसे खुद देखना
इसमें से किसी के लिए एक parser लिखने की ज़रूरत नहीं है। Hexter में कोई भी PNG, ZIP, या Mach-O फ़ाइल खोलें और Analyze टैब format को अपने आप पहचान लेता है, असली chunk या load-command संरचना को चलाते हुए और उसे कच्चे hex के बगल में एक tree के रूप में दिखाते हुए, ताकि आप एक field पर क्लिक कर सकें और ठीक-ठीक देख सकें कि वह किन bytes से आया। यह डिफ़ॉल्ट रूप से read-only है, इसलिए यह एक असली फ़ाइल पर सचमुच सुरक्षित है, एक ऐप binary, एक screenshot, एक archive जो आपने डाउनलोड किया, उसे बदलने के किसी जोखिम के बिना।
अगर आप ऊपर बताई गई बातों को इसके बजाय हाथ से सत्यापित करना चाहते हैं: एक PNG खोलें और जाँचें कि पहले आठ bytes signature से मेल खाते हैं, फिर bytes 8 से 11 (पहले chunk की length) और bytes 12 से 15 (उसका type, जो IHDR पढ़ना चाहिए) देखें। यह कुछ ही मिनटों में करने के लिए एक काफ़ी छोटा अभ्यास है, और यह एक ऐसे फ़ाइल format को समझने का एक सचमुच उपयोगी तरीका है जिसे आपने ज़िंदगी भर इस्तेमाल किया है लेकिन कभी वास्तव में देखा नहीं।