在非exec页面上触发exec错误

时间:2015-06-05 17:29:11

标签: linux kernel

我正在寻找一种方法从用户编写的程序中触发一个错误,其中执行非exec mmap页面导致内核终止进程。

我不确定如何在实际程序中以分配的mmap缓冲区形式推送可执行代码,因此它包含一个有效指令,以便当我尝试将内存转换为函数指针时终止不是SIGILL执行它导致故障。

如果它有任何不同,这是在arm64上。

由于

我在arm64上使用的最终代码:

#include <sys/mman.h>
#include <string.h>
#include <stdio.h>

/* change these to reflect your hardware's opcodes */
#ifdef __aarch64__
#define NOP 0xD503201F
#define RET 0xD65F0000
#else
#error Unsupported platform
#endif

void memset32(uint32_t* dst, uint32_t value, size_t size)
{
    size >>= 2;
    while (size--) {
        *dst++ = value;
    }
}

typedef int (*func_ptr)( void );

int main(int argc, char **argv)
{
    /* mmap() some anonymous memory */
    func_ptr dummy_func = mmap( NULL, 4096, PROT_READ | PROT_WRITE,
            MAP_ANON | MAP_PRIVATE, -1, 0);

    /* emit the address to compare to the fault address
     we should be getting later */
    fprintf( stderr, "Dummy func: %p\n", dummy_func);

    /* fill the memory with NOP opcodes */
    memset32((uint32_t *)dummy_func, NOP, 4096);

    /* put in a return just for grins */
    ((uint32_t *)dummy_func)[512] = RET;

    /* call the "function" */
    int dummy_result = dummy_func();
    return (0);
}

1 个答案:

答案 0 :(得分:0)

使用NOP操作码为您的硬件填充mmap()'d块,然后使用函数指针,并将其设置为mmap()'d块的地址。然后使用函数指针作为函数调用。

奇怪的是,这个C代码实际上在我的x86 Solaris机箱上成功执行:

#include <sys/mman.h>
#include <string.h>
#include <stdio.h>

/* change these to reflect your hardware's opcodes */
#define NOP 0x90
#define RET 0xC2

typedef int (*func_ptr)( void );

int main( int argc, char **argv )
{
    /* mmap() some anonymous memory */
    func_ptr dummy_func = mmap( NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0 );

    /* emit the address to compare to the fault address
       we should be getting later */
    fprintf( stderr, "Dummy func: %p\n", dummy_func );

    /* fill the memory with NOP opcodes */
    memset( dummy_func, NOP, 4096 );

    /* put in a return just for grins */
    ( ( char * ) dummy_func )[ 1024 ] = RET;

    /* call the "function" */
    int dummy_result = dummy_func();
    return( 0 );
}