获取x86当前指令的地址

发布于 2024-12-12 19:04:45 字数 277 浏览 0 评论 0原文

我使用的是 x86 的 Linux(准确地说是 64 位)。有没有办法获取当前指令的地址。实际上我想编写自己的简化版本的setjmp/longjmp在这里,R..发布了longjmp的简化版本。知道如何实现 setjmp 吗?一个简化的版本,即不考虑异常和信号等......

I am using Linux with x86 (64 bit to be precise). Is there a way I can get the address of the current instruction. Actually I want to write my own simplified versions of setjmp/longjmp. Here, R.. posted a simplified version of longjmp. Any idea how setjmp is implemented. A simplified version that is, without taking into account of exceptions and signals etc...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不弃不离 2024-12-19 19:04:45

我相信在 64 位代码中,您可以简单地执行 lea rax, [rip]

32 位习惯用法是:

      call next
next: pop eax

I believe in 64-bit code you can simply do lea rax, [rip].

The 32-bit idiom is:

      call next
next: pop eax
岁月如刀 2024-12-19 19:04:45

如果使用 GCC,您还可以使用 __builtin_return_address

If using GCC, you could also use __builtin_return_address

伤痕我心 2024-12-19 19:04:45

当前段偏移寄存器 (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 扩展。另请参阅这篇有趣的文章

The offset-into-the-current-segment register (EIP) is not normally accessible. However, there is a hackish-way to read it indirectly - you trick the program into pushing the value of EIP onto the stack, then just read it off. You could create a subroutine that looks like this:

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

Or, even simpler:

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

If you use a CALL FAR instruction, the segment value (CS) will be pushed on the stack as well.


If you're using C, there are various compiler-specific C-extensions you could use on this page. See also this interesting article.

贪了杯 2024-12-19 19:04:45

这个站点提供了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
  }
}

This site gives a simple version of setjmp and longjmp, which is as follows.

#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
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文