在非执行页面上触发执行错误
trigger exec fault on non-exec page
我正在寻找一种方法来从用户编写的程序中触发错误,在该错误中执行非执行 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);
}
用您的硬件的 NOP 操作码填充 mmap()
' 块,然后使用函数指针,并将其设置为 mmap()
' 块的地址。然后使用函数指针作为函数调用。
奇怪的是,这段 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 );
}
我正在寻找一种方法来从用户编写的程序中触发错误,在该错误中执行非执行 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);
}
用您的硬件的 NOP 操作码填充 mmap()
' 块,然后使用函数指针,并将其设置为 mmap()
' 块的地址。然后使用函数指针作为函数调用。
奇怪的是,这段 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 );
}