Получить адрес текущей инструкции для x86
Я использую Linux с x86 (точнее 64 бит). Есть ли способ, которым я могу получить адрес текущей инструкции. На самом деле я хочу написать свои собственные упрощенные версии setjmp / longjmp. Здесь R.. выложил упрощенную версию longjmp. Любая идея, как реализован setjmp. Упрощенная версия, то есть без учета исключений и сигналов и т.д...
4 ответа
Я верю в 64-битный код, который вы можете просто сделать lea rax, [rip]
,
32-битная идиома это:
call next
next: pop eax
Если вы используете GCC, вы также можете использовать __builtin_return_address
Регистр смещения в текущий сегмент (EIP
) обычно не доступен. Тем не менее, существует хакерский способ косвенного чтения - вы обманываете программу, помещая значение EIP в стек, а затем просто считываете его. Вы можете создать подпрограмму, которая выглядит следующим образом:
GetAddress:
mov eax, [esp]
ret
...
call GetAddress ; address of this line stored in eax
Или еще проще:
call NextLine
NextLine:
pop eax ; address of previous line stored in EAX
Если вы используете CALL FAR
инструкция, значение сегмента (CS
) также будет помещен в стек.
Если вы используете C, на этой странице вы можете использовать различные C-расширения для конкретного компилятора. Смотрите также эту интересную статью.
Этот сайт предоставляет простую версию 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
}
}