Linux用户态下判断一个指针的合法性

Windows下面就不多说了:IsBadReadPtr,IsBadStringPtr,IsBadWritePtr。

Linux内核态可以用__access_ok函数来判断内存区域的访问性。
用户态自己写了一个,就是利用了段错误这个信号,然后处理这个信号。用siglongjmp和sigsetjmp在栈里面跳转。

直接Posix族的代码贴出来,应该还有一些小bug,有待继续完善
只把读取权限的写了,别的同理




#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>
#include <unistd.h>

/*
x86/Linux、x86/Solaris、SPARC/Solaris will sigal SIGSEGV
x86/FreeBSD、x86/NetBSD、x86/OpenBSD MacOS will sigal SIGBUS
*/

#if defined(__MACH__) && defined(__FreeBSD__) && defined(__NetBSD__) && defined(__OpenBSD__)\
&& defined(__DragonFly__)
#define ERROR_SIGNAL SIGBUS
#else
#define ERROR_SIGNAL SIGSEGV
#endif

static sigjmp_buf badreadjmpbuf;


static void badreadfunc(int signo)
{
/*write(STDOUT_FILENO, "catch\n", 6);*/
siglongjmp(badreadjmpbuf, 1);
}


int isbadreadptr(void *ptr, int length)
{
struct sigaction sa, osa;
int ret = 0;

/*init new handler struct*/
sa.sa_handler = badreadfunc;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;

/*retrieve old and set new handlers*/
if(sigaction(ERROR_SIGNAL, &sa, &osa)<0)
return (-1);

if(sigsetjmp(badreadjmpbuf, 1) == 0)
{
int i, hi=length/sizeof(int), remain=length%sizeof(int);
int* pi = ptr;
char* pc = (char*)ptr + hi;
for(i=0;i<hi;i++)
{
int tmp = *(pi+i);
}
for(i=0;i<remain;i++)
{
char tmp = *(pc+i);
}

}
else
{
ret = 1;
}

/*restore prevouis signal actions*/
if(sigaction(ERROR_SIGNAL, &osa, NULL)<0)
return (-1);

return ret;
}


int main()
{
int *p = 0;
int flag;
int testint = 1234567890, *teststack = &testint;
int * testheap = malloc(sizeof(int) * 10);

printf("bad ptr %d\n", isbadreadptr(p, 4));
printf("bad ptr %d\n", isbadreadptr(teststack, 4));
printf("bad ptr %d\n", isbadreadptr(testheap, 40));
free(testheap);


printf("exiting main\n");
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值