C函数指针:我可以跳转到堆内存汇编代码吗? [英] C function pointer: Can I jump to heap memory assembler code?

查看:55
本文介绍了C函数指针:我可以跳转到堆内存汇编代码吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以通过分配动态内存并为其编写一些汇编操作码来创建动态函数(例如 NOP RET 0x90 0xC2 ),创建指向该动态内存的函数指针,并像C函数中的常规函数​​一样执行它?

Is it possible to create a dynamic function by allocating dynamic memory, writing some assembler opcodes to it (like 0x90 0xC2 for NOP RET), creating a function pointer which points to that dynamic memory and execute it like a regular function from within a C program?

目标应该是常规的x86 Linux系统.

Target should be a regular x86 Linux system.

推荐答案

此内存不是堆内存(请参见下面的注释).而且,我认为您不能更改堆内存的执行权限.

This memory doesn't have be heap memory (see note below). Moreover, I'd think that you can't change execution permission of heap memory.

在Linux上,您可以使用以下内容:

On Linux, You can use the following:

#include <sys/mman.h>
size_t size = 0x1000; // 1 page
// this will be mapped somewhere between /lib/x86_64-linux-gnu/ld-2.15.so
// and stack (see note and memory map below)
void *code = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0);
// use `code` to write your instructions
// then store location at which you want to jump to in `fp`
void *fp = ...;
mprotect(code, size, PROT_READ | PROT_EXEC);
// use some inline assembly to jump to fp

注意:在Linux上,用户映射的内存位于单独的区域中(例如,从 400000000000 开始,在x86 Linux上可能最多,并且可能是 7f0000000000在x64上).堆位于程序的ELF段之后,区域之前,可用于 mmap .堆本身可以使用 brk 系统调用直接分配(现在已由 malloc 取代).参见以下示例(在我的Ubuntu 12.10 x64上获得):

Note: On Linux, memory mapped by user is located in separate region (something like from 400000000000 and up to stack on x86 Linux, and probably 7f0000000000 on x64 one). Heap is located after ELF segments of the program and before region, available for mmap. Heap itself can be allocated directly using brk system call (superseded by malloc by now). See this example (got on my Ubuntu 12.10 x64):

➜  ~ ps
  PID TTY          TIME CMD
 9429 pts/3    00:00:07 zsh
20069 pts/3    00:00:00 git-credential-
22626 pts/3    00:00:00 ps
➜  ~ cat /proc/9429/maps 
00400000-004a2000 r-xp 00000000 08:01 6291468                            /bin/zsh5
006a1000-006a2000 r--p 000a1000 08:01 6291468                            /bin/zsh5
006a2000-006a8000 rw-p 000a2000 08:01 6291468                            /bin/zsh5
006a8000-006bc000 rw-p 00000000 00:00 0 
01a51000-01fd8000 rw-p 00000000 00:00 0                                  [heap]
...
7f6529d61000-7f6529d91000 rw-p 00000000 00:00 0 
...
7f652d0d3000-7f652d0d5000 rw-p 00023000 08:01 44833271                   /lib/x86_64-linux-gnu/ld-2.15.so
7fffd7c7f000-7fffd7cae000 rw-p 00000000 00:00 0                          [stack]
7fffd7dff000-7fffd7e00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

如您所见, heap 是不可执行的(并且是正确的),因此您不能使用 malloc 来获取可执行内存.

As you can see, heap is not executable (and is rightly so), so you can't use malloc to get executable memory.

这篇关于C函数指针:我可以跳转到堆内存汇编代码吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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