
BARF : एक बहु-प्लेटफ़ॉर्म ओपन सोर्स बाइनरी विश्लेषण और रिवर्स इंजीनियरिंग फ्रेमवर्क
बाइनरी कोड का विश्लेषण कंप्यूटर विज्ञान और सॉफ्टवेयर इंजीनियरिंग के कई क्षेत्रों में एक महत्वपूर्ण गतिविधि है, जिसमें सॉफ्टवेयर सुरक्षा और प्रोग्राम विश्लेषण से लेकर रिवर्स इंजीनियरिंग तक शामिल है। मैन्युअल बाइनरी विश्लेषण एक कठिन और समय लेने वाला कार्य है, और ऐसे सॉफ्टवेयर उपकरण हैं जो मानव विश्लेषकों को स्वचालित या सहायता करने का प्रयास करते हैं। हालाँकि, इनमें से अधिकांश उपकरणों में कई तकनीकी और व्यावसायिक प्रतिबंध हैं जो शैक्षणिक और व्यवसायी समुदायों के एक बड़े हिस्से तक पहुँच और उपयोग को सीमित करते हैं। BARF एक ओपन सोर्स बाइनरी विश्लेषण फ्रेमवर्क है जिसका उद्देश्य सूचना सुरक्षा अनुशासन में सामान्य बाइनरी कोड विश्लेषण कार्यों की एक विस्तृत श्रृंखला का समर्थन करना है। यह एक स्क्रिप्टेबल प्लेटफॉर्म है जो कई आर्किटेक्चर से इंस्ट्रक्शन लिफ्टिंग, एक इंटरमीडिएट रिप्रेजेंटेशन में बाइनरी अनुवाद, कोड विश्लेषण प्लगइन्स के लिए एक एक्सटेंसिबल फ्रेमवर्क और डीबगर्स, SMT सॉल्वर्स और इंस्ट्रुमेंटेशन टूल्स जैसे बाहरी उपकरणों के साथ इंटरऑपरेशन का समर्थन करता है। फ्रेमवर्क मुख्य रूप से मानव-सहायक विश्लेषण के लिए डिज़ाइन किया गया है लेकिन इसे पूरी तरह से स्वचालित किया जा सकता है।
BARF प्रोजेक्ट में BARF और संबंधित उपकरण और पैकेज शामिल हैं। अब तक इस परियोजना में निम्नलिखित आइटम शामिल हैं:
अधिक जानकारी के लिए देखें:
वर्तमान स्थिति:
| नवीनतम रिलीज़ | v0.6.0 |
|---|---|
| URL | https://github.com/programa-stic/barf-project/releases/tag/v0.6.0 |
| परिवर्तन लॉग | https://github.com/programa-stic/barf-project/blob/v0.6.0/CHANGELOG.md |
सभी पैकेज Ubuntu 16.04 (x86_64) पर परीक्षण किए गए थे।
BARF बाइनरी विश्लेषण और रिवर्स इंजीनियरिंग के लिए एक Python पैकेज है। यह कर सकता है:
ELF, PE, आदि) में बाइनरी प्रोग्राम लोड करना,यह वर्तमान में विकास के अधीन है।
BARF निम्नलिखित SMT सॉल्वर्स पर निर्भर करता है:
निम्नलिखित कमांड आपके सिस्टम पर BARF स्थापित करता है:
$ sudo python setup.py install
आप इसे स्थानीय रूप से भी स्थापित कर सकते हैं:
$ sudo python setup.py install --user
sudo pip install pyasmjitsudo apt-get install graphvizयह एक बहुत ही सरल उदाहरण है जो दिखाता है कि बाइनरी फ़ाइल कैसे खोलें और प्रत्येक निर्देश को उसके इंटरमीडिएट भाषा (REIL) में अनुवाद के साथ प्रिंट करें।
from barf import BARF
# बाइनरी फ़ाइल खोलें।
barf = BARF("examples/misc/samples/bin/branch4.x86")
# असेंबली निर्देश प्रिंट करें।
for addr, asm_instr, reil_instrs in barf.translate():
print("{:#x} {}".format(addr, asm_instr))
# REIL अनुवाद प्रिंट करें।
for reil_instr in reil_instrs:
print("\t{}".format(reil_instr))
हम CFG को पुनर्प्राप्त भी कर सकते हैं और इसे .dot फ़ाइल में सहेज सकते हैं।
# CFG पुनर्प्राप्त करें।
cfg = barf.recover_cfg()
# CFG को .dot फ़ाइल में सहेजें।
cfg.save("branch4.x86_cfg")
हम SMT सॉल्वर का उपयोग करके कोड पर प्रतिबंधों की जांच कर सकते हैं। उदाहरण के लिए, मान लें कि आपके पास निम्नलिखित कोड है:
80483ed: 55 push ebp
80483ee: 89 e5 mov ebp,esp
80483f0: 83 ec 10 sub esp,0x10
80483f3: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
80483f6: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc]
80483f9: 01 d0 add eax,edx
80483fb: 83 c0 05 add eax,0x5
80483fe: 89 45 fc mov DWORD PTR [ebp-0x4],eax
8048401: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048404: c9 leave
8048405: c3 ret
और आप जानना चाहते हैं कि कोड निष्पादित करने के बाद eax रजिस्टर में एक विशिष्ट मान प्राप्त करने के लिए आपको मेमोरी स्थानों ebp-0x4, ebp-0x8 और ebp-0xc में कौन से मान निर्दिष्ट करने होंगे।
सबसे पहले, हम निर्देशों को विश्लेषक घटक में जोड़ते हैं।
from barf import BARF
# ELF फ़ाइल खोलें
barf = BARF("examples/misc/samples/bin/constraint1.x86")
# विश्लेषण करने के लिए निर्देश जोड़ें।
for addr, asm_instr, reil_instrs in barf.translate(0x80483ed, 0x8048401):
for reil_instr in reil_instrs:
barf.code_analyzer.add_instruction(reil_instr)
फिर, हम प्रत्येक रुचि के चर के लिए व्यंजक उत्पन्न करते हैं और उन पर वांछित प्रतिबंध जोड़ते हैं।
ebp = barf.code_analyzer.get_register_expr("ebp", mode="post")
# पूर्व शर्तें: चर a और b के लिए श्रेणी निर्धारित करें
a = barf.code_analyzer.get_memory_expr(ebp-0x8, 4, mode="pre")
b = barf.code_analyzer.get_memory_expr(ebp-0xc, 4, mode="pre")
for constr in [a >= 2, a <= 100, b >= 2, b <= 100]:
barf.code_analyzer.add_constraint(constr)
# पश्च शर्तें: परिणाम के लिए वांछित मान निर्धारित करें
c = barf.code_analyzer.get_memory_expr(ebp-0x4, 4, mode="post")
for constr in [c >= 26, c <= 28]:
barf.code_analyzer.add_constraint(constr)
अंत में, हम जांचते हैं कि क्या हमारे द्वारा स्थापित प्रतिबंधों को हल किया जा सकता है।
if barf.code_analyzer.check() == 'sat':
print("[+] संतोषजनक! संभावित असाइनमेंट:")
# व्यंजकों के लिए ठोस मान प्राप्त करें
a_val = barf.code_analyzer.get_expr_value(a)
b_val = barf.code_analyzer.get_expr_value(b)
c_val = barf.code_analyzer.get_expr_value(c)
# मान प्रिंट करें
print("- a: {0:#010x} ({0})".format(a_val))
print("- b: {0:#010x} ({0})".format(b_val))
print("- c: {0:#010x} ({0})".format(c_val))
assert a_val + b_val + 5 == c_val
else:
print("[-] असंतोषजनक!")
आप इन और अधिक उदाहरणों को examples निर्देशिका में देख सकते हैं।
फ्रेमवर्क तीन मुख्य घटकों में विभाजित है: core, arch और analysis।
इस घटक में आवश्यक मॉड्यूल शामिल हैं: