
🕵️ अज्ञात परिभाषा वाले प्रोटोकॉल बफ़र्स को रीवर्स-इंजीनियर करने का टूल
सरल प्रोग्राम जो Google Protobuf एन्कोडेड ब्लॉब्स (संस्करण 2 या 3) को उनकी साथ की परिभाषा जाने बिना पार्स कर सकता है। यह उनकी सामग्री का एक अच्छा, रंगीन प्रतिनिधित्व प्रिंट करेगा। उदाहरण:

जैसा कि आप देख सकते हैं, फ़ील्ड नाम स्पष्ट रूप से खो जाते हैं, साथ ही कुछ उच्च-स्तरीय विवरण जैसे:
लेकिन protobuf-inspector अधिकांश समय संदेश संरचना का सही अनुमान लगाने में सक्षम है। जब यह किसी फ़ील्ड पर एम्बेडेड बाइनरी डेटा पाता है, तो यह पहले इसे एक संदेश के रूप में पार्स करने का प्रयास करेगा। यदि वह विफल रहता है, तो यह डेटा को स्ट्रिंग या हेक्सडंप के रूप में प्रदर्शित करेगा। यह गलतियाँ कर सकता है, विशेष रूप से छोटे हिस्सों के साथ।
यह फ़ील्ड को उसी क्रम में दिखाता है जिस क्रम में वे वायर पर एन्कोडेड हैं, इसलिए यह उन लोगों के लिए उपयोगी हो सकता है जो wire format से परिचित होना चाहते हैं या पार्सर डेवलपर्स के लिए, रिवर्स-इंजीनियरिंग के अलावा।
आप pip से इंस्टॉल कर सकते हैं:
pip install protobuf-inspector
यह protobuf_inspector कमांड इंस्टॉल करता है। इसे चलाएँ, stdin पर प्रोटोबफ ब्लॉब फीड करें:
protobuf_inspector < my-protobuf-blob
ब्लॉब के पहले (ब्लाइंड) विश्लेषण को पढ़ने के बाद, आप आम तौर पर कुछ फ़ील्ड को परिभाषित करना शुरू करते हैं ताकि protobuf-inspector आपके ब्लॉब्स को बेहतर ढंग से पार्स कर सके, जब तक आप एक ऐसे बिंदु पर नहीं पहुँच जाते जहाँ आपके पास पूर्ण प्रोटोबफ परिभाषा है और पार्सर को कुछ भी अनुमान लगाने की आवश्यकता नहीं है।
यहाँ फ़ील्ड परिभाषित करने के बारे में पढ़ें।
यदि पार्सिंग त्रुटि पाई जाती है, तो पार्सिंग उस फ़ील्ड के भीतर रुक जाएगी, लेकिन पदानुक्रम के बाहर अप्रभावित रहेगी। स्टैक ट्रेस वहां प्रिंट किया जाएगा जहाँ फ़ील्ड सामग्री जाएगी, साथ ही एक हेक्सडंप जो इंगित करता है कि उस हिस्से में पार्सिंग कहाँ रुकी थी, यदि लागू हो।
इसलिए, यदि आपने uint32 निर्दिष्ट किया और एक बड़ा varint पाया जाता है, तो आपको कुछ इस तरह मिलेगा:

यदि आपने निर्दिष्ट किया कि किसी फ़ील्ड में एक एम्बेडेड संदेश है, लेकिन वहां अमान्य डेटा पाया गया, तो आपको मिलेगा:

कृपया ध्यान दें कि यदि एक या अधिक पार्सिंग त्रुटियाँ हुईं तो main.py गैर-शून्य स्थिति के साथ बाहर निकलेगा।
ब्लॉब के पास जाने पर समय बचाने के लिए कुछ ट्रिक्स हैं:
यदि आप सुनिश्चित हैं कि एक varint zig-zag एन्कोडिंग का नहीं उपयोग करता है, लेकिन फिर भी हस्ताक्षर के बारे में निश्चित नहीं हैं, तो इसे varint के रूप में छोड़ दें। यदि यह zig-zag एन्कोडिंग का उपयोग करता है, तो sint64 का उपयोग करें जब तक कि आप सुनिश्चित न हों कि यह 32-बिट है और 64-बिट नहीं।
यदि कोई हिस्सा गलत तरीके से packed chunk या एम्बेडेड संदेश के रूप में पहचाना जा रहा है, या यदि आप पार्स किए गए संदेश में कुछ अजीब देखते हैं और कच्चे बाइट्स देखना चाहते हैं, तो bytes का प्रकार निर्दिष्ट करें। इसके विपरीत, यदि किसी कारण से इसका एम्बेडेड संदेश के रूप में पता नहीं लगाया जा रहा है और इसे लगाया जाना चाहिए, तो कारण देखने के लिए इसे message पर बाध्य करें।
यदि आप किसी हिस्से के कच्चे डेटा को बेहतर विश्लेषण के लिए फ़ाइल में निकालना चाहते हैं, तो dump का प्रकार निर्दिष्ट करें और protobuf-inspector हर बार एक मिलान ब्लॉब मिलने पर dump.0, dump.1, आदि बनाएगा।
protobuf-inspector ब्लॉब को root प्रकार के संदेश के रूप में पार्स करता है, लेकिन यह सिर्फ एक डिफ़ॉल्ट है। यदि आपके पास कई संदेश प्रकार परिभाषित हैं, तो आप वैकल्पिक तर्क के रूप में एक प्रकार का नाम पास कर सकते हैं, और protobuf-inspector root के बजाय उसका उपयोग करेगा:
सरल उदाहरण:
from protobuf_inspector.types import StandardParser
parser = StandardParser()
with open('my-blob', 'rb') as fh:
output = parser.parse_message(fh, "message")
print(output)
हालाँकि, यह प्रोजेक्ट शुरू में लाइब्रेरी के रूप में उपयोग के लिए डिज़ाइन नहीं किया गया था, और इसका API बदल सकता है। अधिक जटिल उदाहरण के लिए, protobuf_inspector/__main__.py देखें।
protobuf_inspector request < my-protobuf-blob