x86

2011-10-28 8 views
8

के लिए वर्तमान निर्देश का पता प्राप्त करें मैं x86 (64 बिट सटीक होना) के साथ लिनक्स का उपयोग कर रहा हूं। क्या कोई तरीका है कि मैं वर्तमान निर्देश का पता प्राप्त कर सकता हूं। असल में मैं setjmp/longjmp के अपने सरलीकृत संस्करणों को लिखना चाहता हूं। Here, आर .. longjmp का सरलीकृत संस्करण पोस्ट किया गया। कोई विचार कैसे setjmp लागू किया गया है। एक सरलीकृत संस्करण जो अपवादों और सिग्नल आदि के कारण बिना है ...x86

उत्तर

24

मुझे 64-बिट कोड में विश्वास है कि आप बस lea rax, [rip] कर सकते हैं।

32-बिट मुहावरा है:

 call next 
next: pop eax 
+0

का उपयोग और यह 32 बिट में ऐसा ही कुछ ऐसा करना संभव है हो सकता है? – MetallicPriest

+1

@ मेटालिक प्रीस्ट: उत्तर अपडेट किया गया। – NPE

+0

कूल चाल शिकारी: -पी! – MetallicPriest

0

This साइट है जो इस प्रकार है setjmp और longjmp का एक सरल संस्करण, देता है।

#include "setjmp.h" 

#define OFS_EBP 0 
#define OFS_EBX 4 
#define OFS_EDI 8 
#define OFS_ESI 12 
#define OFS_ESP 16 
#define OFS_EIP 20 

__declspec(naked) int setjmp(jmp_buf env) 
{ 
    __asm 
    { 
    mov edx, 4[esp]   // Get jmp_buf pointer 
    mov eax, [esp]   // Save EIP 
    mov OFS_EIP[edx], eax 
    mov OFS_EBP[edx], ebp // Save EBP, EBX, EDI, ESI, and ESP 
    mov OFS_EBX[edx], ebx 
    mov OFS_EDI[edx], edi 
    mov OFS_ESI[edx], esi 
    mov OFS_ESP[edx], esp 
    xor eax, eax    // Return 0 
    ret 
    } 
} 

__declspec(naked) void longjmp(jmp_buf env, int value) 
{ 
    __asm 
    { 
    mov edx, 4[esp]   // Get jmp_buf pointer 
    mov eax, 8[esp]   // Get return value (eax) 

    mov esp, OFS_ESP[edx] // Switch to new stack position 
    mov ebx, OFS_EIP[edx] // Get new EIP value and set as return address 
    mov [esp], ebx 

    mov ebp, OFS_EBP[edx] // Restore EBP, EBX, EDI, and ESI 
    mov ebx, OFS_EBX[edx] 
    mov edi, OFS_EDI[edx] 
    mov esi, OFS_ESI[edx] 

    ret 
    } 
} 
+3

क्या यह आपके प्रश्न का उत्तर है, @MetallicPriest? – karlphillip

+0

जरूरी नहीं है, अगर आपका अच्छा हो, तो मैं आपका जवाब देख सकता हूं: -पी! – MetallicPriest

4

ऑफसेट-में-वर्तमान खंड रजिस्टर (EIP) सामान्य रूप से सुलभ नहीं है। हालांकि, अप्रत्यक्ष रूप से इसे पढ़ने के लिए एक हैकिश-तरीका है - आप इस कार्यक्रम को ईआईपी के मूल्य को ढेर पर धक्का देने के लिए चालित करते हैं, फिर बस इसे पढ़ें। यदि आप एक CALL FAR अनुदेश, खंड मूल्य (CS) का उपयोग करते हैं

call NextLine 
NextLine: 
    pop eax    ; address of previous line stored in EAX 

रूप में अच्छी तरह ढेर पर आगे बढ़ा दिया जाएगा:

GetAddress: 
    mov eax, [esp] 
    ret 
... 
    call GetAddress  ; address of this line stored in eax 

या, और भी आसान: आप एक सबरूटीन कि इस तरह दिखता है बना सकते हैं ।


आप सी उपयोग कर रहे हैं, वहाँ विभिन्न संकलक विशिष्ट सी एक्सटेंशन आप this page पर इस्तेमाल कर सकते हैं कर रहे हैं। this interesting article भी देखें।

+0

ओपी x86_64 के बारे में पूछता है, जिसमें सापेक्ष पते है, इसलिए आरआईपी –

8

जीसीसी का उपयोग कर, तो आप भी __builtin_return_address

+2

के लिए निर्देश "सुलभ" हैं, ध्यान रखें कि आपको इच्छित प्रभाव प्राप्त करने के लिए इसे एक फ़ंक्शन में लपेटने की आवश्यकता होगी, अन्यथा आप समाप्त हो जाएंगे वर्तमान निर्देश के पते के बजाय वर्तमान स्टैक फ्रेम के लिए वापसी पता। – Jason

+2

यदि जीसीसी का उपयोग करना आसान है ['somelabel: return && somelabel;'] (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html) –

+1

@ जेसन सही है और यह सुनिश्चित भी करता है कि __builtin_return_address युक्त रैपिंग फ़ंक्शन की परिभाषा हेडर फ़ाइल में नहीं है और कभी भी रेखांकित नहीं की जाएगी। –