gdb

2012-12-25 16 views
5

में विशिष्ट ऑपोड के साथ निर्देश पर तोड़ें मेरे पास कुछ कोड का असेंबली कोड है जो प्रोग्राम में किसी बिंदु पर निष्पादित किया जाएगा। मुझे स्मृति में कोड का पता नहीं पता है।gdb

क्या वर्तमान निर्देश इनपुट निर्देश के साथ मेल खाता है तो क्या जीडीबी ब्रेक बनाना संभव है?

उदाहरण के लिए मैं जब भी gdb यह निर्देश तक पहुँच जाता है को तोड़ने के लिए GDB हैं:

leaq  0x000008eb(%rip),%rax 

उत्तर

2

नहीं, यह संभव नहीं है और यह भी लागू करने के लिए बहुत अक्षम हो जाएगा।

  • हार्डवेयर breakpoints: डिबगर स्मृति में कुछ स्थान की तरह जब कुछ घटना होती है एक विशेष अपवाद बाधा को बढ़ाने के लिए, बदल गया है सीपीयू पूछता

    डीबगर के आम तौर पर breakpoints के दो प्रकार का समर्थन है।

  • सॉफ़्टवेयर ब्रेकपॉइंट्स: डीबगर x86 आर्किटेक्चर पर एक विशेष "जाल" निर्देश (int 3/0xcc) के साथ ब्रेकपॉइंट के पते पर ऑपोड को प्रतिस्थापित करता है।

वर्तमान निर्देश के ओपोड को मिलान करने के लिए या तो हार्डवेयर ब्रेकपॉइंट डालने के लिए सीपीयू समर्थन की आवश्यकता होगी या डीबगर को सॉफ़्टवेयर ब्रेकपॉइंट का उपयोग करने के लिए पते को जानने की आवश्यकता होगी।

सिद्धांत रूप में, डीबगर केवल निर्देश की बाइट अनुक्रम के लिए पूरी मेमोरी खोज सकता है, लेकिन बाइट अनुक्रम एक निर्देश के बीच या डेटा में भी हो सकता है, इसलिए यह झूठी सकारात्मक हो सकती है।

चूंकि असेंबली निर्देश परिवर्तनीय-लंबाई हैं, नियंत्रण किसी भी मनमाना पते पर जा सकता है या कोड स्वयं को संशोधित कर सकता है, यह कुछ विशेष निर्देश खोजने के लिए स्मृति के पूरे क्षेत्र को अलग करने के लिए भी छोटा नहीं है।

तो मूल रूप से, मनमानी असेंबली कोड में निर्देश को विश्वसनीय रूप से खोजने का एकमात्र तरीका निर्देश स्तर पर एकल-चरणबद्ध होगा। और यह बेहद महंगा होगा, यहां तक ​​कि printf() जैसे एक छोटी लाइब्रेरी कॉल भी आज के हार्डवेयर पर मिनट ले सकती है यदि आप प्रत्येक निर्देश को सिंगल-चरण करते हैं।

+0

* "... और यह भी लागू करने के लिए बहुत अक्षम हो जाएगा।" * - मैं इस बारे में निश्चित नहीं हूँ। एक निष्पक्ष कार्यान्वयन अक्षम हो सकता है, जैसे निष्पादित होने पर प्रत्येक स्नेही की तुलना स्ट्रिंग की तरह। लेकिन जीडीबी से ऐसा करने के लिए कहा गया है जो रूसी सुझाव दिया गया उचित लगता है। मेरे मामले में, मैं 'CPUID' पर कॉल को तोड़ना चाहता हूं। इसमें केवल चार या पांच कॉल हैं, इसलिए ऐसा लगता है कि जीडीबी ने जो काम किया है, वह रूसी मेरे लिए सही होगा, इसलिए मुझे समय बर्बाद नहीं करना पड़ेगा। – jww

2

I don't know the address of the code in memory.

क्या आपको यह पता ढूंढने से रोकता है? objdump -d चलाएं, रुचि के निर्देश को ढूंढें, उसका पता नोट करें। समस्या सुलझ गयी? (यह साझा पुस्तकालयों के लिए भी छोटा रूप से विस्तारित है।)

