当前位置: 首页 > news >正文

Android Framework P4 - ServiceManager 进程

ServiceManager 进程

// /system/core/rootdir/init.rc service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart healthd onrestart restart zygote onrestart restart media onrestart restart surfaceflinger onrestart restart drm
// /frameworks/native/cmds/servicemanager/service_manager.cintmain(intargc,char**argv){structbinder_state*bs;bs=binder_open(128*1024);if(!bs){ALOGE("failed to open binder driver\n");return-1;}if(binder_become_context_manager(bs)){ALOGE("cannot become context manager (%s)\n",strerror(errno));return-1;}selinux_enabled=is_selinux_enabled();sehandle=selinux_android_service_context_handle();selinux_status_open(true);if(selinux_enabled>0){if(sehandle==NULL){ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");abort();}if(getcon(&service_manager_context)!=0){ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");abort();}}unionselinux_callback cb;cb.func_audit=audit_callback;selinux_set_callback(SELINUX_CB_AUDIT,cb);cb.func_log=selinux_log_callback;selinux_set_callback(SELINUX_CB_LOG,cb);binder_loop(bs,svcmgr_handler);return0;}
// /frameworks/native/cmds/servicemanager/binder.cstructbinder_state*binder_open(size_tmapsize){structbinder_state*bs;structbinder_versionvers;bs=malloc(sizeof(*bs));if(!bs){errno=ENOMEM;returnNULL;}bs->fd=open("/dev/binder",O_RDWR);if(bs->fd<0){fprintf(stderr,"binder: cannot open device (%s)\n",strerror(errno));gotofail_open;}if((ioctl(bs->fd,BINDER_VERSION,&vers)==-1)||(vers.protocol_version!=BINDER_CURRENT_PROTOCOL_VERSION)){fprintf(stderr,"binder: kernel driver version (%d) differs from user space version (%d)\n",vers.protocol_version,BINDER_CURRENT_PROTOCOL_VERSION);gotofail_open;}bs->mapsize=mapsize;bs->mapped=mmap(NULL,mapsize,PROT_READ,MAP_PRIVATE,bs->fd,0);if(bs->mapped==MAP_FAILED){fprintf(stderr,"binder: cannot map device (%s)\n",strerror(errno));gotofail_map;}returnbs;fail_map:close(bs->fd);fail_open:free(bs);returnNULL;}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_become_context_manager(structbinder_state*bs){returnioctl(bs->fd,BINDER_SET_CONTEXT_MGR,0);}
// /frameworks/native/cmds/servicemanager/binder.cvoidbinder_loop(structbinder_state*bs,binder_handler func){intres;structbinder_write_readbwr;uint32_treadbuf[32];bwr.write_size=0;bwr.write_consumed=0;bwr.write_buffer=0;readbuf[0]=BC_ENTER_LOOPER;binder_write(bs,readbuf,sizeof(uint32_t));for(;;){bwr.read_size=sizeof(readbuf);bwr.read_consumed=0;bwr.read_buffer=(uintptr_t)readbuf;res=ioctl(bs->fd,BINDER_WRITE_READ,&bwr);if(res<0){ALOGE("binder_loop: ioctl failed (%s)\n",strerror(errno));break;}res=binder_parse(bs,0,(uintptr_t)readbuf,bwr.read_consumed,func);if(res==0){ALOGE("binder_loop: unexpected reply?!\n");break;}if(res<0){ALOGE("binder_loop: io error %d %s\n",res,strerror(errno));break;}}}
// /frameworks/native/cmds/servicemanager/binder.cintbinder_parse(structbinder_state*bs,structbinder_io*bio,uintptr_tptr,size_tsize,binder_handler func){intr=1;uintptr_tend=ptr+(uintptr_t)size;while(ptr<end){uint32_tcmd=*(uint32_t*)ptr;ptr+=sizeof(uint32_t);#ifTRACEfprintf(stderr,"%s:\n",cmd_name(cmd));#endifswitch(cmd){caseBR_NOOP:break;caseBR_TRANSACTION_COMPLETE:break;caseBR_INCREFS:caseBR_ACQUIRE:caseBR_RELEASE:caseBR_DECREFS:#ifTRACEfprintf(stderr," %p, %p\n",(void*)ptr,(void*)(ptr+sizeof(void*)));#endifptr+=sizeof(structbinder_ptr_cookie);break;caseBR_TRANSACTION:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("parse: txn too small!\n");return-1;}binder_dump_txn(txn);if(func){unsignedrdata[256/4];structbinder_iomsg;structbinder_ioreply;intres;bio_init(&reply,rdata,sizeof(rdata),4);bio_init_from_txn(&msg,txn);res=func(bs,txn,&msg,&reply);binder_send_reply(bs,&reply,txn->data.ptr.buffer,res);}ptr+=sizeof(*txn);break;}caseBR_REPLY:{structbinder_transaction_data*txn=(structbinder_transaction_data*)ptr;if((end-ptr)<sizeof(*txn)){ALOGE("parse: reply too small!\n");return-1;}binder_dump_txn(txn);if(bio){bio_init_from_txn(bio,txn);bio=0;}else{/* todo FREE BUFFER */}ptr+=sizeof(*txn);r=0;break;}caseBR_DEAD_BINDER:{structbinder_death*death=(structbinder_death*)(uintptr_t)*(binder_uintptr_t*)ptr;ptr+=sizeof(binder_uintptr_t);death->func(bs,death->ptr);break;}caseBR_FAILED_REPLY:r=-1;break;caseBR_DEAD_REPLY:r=-1;break;default:ALOGE("parse: OOPS %d\n",cmd);return-1;}}returnr;}
// /frameworks/native/cmds/servicemanager/service_manager.cintsvcmgr_handler(structbinder_state*bs,structbinder_transaction_data*txn,structbinder_io*msg,structbinder_io*reply){structsvcinfo*si;uint16_t*s;size_tlen;uint32_thandle;uint32_tstrict_policy;intallow_isolated;//ALOGI("target=%p code=%d pid=%d uid=%d\n",// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);if(txn->target.ptr!=BINDER_SERVICE_MANAGER)return-1;if(txn->code==PING_TRANSACTION)return0;// Equivalent to Parcel::enforceInterface(), reading the RPC// header with the strict mode policy mask and the interface name.// Note that we ignore the strict_policy and don't propagate it// further (since we do no outbound RPCs anyway).strict_policy=bio_get_uint32(msg);s=bio_get_string16(msg,&len);if(s==NULL){return-1;}if((len!=(sizeof(svcmgr_id)/2))||memcmp(svcmgr_id,s,sizeof(svcmgr_id))){fprintf(stderr,"invalid id %s\n",str8(s,len));return-1;}if(sehandle&&selinux_status_updated()>0){structselabel_handle*tmp_sehandle=selinux_android_service_context_handle();if(tmp_sehandle){selabel_close(sehandle);sehandle=tmp_sehandle;}}switch(txn->code){caseSVC_MGR_GET_SERVICE:caseSVC_MGR_CHECK_SERVICE:s=bio_get_string16(msg,&len);if(s==NULL){return-1;}handle=do_find_service(bs,s,len,txn->sender_euid,txn->sender_pid);if(!handle)break;bio_put_ref(reply,handle);return0;caseSVC_MGR_ADD_SERVICE:s=bio_get_string16(msg,&len);if(s==NULL){return-1;}handle=bio_get_ref(msg);allow_isolated=bio_get_uint32(msg)?1:0;if(do_add_service(bs,s,len,handle,txn->sender_euid,allow_isolated,txn->sender_pid))return-1;break;caseSVC_MGR_LIST_SERVICES:{uint32_tn=bio_get_uint32(msg);if(!svc_can_list(txn->sender_pid)){ALOGE("list_service() uid=%d - PERMISSION DENIED\n",txn->sender_euid);return-1;}si=svclist;while((n-->0)&&si)si=si->next;if(si){bio_put_string16(reply,si->name);return0;}return-1;}default:ALOGE("unknown code %d\n",txn->code);return-1;}bio_put_uint32(reply,0);return0;}
// /frameworks/native/cmds/servicemanager/service_manager.cintdo_add_service(structbinder_state*bs,constuint16_t*s,size_tlen,uint32_thandle,uid_tuid,intallow_isolated,pid_tspid){structsvcinfo*si;//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);if(!handle||(len==0)||(len>127))return-1;if(!svc_can_register(s,len,spid)){ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",str8(s,len),handle,uid);return-1;}si=find_svc(s,len);if(si){if(si->handle){ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",str8(s,len),handle,uid);svcinfo_death(bs,si);}si->handle=handle;}else{si=malloc(sizeof(*si)+(len+1)*sizeof(uint16_t));if(!si){ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",str8(s,len),handle,uid);return-1;}si->handle=handle;si->len=len;memcpy(si->name,s,(len+1)*sizeof(uint16_t));si->name[len]='\0';si->death.func=(void*)svcinfo_death;si->death.ptr=si;si->allow_isolated=allow_isolated;si->next=svclist;svclist=si;}binder_acquire(bs,handle);binder_link_to_death(bs,handle,&si->death);return0;}
  1. binder_open(128*1024):打开 Binder 驱动

    • open("/dev/binder", O_RDWR):打开/dev/binder

    • 检查驱动版本:ioctl(bs->fd, BINDER_VERSION, &vers)获取驱动版本,vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION对比版本

    • mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0):内存映射

    • return bs:返回句柄

  2. binder_become_context_manager(bs):成为上下文管理器,固定编号 0

  3. binder_loop(bs, svcmgr_handler):进入 Binder 循环,处理所有请求

    • binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func):解析数据

      • switch(cmd):处理业务
