要想挖漏洞,必先深入理解代码实现,而且必要时需要比开发者更懂代码。
不同于android,在鸿蒙系统中,只有一种组件即ability。更细分的话分为UIAbility, serviceAbility和dataAbility。访问其他ability的方式分别是startAbility和connectAbility。
理解底层实现是一项非常复杂的工程,虽然有OpenHarmony和android可以参考,但工作量依然很大。期望靠自己的蚂蚁搬家一点一点吃透并通过文章展示出来。
要理解ipc,就不得不先了解systemAbilityManager。systemAbilityManager的OpenHarmony实现代码在https://gitee.com/openharmony/systemabilitymgr_samgr。发布的鸿蒙系统二进制代码在/system/lib64/chipset-pub-sdk/libsamgr.dylib.so。对于应用的Ability管理,是通过AbilityManager管理的。
samgr服务接收到sa框架层发送的注册消息,会在本地缓存中存入系统服务相关信息。
AbilityManagerService又是应用间非常重要的一个服务。用于协调各Ability运行关系、及对生命周期进行调度的系统服务。其中包括和ability的各种唤起,连接,数据分享等。
- 连接管理模块(AbilityConnectManager)是Ability管理服务对Service类型Ability连接管理的模块。
-
数据管理模块(DataAbilityManager)是Ability管理服务对Data类型Ability管理的模块。 -
App管理服务调度模块(AppScheduler)提供Ability管理服务对用户程序管理服务进行调度管理的能力。 -
Ability调度模块(AbilityScheduler)提供对Ability进行调度管理的能力。 -
生命周期调度模块(LifecycleDeal)是Ability管理服务对Ability的生命周期事件进行管理调度的模块。
this.context.connectServiceExtensionAbility(want, { onConnect(elementName:object, remote) {console.info('onConnect callback');let option = new rpc.MessageOption();let data = new rpc.MessageSequence();let reply = new rpc.MessageSequence(); data.writeInt(100); data.writeInt(200); remote.sendMessageRequest(1, data, reply, option); }, onDisconnect(elementName:object) {console.info('onDisconnect callback') }, onFailed(code:number) {console.info('onFailed callback') } });
BindNativeFunction(env, object,"connectServiceExtensionAbility", moduleName, JsServiceExtensionContext::ConnectAbility);
NapiAsyncTask::ExecuteCallback GetConnectAbilityExecFunc(const AAFwk::Want &want,sptr<JSServiceExtensionConnection> connection, int64_t connectId, std::shared_ptr<int> innerErrorCode){return [weak = context_, want, connection, connectId, innerErrorCode]() { *innerErrorCode = context->ConnectAbility(want, connection); };}
ErrCode ServiceExtensionContext::ConnectAbility(const AAFwk::Want &want, const sptr<AbilityConnectCallback> &connectCallback) const{ ErrCode ret = ConnectionManager::GetInstance().ConnectAbility(token_, want, connectCallback);return ret;}
ErrCode AbilityManagerClient::ConnectAbility(const Want &want, sptr<IAbilityConnection> connect, int32_t userId){ auto abms = GetAbilityManager();// 跨进程通信的转折点return abms->ConnectAbilityCommon(want, connect, nullptr, AppExecFwk::ExtensionAbilityType::SERVICE, userId);}
AbilityManagerClient::ConnectAbility函数是应用进程和abilitymanager服务ipc通信的转折点。其中:
-
want: connectServiceExtensionAbility或者startAbility的want参数 -
connect:当serviceability连接/连接失败的回调函数 - userid: 最初来自于ConnectAbilityInner函数的输入参数,默认是-1,也可以通过参数指定
比如connectServiceExtensionAbilityWithAccount(want, accountId, options)中的accountId也就是userid
napi_value CreateJsServiceExtensionContext(napi_env env, std::shared_ptr<ServiceExtensionContext> context){ napi_value object = CreateJsExtensionContext(env, context, abilityInfo); std::unique_ptr<JsServiceExtensionContext> jsContext = std::make_unique<JsServiceExtensionContext>(context); napi_wrap(env, object, jsContext.release(), JsServiceExtensionContext::Finalizer, nullptr, nullptr);const char *moduleName = "JsServiceExtensionContext"; BindNativeFunction(env, object, "startAbilityWithAccount", moduleName, JsServiceExtensionContext::StartAbilityWithAccount); BindNativeFunction( env, object, "connectAbilityWithAccount", moduleName, JsServiceExtensionContext::ConnectAbilityWithAccount); BindNativeFunction( env, object,"connectServiceExtensionAbilityWithAccount", moduleName, JsServiceExtensionContext::ConnectAbilityWithAccount); BindNativeFunction(env, object, "startServiceExtensionAbilityWithAccount", moduleName,JsServiceExtensionContext::StartServiceExtensionAbilityWithAccount); BindNativeFunction(env, object, "stopServiceExtensionAbilityWithAccount", moduleName,JsServiceExtensionContext::StopServiceExtensionAbilityWithAccount);return object;}
console.log(this.context["__context_impl__"].startServiceExtensionAbilityWithAccount);
原文始发于微信公众号(大山子雪人):代码级深入分析鸿蒙ability跨进程通信
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论