iOS的UAF错误到底是什么错误

Use After Free

UAF 就是 Use After Free的缩写,是一种比较常见的内存错误式利用。很多iOS的越狱都是利用的这种方法。
在此简单的举个例子说明UAF出现的情况

代码说明一切

    class Car
    {
        public:
            virtual void setValue(int value)=0;
            virtual int getValue()=0;

        protected:
            int mValue;
    };

    class Electric_car: public Car
    {
        public:
            void setValue(int value){
            mValue = value;
        }

        int getValue(){
        mValue += 1;
        cout<<"This is Electric_car‘s getValue"<<endl;
        return mValue;
        }
    };

    class Fuel_car : public Car
    {
        public:
            void setValue(int value){
            mValue = value;
        }
        int getValue(){
        cout<<"This is Fuel_car‘s getValue"<<endl;
        mValue += 100;
        return mValue;
        }
    };

    void handleObject(Car* car)
    {
        car->setValue(0);
        cout<<car->getValue()<<endl;
    }

这个程序有三个类,其中Fuel_car和Electric_car都是继承自Car。并且分别实现了Car类的虚函数。因此当程序调用handleObject这个函数的时候,无论出入的参数是Electric_car还是Fuel_car,handleObject函数都可以正常被调用。

接着我们来看一下主函数的情况

    int main(void) {
    Electric_car *myElectric_car = new Electric_car();
    printf("Electric_car=%p\n",myElectric_car);   

    handleObject(myElectric_car);

    free(myElectric_car); 

    Fuel_car *myFuel_car = new Fuel_car();
    printf("Fuel_car=%p\n",myFuel_car);   

    handleObject(c);
    }
  1. 我们先new一个Electric_car,然后再调用handleObject来打印它的value值。最后释放掉这个Electric_car。
  2. 接着,我们new一个Fuel_car,然后调用handleObject来打印Electric_car(请注意是Electric_car,不是Fuel_car)

按照以上的步骤调用了相关函数之后会发生什么情况呢,正常情况下会出现内存泄漏的报错。但是上面主函数只是free掉了myElectric_car,并且没有把指针也置为NULL。这个时候如果有另一个对象(比如上面的Fuel_car)刚好被分配到了myElectric_car的指针地址里面。handleObject就会对这个对象进行处理并且不会出现错误。这就是典型的UAF错误

简单看一下运行结果吧。

    myElectric_car=0x15b23a76
    This is Electric_car‘s getValue
    1
    myFuel_car=0x15b23a76
    This is Fuel_car‘s getValue
    100

可以看到Electric_car对象在内存中的地址为0x15b23a76,然后Electric_car就被free掉了。随后,程序又创建了另一个对象myFuel_car。因为堆的特性,系统会把刚刚free掉的内存再分配给myFuel_car。因此myFuel_car在内存中的地址也是0x15b23a76。所以当程序调用handleObject(myElectric_car)的时候,本应该期待调用Electric_car‘s getValue()函数却调用了Fuel_car‘s getValue()函数,这就造成一个UAF错误。

总结

以上就是对UAF错误发生原因的介绍,对应方法一般为释放内存之后还要记得把指针也释放掉。 提一个有意思的话题,在iOS9.0中,有人就用这个UAF错误实现了越狱。主要漏洞发生的函数是IOHIDResourceUserClient。 你能找出问题吗(同学们这是一道送分题啊)

    //----------------------------------------------------------------------------
    // IOHIDResourceDeviceUserClient::terminateDevice
    //----------------------------------------------------------------------------
    IOReturn IOHIDResourceDeviceUserClient::terminateDevice()
    {
        if (_device) {
            _device->terminate();
    }
        OSSafeRelease(_device);

    return kIOReturnSuccess;
    }(最近在尝试在gitpage上写文章,所以这篇文章也放到了自己的github上)
时间: 2024-12-28 21:07:53

iOS的UAF错误到底是什么错误的相关文章

【三分钟视频教程】iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#

[三分钟视频教程]iOS开发中 Xcode 报 apple-o linker 错误的#解决方案# [三分钟视频教程]iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#,布布扣,bubuko.com

