太简单了,简单到我都不好意思说,只是我这个人嘛,最近老忘事,记在这里,避免自己把自己给忘了.
在linux下想要获取root权限,执行什么命令?su啊,不会连这个都不知道吧?哇嘎嘎,我太高兴了,比我还笨.其实android系统默认也是有这个命令的,而且它的权限也是其余用户可以执行的权限,那是不是自己在android应用里执行这个shell命令就可以root了呢?哇哦,我突然发现我好聪明啊,比爱因斯坦还聪明一个级别.
我勒乐个草,不是这样的,为了安全着想,默认是只允许root和shell用户运行的.哇嘎嘎,虽然我不知道android应用程序是以什么用户运行的,但绝对不是这2种.聪明的人肯定想到了替换这个su命令哇.恩,我也是这样想的,现在满天飞的root工具就是基于这个原理.可是那些工具是做了特殊处理的,想要原生就让android系统root,我靠哇,有这么复杂么.忽然想到我当年怎么不回家种田去.多简单的工作哇.忽然让我想到了我想要的那种生活:农妇,山前,有点田..
其实嘛,这要比想像中的简单得多,但是,但是你要懂各个方面的知识,比如linux系统权限管理,什么setuid,setgid函数等等等,还要会编译android源码树.哎呀,我不说了,我自己都晕了,因为我根本不会嘛.我草,又要花2天时间学习了.
su命令的原理很简单,就是设置uid来实现的.至于这个uid,其实还有gid.在里面都是用setuid,setgid两个函数来设置的.下面贴上su.c的代码,是在android源码树里copy的.
int main(int argc, char **argv)
{
struct passwd *pw;
int uid, gid, myuid;
//---------------------------------------------------------------disabled by fisher
//-----------------------------------------------------------------if(argc < 2) {
uid = gid = 0;
} else {
pw = getpwnam(argv[1]);if(pw == 0) {
uid = gid = atoi(argv[1]);
} else {
uid = pw->pw_uid;
gid = pw->pw_gid;
}
}if(setgid(gid) || setuid(uid)) {
fprintf(stderr,"su: permission denied ");
return 1;
}
if (argc == 3 ) {
if (execlp(argv[2], argv[2], NULL) < 0) {
fprintf(stderr, "su: exec failed for %s Error:%s ", argv[2],
strerror(errno));
return -errno;
}
} else if (argc > 3) {
char *exec_args[argc - 1];
memset(exec_args, 0, sizeof(exec_args));
memcpy(exec_args, &argv[2], sizeof(exec_args));
if (execvp(argv[2], exec_args) < 0) {
fprintf(stderr, "su: exec failed for %s Error:%s ", argv[2],
strerror(errno));
return -errno;
}
}
execlp("/system/bin/sh", "sh", NULL);fprintf(stderr, "su: exec failed ");
return 1;
}
这个代码就不说了,本来想说的,打字途中想起不开心的事了,简单代过.看前面那部分被注释掉的代码,这个在执行的时候会检测用户是否为root或者shell,如果不是,直接返回,如果是,那么执行下面的setuid,setgid代码.还不明白的自己去买块老豆腐吃死算了.
此方法在android4.2系统上验证通过.