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;
}
分享到:
相关推荐
在这个项目中,我们看到一个用C语言实现的推箱子游戏,并且能在Linux环境下运行。C语言是一种强大的编程语言,适合开发系统级软件和高性能的应用程序,包括游戏。 首先,我们要理解C语言的基础知识。C语言提供了...
Linux 是一个真正的多用户操作系统,可以同时接受多个用户登录,还允许一个用户进行多次登录。这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统...
5. **用户输入验证**:在读取用户输入时,需要验证其合法性,例如检查学号是否为数字,姓名是否为空等。这通常通过字符串处理函数(如`fgets()`、`strlen()`、`strtok()`)和条件判断实现。 6. **文件格式化**:在...
4. 语句的合法性:C语言中,语句的合法性取决于编译器的实现,例如int a = 5, b = 7, c;c = a+++b;是否合法取决于编译器的实现。 二、嵌入式系统 1. 嵌入式系统特点:嵌入式系统经常具有要求程序员去访问某特定的...
【Valgrind】是一款在Linux环境下广泛使用的开源内存调试工具,它通过模拟CPU环境来检测内存使用中的问题。Valgrind的核心是一个框架,提供服务给其他工具,这些工具如插件一样利用核心功能来实现特定的内存调试任务...
为了验证上述变形Linux Kernel Mode Rootkit及其检测方法的有效性,可以设计一系列实验来进行测试和评估。这些实验应包括但不限于以下几个方面: - **Rootkit植入实验**:在受控环境下模拟Rootkit的植入过程,评估...
从给定的C语言选择判断题中,我们可以总结出一系列重要的C语言知识点,涉及数据类型、函数使用、字符串处理、输入输出操作、算术运算、条件判断、数据存储以及编程规范等多个方面。以下是对这些知识点的详细说明: ...
但用户体验完全不同,拿串口升级来说,首先用户需要一个串口软件,然后对于没有硬件串口的PC来说,就需要一个USB转串口设备,对于不同PC平台,串口软件就不一样,这需要学习成本,过程繁琐;所以在一些需要用户自行...
【C语言斗地主】项目是一个使用C语言编写的、能在Linux环境下运行的简单游戏程序。这个项目的主要目的是让学生了解并实践C语言编程基础,同时掌握一些简单的游戏逻辑设计和控制流程。虽然开发者自认代码可能不够完善...
同时,考虑牌的合法性,可能需要额外的变量或函数来检查输入是否合法(如牌值在1到13之间,且不重复)。 3. **运算符枚举**: 为了处理加、减、乘、除四种运算,可以创建一个枚举类型,如`enum Operators {PLUS, ...
用户通过输入坐标来选择下棋位置,程序则根据输入进行合法性检查,并更新棋盘状态。 3. **游戏逻辑**:编写判断胜负的函数至关重要。这涉及到遍历棋盘,检查每一步是否形成了五子连珠。在实现过程中,需要考虑所有...
在源代码中,这两个函数的主体逻辑首先会通过`access_ok`函数检查用户空间的指针有效性。`access_ok`函数会验证指定的地址范围是否在用户空间的合法地址范围内,防止恶意的越界访问。如果检查通过,函数会继续执行...
11. **指针和数组**:在C语言中,数组名是首元素的地址,所以`&arr+1`指向数组的第一个元素的下一个位置,减1后指回数组最后一个元素。因此,`*(*(&arr+1)-1)`的结果是数组的最后一个元素的值,即5,选项D正确。 12...
- **多态性**: 同一个接口可以被不同类的对象所实现,表现出不同的行为。 - **异常处理**: 正确处理运行时可能出现的各种异常情况。 - **资源管理**: 使用智能指针等现代技术管理资源,避免内存泄漏。 #### 6. 位...
#### 如何k个一组反转链表、判定括号合法性 - 介绍链表操作技巧,以及用栈来判断括号合法性。 #### 如何寻找缺失的元素、同时寻找缺失和重复的元素 - 探讨如何在数组中寻找缺失或重复的元素。 #### 如何判断回文...
在C++编程中,有时我们需要判断一个...同时,确保在调用`lstat`之前,对传入的路径进行合法性检查,防止空指针或无效路径导致的问题。在多线程环境中,还需考虑同步问题,避免因并发访问文件系统而导致的数据不一致。
2. MySQL特性:MySQL是一种开源的数据库管理系统,它可以在多种操作系统上运行,包括Linux、Windows等,并且支持多用户同时访问。 3. ASP.NET与SQLServer:在ASP.NET应用程序中,如果要访问SQLServer数据库,需要...
2. **请求合法性检查**: 检查`bio`的合法性,确保每个`bio`都包含正确的块设备信息(`bi_bdev`),并通过队列指针关联到具体的块设备队列。 3. **地址转换**: 如果请求涉及的是分区内的相对地址,则通过`blk_partition...
Apache Commons Lang 是一个Java工具包,它提供了一些实用的、高级的Java语言功能,扩展了Java的核心类库。"commons-lang-1.0.tar.gz"是这个库的1.0版本,以tar.gz格式压缩,这是在Unix或Linux环境中常用的归档和...