iOS 开发过程中常出现的一些错误总结

iOS 开发过程中常出现的一些错误总结 1.两个视图控制器之间的跳转 (1)跳转:[self presentModalViewController:control animated:YES]; 返回:[self dismissModalViewControllerAnimated:YES]; (2) 跳转:[self.navigationController  pushViewController:subTableViewController animated:YES]; 返回:[self.na

Ajax错误 “SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成” 的归纳总结

最近在做Asp.net项目的时候,是用Ajax访问服务器数据有时候老是莫名其妙的报错:SCRIPT7002: XMLHttpRequest: 网络错误 0x2ef3, 由于出现错误 00002ef3 而导致此项操作无法完成 .在网上查了查引起这个错误是个非常复杂的问题,也就是说有很多因素会引发这个Ajax错误,最蛋疼的是这个Ajax错误发生后,服务器端不会反回任何状态码和错误消息,所以无法直接跟踪和判断到底是什么原因引发了该错误.这里写一篇文章做一个归纳总结,将已知的错误原因总结出来,如果以后知

错误号:1364 错误信息:Field &#39;platId&#39; doesn&#39;t have a default value

1. 错误描述 错误号:1364 错误信息:Field 'platId' doesn't have a default value insert into `use`.`t_platform_scale` () values () 2.错误原因 由于在建表时,给platId一个not null限制,而且没有给默认值,在插入数据时未插入,导致报错 3.解决办法 (1)修改platId可以为null (2)插入数据时一定要插入platId 版权声明:本文为博主原创文章,未经博主允许不得转载. 错误号

oracle监听程序无法启动(TNS-12560: TNS: 协议适配器错误,TNS-00530: 协议适配器错误)

问题描述1: C:\Users\Administrator>lsnrctl start LSNRCTL for 64-bit Windows: Version 11.2.0.1.0 - Production on 12-12月-20144:50 Copyright (c) 1991, 2010, Oracle.  All rights reserved. 启动tnslsnr: 请稍候... Failed to start service, error 193.TNS-12560: TNS: 协议

一些错误的想法和错误的感悟

1.为什么不适合用SSL纪录协议封装一个新的协议 记住,SSL只是一个传输层上的封装协议,传输层上的.它代表的语义一定要比传输层更具体而比应用层更不具体.怎么能拿它来封装一个具体应用呢?这是典型的主次颠倒,本末倒置,喧宾夺主的极端做法!HTTPS只能在SSL之上,难道能在SSL之下吗?       这里最重要的是数据边界问题,你是用你的应用协议来定义数据边界还是用SSL来定义你的数据边界?谁能定义数据边界谁就要在外边,显然,作为且仅仅作为一个传输层安全增强协议,SSL只能在里面.如果在外面,那么

Ubuntu启动、停止、重启MySQL,查看MySQL错误日志、中文编码错误

1)启动: sudo /etc/init.d/mysql start 2)停止: sudo /etc/init.d/mysql stop 3)重启: sudo /etc/init.d/mysql restart 4)查看日志: cat /var/log/mysql.err cat /var/log/mysql/error.log 5)不支持中文 修改 /etc/mysql/my.cnf 在 [client] 下面增加: default-character-set=utf8 或 character

HttpWebResponse远程服务器返回错误: (500) 内部服务器错误。

现象 我们编码实现请求一个页面时,请求的代码类似如下代码: 1 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strUrl); 2 req.UserAgent = "MSIE6.0"; 3 req.Method = "GET"; 4 HttpWebResponse res = (HttpWebResponse)req.GetResponse(); 5 StreamReader sr = new Stre

linux6.4 安装oracle11g 出现错误ORA-01078和LRM-00109错误

在linux中oracle11g安装成功后,启动监听(lsnrctl  start)后,运行sqlplus / as sysdba后连接 startup出现了如下图的错误ORA-01078和LRM-00109错误 解决方法:     我当时也上网百度了一下,基本也都大同小异,以下两种方法基本就是网络上最常见的解决的方法,但我用了以下方法都不能解决问题,后来我发现了一种更快,也是简单有效的方法.方法一:http://www.linuxidc.com/Linux/2013-09/89670.htm方