Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 非执行页面上的触发器执行错误_Linux_Kernel - Fatal编程技术网

Linux 非执行页面上的触发器执行错误

Linux 非执行页面上的触发器执行错误,linux,kernel,Linux,Kernel,我正在寻找一种方法,从用户编写的程序触发一个错误,其中执行了一个非执行mmap'd页面,导致内核终止进程 我不确定如何在实际程序中以分配的mmap缓冲区形式推送可执行代码,使其包含有效指令,以便在我尝试将内存强制转换到函数指针以执行导致故障的指令时,终止不会发出信号 这是在arm64上,如果它有任何区别 谢谢 我在arm64上使用的最终代码: #include <sys/mman.h> #include <string.h> #include <stdio.h>

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

我不确定如何在实际程序中以分配的mmap缓冲区形式推送可执行代码,使其包含有效指令,以便在我尝试将内存强制转换到函数指针以执行导致故障的指令时,终止不会发出信号

这是在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);
}
#包括
#包括
#包括
/*更改这些以反映硬件的操作码*/
#ifdef__aarch64__
#定义NOP 0xD503201F
#定义RET 0xD65F0000
#否则
#错误:不支持的平台
#恩迪夫
void memset32(uint32_t*dst、uint32_t值、大小)
{
大小>>=2;
而(大小--){
*dst++=数值;
}
}
typedef int(*func_ptr)(无效);
int main(int argc,字符**argv)
{
/*mmap()一些匿名内存*/
func_ptr dummy_func=mmap(NULL,4096,保护读取,保护写入,
MAP|ANON | MAP|u PRIVATE,-1,0);
/*发出要与故障地址进行比较的地址
我们应该晚一点*/
fprintf(标准,“虚拟函数:%p\n”,虚拟函数);
/*用NOP操作码填充内存*/
memset32((uint32_t*)dummy_func,NOP,4096);
/*报答只是为了露齿而笑*/
((uint32_t*)dummy_func)[512]=RET;
/*调用“函数”*/
int dummy_result=dummy_func();
返回(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 );
}
#包括
#包括
#包括
/*更改这些以反映硬件的操作码*/
#定义nop0x90
#定义RET 0xC2
typedef int(*func_ptr)(无效);
int main(int argc,字符**argv)
{
/*mmap()一些匿名内存*/
func_ptr dummy_func=mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_ANON | MAP_PRIVATE,-1,0);
/*发出要与故障地址进行比较的地址
我们应该晚一点*/
fprintf(标准,“虚拟函数:%p\n”,虚拟函数);
/*用NOP操作码填充内存*/
memset(dummy_func,NOP,4096);
/*报答只是为了露齿而笑*/
((char*)dummy_func)[1024]=RET;
/*调用“函数”*/
int dummy_result=dummy_func();
返回(0);
}

如果我能在arm64上找到return的操作码,我会尽快尝试。我找到了一个没有的。