http://www.jsqmd.com/news/885981/

相关文章:

  • LaTeX公式一键转Word:3步告别数学公式编辑烦恼
  • 2026年横评10款降AIGC网站:一键锁定高效助手!
  • 终极指南:5步快速定位Windows热键冲突元凶
  • 诚信标签工厂端落地技术方案 多品类俄标追溯采集应用分析
  • 独家专访杨元庆:详解联想集团千亿美金营收目标
  • 观察taotoken在多模型间自动路由对api调用成功率的影响
  • 中国股票市场限价单成交概率与微观结构高频分析【附模型】
  • 深度学习进阶:自然语言处理|4.1.2 QA|grads 列表与省略号 [...] 详解
  • 如何快速实现Windows游戏控制器虚拟化:ViGEmBus完整使用指南
  • 夏季血压“正常”了,能停药吗?别让好心办坏事
  • LongLLMLingua 核心原理:对比困惑度实现提示词压缩
  • 航空发动机叶片三维扫描-诺斯顿
  • Flory-Huggins参数与机器学习结合:聚合物耐化学性预测模型构建与应用
  • 告别MQTT.fx!用STM32+ESP8266直连新版OneNET,手把手教你从零配置JSON数据上传
  • ZMJS,把 JavaScript 解释器放进 SAP ABAP 应用服务器之后,很多扩展思路会变得不一样
  • 39 - Go 信号捕获与处理:优雅退出、进程控制
  • 告别AWCC臃肿:AlienFX Tools终极轻量级控制方案深度评测
  • 谈美---朱光潜前20页
  • 15个靶场如何构建渗透测试能力成长路径
  • 【Linux:文件】Linux 动静态库详解:动态链接与动态库加载深度解析
  • 如何突破百度网盘下载限制:Python解析工具完整指南
  • Ubuntu经常安装软件
  • 【安全加固】Claude Code v2.1.149 发布:堵截 PowerShell 越权路径漏洞,账单明细精准透视
  • Redis三大缓存异常问题
  • 机器学习势函数在辐射损伤模拟中的性能评估与优化策略
  • 白嫖$100直充券,3款Search MCP让你的AI Agent更聪明!
  • 为什么这个免费工具能快速修复你的重要视频文件:完整实战指南
  • 相贯曲线自动焊接轨迹规划与轨迹控制技术【附代码】
  • 2026 太原装修公司十佳榜单重磅发布!口碑实力双优,装修选对不踩坑 - 资讯快报
  • 5分钟学会BlenderKit:让你在Blender里拥有一个永不枯竭的创意资源库