
रजिस्टर उपयोग फ्रेम के विश्लेषण के लिए IDA प्लगइन और स्क्रिप्ट

"""
यह रजिस्टर किसके लिए उपयोग होता है?
हम्म.. मैं इसे बहुत ही अनोखे नाम में बदल दूंगा, एक टेक्स्टुअल खोज करूंगा, और सभी संदर्भ ढूंढूंगा!
ठीक.. खोज समाप्त होने की प्रतीक्षा कर रहा हूं.. अब कोई भी पल.. हो गया!
अब मुझे बस यह समझना है कि खोज परिणामों में से कौन सा रजिस्टर के वर्तमान उपयोग फ्रेम से संबंधित है।
कठिन नहीं होना चाहिए, है ना?
"""
अगर आपके साथ ऐसा हुआ है (शायद एक से अधिक बार), तो आपके लिए एक अच्छा मौका है!
बस Shift-X दबाएं, और आपकी परेशानियां दूर हो जाएंगी!
आप उपयोग फ्रेम में रजिस्टर का नाम भी बदल सकते हैं (re(g)name)। बस Shift-N दबाएं, और निर्देशों का पालन करें!
साथ ही - सभी उपयोगों के प्रकारों को एक निश्चित प्रकार में बदलने के बजाय, बस एक बार Shift-T दबाएं।
और अंतिम लेकिन महत्वपूर्ण - यदि आप इस रजिस्टर के सभी उपयोगों के लिए एक ऑफसेट (Ctrl-R करने जैसा) सेट करना चाहते हैं, तो बस Shift-R दबाएं।
नोट: कभी-कभी कोई और प्लगइन पहले से Shift-T का उपयोग कर रहा होता है। उस प्लगइन को हटा दें - आपने वैसे भी इसका कभी उपयोग नहीं किया :-)।
यह प्लगइन IDA स्क्रिप्ट्स के साथ आराम से इंटरैक्ट करने के लिए sark का उपयोग करता है, और फ्रेम स्कैन को कैश करने के लिए cachetools का उपयोग करता है, जिससे यह बहुत तेज़ हो जाता है।
Oregami IDA 7.x/8.x और IDA 9.0+ दोनों का समर्थन करता है।
यदि आप IDA 9 का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आपके पास sark का एक अद्यतित संस्करण है जो IDA 9 को समर्थन करता है।
नोट: IDA 9 ने अपनी खुद की Shift-X कार्यक्षमता पेश की है। यदि आपको oregami के बजाय IDA के अंतर्निहित Shift-X का उपयोग करने की आवश्यकता है, तो आपको प्लगइन फ़ाइल में oregami शॉर्टकट बदलना चाहिए।
[पायथन3 के लिए]
pip3 install sark
[पायथन2 के लिए]
यदि IDA के python2 संस्करण का उपयोग कर रहे हैं, तो आपको इसके बजाय यह चलाना चाहिए:
pip2 install -U git+https://github.com/tmr232/[email protected]#egg=Sark
ध्यान दें कि python2 सक्रिय रूप से समर्थित नहीं है (जैसा कि IDA अधिकतर python3 में स्थानांतरित हो गया है, और मैंने भी ऐसा किया है), इसलिए यह काम नहीं कर सकता है।
git clone https://github.com/shemesh999/oregami
sark कोडबेस कई प्लगइन्स प्रदान करता है। उनमें से एक है: https://github.com/tmr232/Sark/blob/master/plugins/plugin_loader.py
हम अनुशंसा करते हैं कि इसे अपने प्लगइन्स निर्देशिका में कॉपी करें और फिर IDA को एक बार व्यवस्थापक विशेषाधिकारों के साथ चलाएं (ताकि यह plugins.list फ़ाइलें बना सके)।
ऐसा करने के बाद, आप प्लगइन्स.लिस्ट फ़ाइलों में से किसी एक में उनका पथ जोड़कर नए प्लगइन्स जोड़ सकते हैं (जैसे, एक IDA के cfg फ़ोल्डर में बनाई गई है)
अब, plugins.list फ़ाइलों में से एक में जोड़ें:
FULLPATH\oregami\oregami_plugin.py
FULLPATH\oregami\regname_plugin.py
FULLPATH\oregami\typeregter_plugin.py
FULLPATH\oregami\offreg_plugin.py
IDA को पुनरारंभ करें, और प्लगइन्स काम करने चाहिए।
वैकल्पिक रूप से:
सभी फ़ाइलें (आंतरिक oregami फ़ोल्डर सहित, setup.py को छोड़कर) IDA प्लगइन्स निर्देशिका में कॉपी करें।
प्लगइन्स के रूप में उपयोग किए जाने के अलावा, oregami का उपयोग आपकी अपनी स्क्रिप्ट लिखने के लिए भी किया जा सकता है!
इसके लिए, आपको पहले शामिल setup.py फ़ाइल का उपयोग करके इंस्टॉल करना चाहिए। इसका मतलब है कि आपको कॉल करना चाहिए:
'python setup.py develop', और तब से आप आंतरिक क्लासेस और फ़ंक्शन का उपयोग कर सकते हैं।
ध्यान दें कि हम 'install' के बजाय 'develop' का उपयोग करने की सलाह देते हैं, ताकि यदि आप oregami का नया संस्करण खींचते हैं, तो यह तुरंत काम करेगा।
उदाहरण के लिए:
-- script.py --
def find_func_usage(func_ea, reg='r0'):
"""
Find and print all usages of a register, including the information of the specific operands
it is in, and what operation it does in the operand.
"""
import oregami
rf = oregami.RegFrame(func_ea, reg)
for insn in rf.get_instructions():
print('Addr:{:x}'.format(insn.ea))
for opnd in insn.operands:
if opnd.uf_is_external:
continue
print('--opnd_idx:{} - {}'.format(opnd.n, oregami.UsageBits(opnd.op_flags)))
मान लें कि निम्नलिखित ऑपकोड अनुक्रम है:
ROM:01000010 e_lis r10, 0x4004 # 0x40040000 # Load Immediate Shifted
ROM:01000014 e_add16i r10, r10, 0x1337 # 0x40041337 # Add Immediate
ROM:01000020 se_mr r30, r31 # Move Register
ROM:01000022 cmplw r11, r10 # Compare Logical Word
ROM:01000026 se_bge loc_1000036 # Branch if greater than or equal
ROM:01000028
ROM:01000028 loc_1000028: # CODE XREF: sub_0100000+144↓j
ROM:01000028 e_stmw r30, 0(r11) # Store Multiple Word
ROM:0100002C e_add16i r11, r11, 8 # Add Immediate
ROM:01000030 cmplw r11, r10 # Compare Logical Word
ROM:01000034 se_blt loc_1000028 # Branch if less than
ROM:01000036
ROM:01000036 loc_1000036: # CODE XREF: sub_0100000+136↑j
ROM:01000036 e_add16i r10, r10, 8 # Add Immediate
ROM:0100003A e_li r11, 0 # Load Immediate
यदि हम r10 रजिस्टर के उपयोग फ्रेम को पता 01000022 से स्कैन करते हैं, तो हम उपयोग फ्रेम में तीन प्रकार के उपयोग पाएंगे।
इसमें वे निर्देश शामिल होंगे जो रजिस्टर के मान को प्रारंभ करते हैं।
हम केवल अंतिम निर्देश शामिल करना चाह सकते हैं जिसने रजिस्टर मान बदला (उदाहरण में पता 01000014), या रजिस्टर का प्रारंभिक मान सेट करने के लिए उपयोग किए गए संचालन का एक अनुक्रम (उदाहरण में पते 01000010 और 01000014)।
रजिस्टर प्रारंभीकरण में उपयोग किए गए संचालन के अनुक्रम को "init stage" कहा जा सकता है।
आप RegFrame प्रारंभीकरण में पैरामीटर init_stage_bool के आधार पर init stage का समर्थन करने या न करने का चुनाव कर सकते हैं।
इसमें वे निर्देश शामिल होंगे जो रजिस्टर के मान का उपयोग करते हैं, और इसे किसी भी तरह से नहीं बदलते हैं। ये उदाहरण में पंक्तियों 01000022 और 01000030 के अनुरूप हैं।
इसमें वे निर्देश शामिल होंगे जो रजिस्टर के मान का उपयोग करते हैं, लेकिन फिर इसका मान बदल देते हैं। इन निर्देशों को दो अलग-अलग उपयोग फ्रेमों में शामिल माना जा सकता है - वह जो उनकी ओर ले जाता है, और वह जो उनसे उत्पन्न होता है।
यह उदाहरण में पंक्ति 01000036 से मेल खाता है।
उपयोग रजिस्टर को स्कैन करते समय, किसी init ऑपरेशन या break ऑपरेशन तक पहुंचने से हम एक निश्चित दिशा में स्कैन करना बंद कर देंगे।
लेकिन, हम उपयोग फ्रेम के बाहर के निर्देशों के कारण भी स्कैन रोक सकते हैं।
उदाहरण के लिए, r11 रजिस्टर के उपयोग फ्रेम को पता 01000030 से स्कैन करना पंक्ति 0100003A पर रुक जाएगा।
यह oregami में उपयोग की जाने वाली मूल क्लास है। इसे एक पते और विशिष्ट रजिस्टर पर प्रारंभ करके, यह रजिस्टर के उपयोग फ्रेम को स्कैन करेगा, और सभी प्रासंगिक निर्देशों के लिए एक UFIntruction बनाएगा।
get_instruction - दिए गए पते से निर्देश प्राप्त करें
get_instructions - एक जनरेटर, उपयोग फ्रेम में निर्देश लौटाता है।
आप उपयोग किए गए निर्देशों के विशिष्ट उपसमूहों के लिए भी पूछ सकते हैं:
get_init_instructions - केवल init प्रकार के निर्देश प्राप्त करें
get_pure_instructions - केवल pure प्रकार के निर्देश प्राप्त करें
get_break_instructions - केवल break प्रकार के निर्देश प्राप्त करें
get_nobreak_instructions - केवल वे निर्देश प्राप्त करें जो break प्रकार के नहीं हैं (अर्थात init + pure)
get_noinit_instructions - केवल वे निर्देश प्राप्त करें जो init प्रकार के नहीं हैं (अर्थात pure + break)
get_outbreak_instructions - केवल out break प्रकार के निर्देश प्राप्त करें
डिफ़ॉल्ट रूप से यह क्लास स्कैन के परिणामों को कैश करेगा, और खुद को उसी उपयोग फ्रेम को पुन: स्कैन करने से रोकेगा। इसका मतलब है कि उपयोग फ्रेम का हिस्सा था (विशेष रूप से init + pure प्रकार के। Break नहीं, क्योंकि उन पर स्कैन शुरू करने से उनसे उत्पन्न होने वाला उपयोग फ्रेम वापस आना चाहिए) किसी भी निर्देश के RegFrame का अनुरोध करने से वही पूर्व-गणना किया गया RegFrame इंस्टेंस वापस आएगा। पुन: स्कैन करने के लिए बाध्य करने के लिए, क्लास को प्रारंभ करते समय force फ़्लैग का उपयोग करें।
यह RegFrame द्वारा लौटाई गई क्लास है, जो उपयोग फ्रेम में एक निर्देश का प्रतिनिधित्व करती है।
यह क्लास sark Instruction क्लास से इनहेरिट करती है, और इस प्रकार उन्हीं विधियों का समर्थन करती है।
एक मुख्य अंतर यह है कि इसमें sark Operand क्लास की एक operands सरणी होने के बजाय, इसमें UFOperand क्लास की एक सरणी होगी।
इस क्लास में निर्देश प्रकार (init, pure, break, outbreak) और संचालन बिट्स (read, write, explicit, और विभिन्न प्रकार के implicit) को समझने के लिए विधियाँ भी शामिल हैं।
यह एक विशिष्ट UFInstruction के अंदर operands सरणी में क्लास है।
यह क्लास sark Instruction क्लास से इनहेरिट करती है, और इस प्रकार उन्हीं विधियों का समर्थन करती है।
sark संचालन के अतिरिक्त, इसमें संचालन बिट्स (read, write, explicit, और विभिन्न प्रकार के implicit) प्राप्त करने के लिए विधियाँ हैं, और यह जानने के लिए कि क्या operand वास्तव में उपयोग फ्रेम का हिस्सा है (यह जानने के लिए उपयोगी कि break प्रकार के निर्देश में कौन सा operand उपयोग फ्रेम का हिस्सा है)।
यह एक क्लास है जो किसी विशिष्ट निर्देश का विश्लेषण करने के लिए उपयोग की जाती है, ताकि रजिस्टरों के संबंध में इसके उपयोग को जाना जा सके।
यह IDA, टेक्स्टुअल विश्लेषण, और प्रोसेसर के लिए विशिष्ट विवरण से ज्ञान का उपयोग करके ऐसा करता है।
इस क्लास का कारण यह है कि बुनियादी IDA विश्लेषण उपयोग किए गए रजिस्टरों के सेट के बारे में झूठ बोलता है, जिस तरह से वे कई ऑपकोड में उपयोग किए जाते हैं।
यह क्लास sark Instruction क्लास से इनहेरिट करती है, और इस प्रकार उन्हीं विधियों का समर्थन करती है।
एक मुख्य अंतर यह है कि इसमें sark Operand क्लास की एक operands सरणी होने के बजाय, इसमें RegOperand क्लास की एक सरणी होगी।
यह एक क्लास है जो किसी विशिष्ट operand का विश्लेषण करने के लिए उपयोग की जाती है, ताकि रजिस्टरों के संबंध में इसके उपयोग को जाना जा सके।
यह IDA, टेक्स्टुअल विश्लेषण, और प्रोसेसर के लिए विशिष्ट विवरण से ज्ञान का उपयोग करके ऐसा करता है।
इस क्लास का कारण यह है कि बुनियादी IDA विश्लेषण उपयोग किए गए रजिस्टरों के सेट के बारे में झूठ बोलता है, जिस तरह से वे कई ऑपकोड में उपयोग किए जाते हैं।
यह क्लास sark Operand क्लास से इनहेरिट करती है, और इस प्रकार उन्हीं विधियों का समर्थन करती है।