Получить адрес текущей инструкции для 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
  }
}
Другие вопросы по тегам