`
zhangyafei_kimi
  • 浏览: 264116 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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;
}
分享到:
评论

相关推荐

    推箱子-C语言-Linux下运行.zip

    在这个项目中,我们看到一个用C语言实现的推箱子游戏,并且能在Linux环境下运行。C语言是一种强大的编程语言,适合开发系统级软件和高性能的应用程序,包括游戏。 首先,我们要理解C语言的基础知识。C语言提供了...

    Linux下用C语言实现学生信息管理系统.zip

    5. **用户输入验证**:在读取用户输入时,需要验证其合法性,例如检查学号是否为数字,姓名是否为空等。这通常通过字符串处理函数(如`fgets()`、`strlen()`、`strtok()`)和条件判断实现。 6. **文件格式化**:在...

    制作一个可供小学数学运算的程序

    程序通过预先设定的指针数组存储题目,当用户输入题号时,使用if语句检查输入的合法性,避免重复出题。如果输入的题号已经出现过,程序将提示用户重新选择,并通过递归调用出题模块来生成新的题目。 2. 答题模块...

    西安光向信息技术有限公司-嵌入式linux工程师招聘笔试题13.9_嵌入式-常用知识&面试题库_大厂面试真题.doc

    4. 语句的合法性:C语言中,语句的合法性取决于编译器的实现,例如int a = 5, b = 7, c;c = a+++b;是否合法取决于编译器的实现。 二、嵌入式系统 1. 嵌入式系统特点:嵌入式系统经常具有要求程序员去访问某特定的...

    应用 Valgrind 发现 Linux 程序的内存问题1

    【Valgrind】是一款在Linux环境下广泛使用的开源内存调试工具,它通过模拟CPU环境来检测内存使用中的问题。Valgrind的核心是一个框架,提供服务给其他工具,这些工具如插件一样利用核心功能来实现特定的内存调试任务...

    基於Linux 核心模式之Rootkit 惡意軟體的隱藏及偵測技術

    为了验证上述变形Linux Kernel Mode Rootkit及其检测方法的有效性,可以设计一系列实验来进行测试和评估。这些实验应包括但不限于以下几个方面: - **Rootkit植入实验**:在受控环境下模拟Rootkit的植入过程,评估...

    usb_bootloader.zip

    但用户体验完全不同,拿串口升级来说,首先用户需要一个串口软件,然后对于没有硬件串口的PC来说,就需要一个USB转串口设备,对于不同PC平台,串口软件就不一样,这需要学习成本,过程繁琐;所以在一些需要用户自行...

    C语言斗地主

    【C语言斗地主】项目是一个使用C语言编写的、能在Linux环境下运行的简单游戏程序。这个项目的主要目的是让学生了解并实践C语言编程基础,同时掌握一些简单的游戏逻辑设计和控制流程。虽然开发者自认代码可能不够完善...

    完善的24点小游戏(C程序)

    同时,考虑牌的合法性,可能需要额外的变量或函数来检查输入是否合法(如牌值在1到13之间,且不重复)。 3. **运算符枚举**: 为了处理加、减、乘、除四种运算,可以创建一个枚举类型,如`enum Operators {PLUS, ...

    c语言编程的五子棋.rar

    用户通过输入坐标来选择下棋位置,程序则根据输入进行合法性检查,并更新棋盘状态。 3. **游戏逻辑**:编写判断胜负的函数至关重要。这涉及到遍历棋盘,检查每一步是否形成了五子连珠。在实现过程中,需要考虑所有...

    基于ARM 构架(带MMU)的copy-from-user与copy-to-user详细分析.pdf

    在源代码中,这两个函数的主体逻辑首先会通过`access_ok`函数检查用户空间的指针有效性。`access_ok`函数会验证指定的地址范围是否在用户空间的合法地址范围内,防止恶意的越界访问。如果检查通过,函数会继续执行...

    滴滴出行笔试题 - 系统工程师.pdf

    11. **指针和数组**:在C语言中,数组名是首元素的地址,所以`&arr+1`指向数组的第一个元素的下一个位置,减1后指回数组最后一个元素。因此,`*(*(&arr+1)-1)`的结果是数组的最后一个元素的值,即5,选项D正确。 12...

    深信服科技公司校园招聘笔试题

    - **多态性**: 同一个接口可以被不同类的对象所实现,表现出不同的行为。 - **异常处理**: 正确处理运行时可能出现的各种异常情况。 - **资源管理**: 使用智能指针等现代技术管理资源,避免内存泄漏。 #### 6. 位...

    labuladong的算法小抄完整版.pdf

    #### 如何k个一组反转链表、判定括号合法性 - 介绍链表操作技巧,以及用栈来判断括号合法性。 #### 如何寻找缺失的元素、同时寻找缺失和重复的元素 - 探讨如何在数组中寻找缺失或重复的元素。 #### 如何判断回文...

    c++判断是否为目录的示例分享

    在C++编程中,有时我们需要判断一个...同时,确保在调用`lstat`之前,对传入的路径进行合法性检查,防止空指针或无效路径导致的问题。在多线程环境中,还需考虑同步问题,避免因并发访问文件系统而导致的数据不一致。

    2021-2022计算机二级等级考试试题及答案No.16902.docx

    2. MySQL特性:MySQL是一种开源的数据库管理系统,它可以在多种操作系统上运行,包括Linux、Windows等,并且支持多用户同时访问。 3. ASP.NET与SQLServer:在ASP.NET应用程序中,如果要访问SQLServer数据库,需要...

    IO流程解析与基本原理

    2. **请求合法性检查**: 检查`bio`的合法性,确保每个`bio`都包含正确的块设备信息(`bi_bdev`),并通过队列指针关联到具体的块设备队列。 3. **地址转换**: 如果请求涉及的是分区内的相对地址,则通过`blk_partition...

Global site tag (gtag.js) - Google Analytics