如何在没有 0x00 或 0xFF 字节的情况下获取 x86_64 中的指令指针? [英] How to get the instruction pointer in x86_64 without 0x00 or 0xFF bytes?

查看:22
本文介绍了如何在没有 0x00 或 0xFF 字节的情况下获取 x86_64 中的指令指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在汇编语言中,有没有一种方法可以在不使用 call 后跟 pop 的情况下访问指令指针 (RIP) 中的值?或者是否有可以做到这一点的机器代码操作码?

Is there a way to access the value in the instruction pointer (RIP) without using a call followed by a pop in assembly language? Or is there a machine code opcode that can do it?

我一直在谷歌搜索,没有明确的结果.

I have been googling with no clear results.

我的问题是机器代码中不能有任何零,否则我会收到 SIGSEGV 错误.这是由于服务器加载代码并从一串字节执行它的方式.近调用在到子例程的距离上为零,因此不能选择使用调用.

My problem is that I can't have any zeroes in the machine code, or else I get a SIGSEGV error. It's due to the way the server loads the code and executes it from a string of bytes. A near call has zeroes in the distance to the subroutine, so using call is not an option.

我使用的是 64 位 linux,并且有 nasm 和 yasm.

I'm on linux, 64-bit, and have nasm and yasm.

推荐答案

在 x86_64 中,标准方法是使用 RIP 相对寻址,而不是像 x86 中那样使用 CALL.即便如此,也不推荐使用 call/pop 方式1

In x86_64 the standard way is to use RIP-relative addressing instead of CALL like in x86. Even then, call/pop is not a recommended way1

通常,您将使用 lea rax, [rip] 将 RIP 转换为 RAX(实际上编码为 lea rax, [rip + 0] 有四个字节立即结束).但是,由于 LEA 不会取消引用内存地址,因此您可以将任何常量位移添加到 RIP 中,然后再减去它

Normally you'll use lea rax, [rip] to get RIP into RAX (which is actually encoded as lea rax, [rip + 0] with four bytes for the immediate at the end). However since LEA doesn't dereference the memory address, you can just add any constant displacements to the RIP and subtract it later

0:  48 8d 05 04 03 02 01    lea    rax,[rip+0x1020304]
7:  48 2d 04 03 02 01       sub    rax,0x1020304

您可以选择任何没有零或 0xFF 字节的立即数.如果你想要lea(7个字节长)之后的指令地址,你可以相应地用sub rax, 0x01020304 - 7

You can choose any immediate values that don't have a zero or 0xFF byte. If you want the address of the instruction after lea (which is 7 bytes long) you can fix up accordingly with sub rax, 0x01020304 - 7

1推荐方式

GetCurrentAddress:
    mov eax, [esp]
    ret
...
    call GetCurrentAddress
    mov [currentInstruction], eax

为了避免调用堆栈和返回堆栈缓冲区(RSB)之间的不匹配.但可能它在 shellcode 中并不重要

in order to avoid mismatching between the call stack and the return stack buffer (RSB). But probably it isn't important in shellcode

这篇关于如何在没有 0x00 或 0xFF 字节的情况下获取 x86_64 中的指令指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