के लिए वर्तमान निर्देश का पता प्राप्त करें मैं x86 (64 बिट सटीक होना) के साथ लिनक्स का उपयोग कर रहा हूं। क्या कोई तरीका है कि मैं वर्तमान निर्देश का पता प्राप्त कर सकता हूं। असल में मैं setjmp/longjmp के अपने सरलीकृत संस्करणों को लिखना चाहता हूं। Here, आर .. longjmp का सरलीकृत संस्करण पोस्ट किया गया। कोई विचार कैसे setjmp लागू किया गया है। एक सरलीकृत संस्करण जो अपवादों और सिग्नल आदि के कारण बिना है ...x86
x86
उत्तर
मुझे 64-बिट कोड में विश्वास है कि आप बस lea rax, [rip]
कर सकते हैं।
32-बिट मुहावरा है:
call next
next: pop eax
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
}
}
क्या यह आपके प्रश्न का उत्तर है, @MetallicPriest? – karlphillip
जरूरी नहीं है, अगर आपका अच्छा हो, तो मैं आपका जवाब देख सकता हूं: -पी! – MetallicPriest
ऑफसेट-में-वर्तमान खंड रजिस्टर (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 भी देखें।
ओपी x86_64 के बारे में पूछता है, जिसमें सापेक्ष पते है, इसलिए आरआईपी –
जीसीसी का उपयोग कर, तो आप भी __builtin_return_address
के लिए निर्देश "सुलभ" हैं, ध्यान रखें कि आपको इच्छित प्रभाव प्राप्त करने के लिए इसे एक फ़ंक्शन में लपेटने की आवश्यकता होगी, अन्यथा आप समाप्त हो जाएंगे वर्तमान निर्देश के पते के बजाय वर्तमान स्टैक फ्रेम के लिए वापसी पता। – Jason
यदि जीसीसी का उपयोग करना आसान है ['somelabel: return && somelabel;'] (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html) –
@ जेसन सही है और यह सुनिश्चित भी करता है कि __builtin_return_address युक्त रैपिंग फ़ंक्शन की परिभाषा हेडर फ़ाइल में नहीं है और कभी भी रेखांकित नहीं की जाएगी। –
का उपयोग और यह 32 बिट में ऐसा ही कुछ ऐसा करना संभव है हो सकता है? – MetallicPriest
@ मेटालिक प्रीस्ट: उत्तर अपडेट किया गया। – NPE
कूल चाल शिकारी: -पी! – MetallicPriest