+1

यह एक क्विकलुक प्लगइन है, इसलिए मुझे नहीं पता कि यह कैसे लोड और कॉल किया जाता है। – Tyilo

+0

क्या जीडीबी हमारे लिए ऐसा करने से रोकता है? कंप्यूटर को हमारे जीवन को आसान बनाना चाहिए, कठिन नहीं :) – jww

6

जैसा कि अन्य ने कहा, यह संभवतः ऐसा करने के लिए असंभव है क्योंकि हार्डवेयर समर्थन नहीं है।

यदि आपको वास्तव में यह करने के लिए चाहते हैं, यह अजगर आदेश एक प्रारंभिक बिंदु के रूप में सेवा कर सकते हैं:

class ContinueI(gdb.Command): 
    """ 
Continue until instruction with given opcode. 

    ci OPCODE 

Example: 

    ci callq 
    ci mov 
""" 
    def __init__(self): 
     super().__init__(
      'ci', 
      gdb.COMMAND_BREAKPOINTS, 
      gdb.COMPLETE_NONE, 
      False 
     ) 
    def invoke(self, arg, from_tty): 
     if arg == '': 
      gdb.write('Argument missing.\n') 
     else: 
      thread = gdb.inferiors()[0].threads()[0] 
      while thread.is_valid(): 
       gdb.execute('si', to_string=True) 
       frame = gdb.selected_frame() 
       arch = frame.architecture() 
       pc = gdb.selected_frame().pc() 
       instruction = arch.disassemble(pc)[0]['asm'] 
       if instruction.startswith(arg + ' '): 
        gdb.write(instruction + '\n') 
        break 
ContinueI() 

बस स्रोत इसके साथ:

source gdb.py 

और के रूप में आदेश का उपयोग करें:

breaki mov 
breaki callq 

और आपको दिए गए ऑपोड के साथ निष्पादित मुट्ठी निर्देश पर छोड़ा जाएगा।

TODO: यह आपके अन्य ब्रेकपॉइंट्स को अनदेखा कर देगा।

syscall की विशेष आम मामले के लिए, आप catch syscall उपयोग कर सकते हैं: https://reverseengineering.stackexchange.com/questions/6835/setting-a-breakpoint-at-system-call

+0

* "यह संभवतः ऐसा करने के लिए असंभव है क्योंकि कोई हार्डवेयर समर्थन नहीं है ...." * - फ़ंक्शन नाम को तोड़ने के लिए कोई हार्डवेयर समर्थन नहीं है, लेकिन जीडीबी प्रबंधन करता है कर दो। – jww

+0

@jww कड़ाई से बोलते हुए आप सही हैं, लेकिन मुझे लगता है कि यह स्पष्ट है कि मेरा क्या मतलब है: जीडीबी निश्चित रूप से पूरे टेक्स्ट सेक्शन को पार्स कर सकता है और उन सभी ऑपकोड्स पर सॉफ़्टवेयर ब्रेकपॉइंट्स डाल सकता है, और यह पाइथन में करना आसान है। या आप एक कदम कर सकते हैं जैसे मैं कर रहा हूँ। लेकिन कुछ कार्यों को खोजने और ब्रेकपॉइंट्स रखने के लिए प्रतीक तालिका के माध्यम से जाने से काफी लंबा समय लगता है। इसके अलावा, हजारों ऑपकोड बनाम एक फ़ंक्शन नाम होंगे, इसलिए यदि आप पहले ब्रेकपॉइंट डालते हैं तो भी निष्पादन धीमा होने वाला है। –

+0

@jww मुझे यह भी लगता है कि यह उल्लेखनीय है क्योंकि इसके लिए हार्डवेयर समर्थन होना संभव होगा क्योंकि प्रोसेसर पहले से ही opcodes का विश्लेषण करता है। लेकिन हार्डवेयर समर्थन फ़ंक्शन ब्रेकपॉइंट्स के लिए, एक ईएलएफ पार्सिंग प्रोसेसर की आवश्यकता होगी :-) –