跳转到数据段

发布于 2024-12-17 06:53:50 字数 292 浏览 2 评论 0原文

我正在测试我正在编写的生成 X86 指令的汇编程序。我想做这样的事情来测试说明是否有效。

#include<stdio.h>

unsigned char code[2] = {0xc9, 0xc3};

int main() {
  void (*foo)();
  foo = &code;
  foo();
  return 0;
}

然而,由于 DEP,OS X 似乎阻止了这种情况。有没有办法(a)为此程序禁用 DEP 或(b)以另一种格式输入字节,以便我可以跳转到它们。

I am testing an assembler I am writing which generates X86 instructions. I would like to do something like this to test whether the instructions work or not.

#include<stdio.h>

unsigned char code[2] = {0xc9, 0xc3};

int main() {
  void (*foo)();
  foo = &code;
  foo();
  return 0;
}

However it seems that OS X is preventing this due to DEP. Is there a way to either (a) disable DEP for this program or (b) enter the bytes in another format such that I can jump to them.

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

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

发布评论

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

评论(2

赤濁 2024-12-24 06:53:50

如果您只需要测试,请尝试这个,它神奇...

const unsigned char code[2] = {0xc9, 0xc3};
^^^^^

const 关键字使编译器将其放置在 const 部分(警告!这是一个实现细节!),它与 text 部分位于同一段中。整个段应该是可执行的。这样做可能更便携:

__attribute__((section("text"))
const unsigned char code[2] = {0xc9, 0xc3};

并且您始终可以在汇编文件中执行此操作,

    .text
    .globl code
code:
    .byte 0xc9
    .byte 0xc3

但是:如果您想在运行时更改代码,则需要使用mprotect< /代码>。默认情况下,内存中不存在同时具有写入和执行权限的映射。

下面是一个示例:

#include <stdlib.h>
#include <sys/mman.h>
#include <err.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    unsigned char *p = malloc(4);
    int r;
    // This is x86_64 code
    p[0] = 0x8d;
    p[1] = 0x47;
    p[2] = 0x01;
    p[3] = 0xc3;
    // This is hackish, and in production you should do better.
    // Casting 4095 to uintptr_t is actually necessary on 64-bit.
    r = mprotect((void *) ((uintptr_t) p & ~(uintptr_t) 4095), 4096,
                 PROT_READ | PROT_WRITE | PROT_EXEC);
    if (r)
        err(1, "mprotect");
    // f(x) = x + 1
    int (*f)(int) = (int (*)(int)) p;
    return f(1);
}

mprotect 规范指出,如果内存最初不是使用 mmap 映射的,则其行为是未定义的,但您正在测试,而不是发货,所以只需知道它在 OS X 上工作得很好,因为 OS X malloc 在幕后使用 mmap(我认为是唯一的)。

If you just need to test, try this instead, it's magic...

const unsigned char code[2] = {0xc9, 0xc3};
^^^^^

The const keyword causes the compiler to place it in the const section (warning! this is an implementation detail!), which is in the same segment as the text section. The entire segment should be executable. It is probably more portable to do it this way:

__attribute__((section("text"))
const unsigned char code[2] = {0xc9, 0xc3};

And you can always do it in an assembly file,

    .text
    .globl code
code:
    .byte 0xc9
    .byte 0xc3

However: If you want to change the code at runtime, you need to use mprotect. By default, there are no mappings in memory with both write and execute permissions.

Here is an example:

#include <stdlib.h>
#include <sys/mman.h>
#include <err.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    unsigned char *p = malloc(4);
    int r;
    // This is x86_64 code
    p[0] = 0x8d;
    p[1] = 0x47;
    p[2] = 0x01;
    p[3] = 0xc3;
    // This is hackish, and in production you should do better.
    // Casting 4095 to uintptr_t is actually necessary on 64-bit.
    r = mprotect((void *) ((uintptr_t) p & ~(uintptr_t) 4095), 4096,
                 PROT_READ | PROT_WRITE | PROT_EXEC);
    if (r)
        err(1, "mprotect");
    // f(x) = x + 1
    int (*f)(int) = (int (*)(int)) p;
    return f(1);
}

The mprotect specification states that its behavior is undefined if the memory was not originally mapped with mmap, but you're testing, not shipping, so just know that it works just fine on OS X because the OS X malloc uses mmap behind the scenes (exclusively, I think).

无风消散 2024-12-24 06:53:50

不知道 OSX 上的 DEP,但您可以做的另一件事是对您编写代码的内存进行 malloc(),然后跳转到此 malloc 区域。至少在 Linux 上,该内存不会受到 exec 保护(事实上,JIT 通常就是这样做的)。

Don't know about your DEP on OSX, but another thing you could do would be to malloc() the memory you write the code to and then jump into this malloc'ed area. At least on Linux this memory would not be exec-protected (and in fact that's how a JIT usually does the trick).

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