代码级深入分析鸿蒙ability跨进程通信

admin 2025年1月11日12:51:06评论16 views字数 4065阅读13分33秒阅读模式

要想挖漏洞,必先深入理解代码实现,而且必要时需要比开发者更懂代码。

不同于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管理的。

代码级深入分析鸿蒙ability跨进程通信

samgr服务接收到sa框架层发送的注册消息,会在本地缓存中存入系统服务相关信息。

AbilityManagerService又是应用间非常重要的一个服务。用于协调各Ability运行关系、及对生命周期进行调度的系统服务。其中包括和ability的各种唤起,连接,数据分享等。

代码级深入分析鸿蒙ability跨进程通信
  1. 连接管理模块(AbilityConnectManager)是Ability管理服务对Service类型Ability连接管理的模块。
  2. 数据管理模块(DataAbilityManager)是Ability管理服务对Data类型Ability管理的模块。
  3. App管理服务调度模块(AppScheduler)提供Ability管理服务对用户程序管理服务进行调度管理的能力。
  4. Ability调度模块(AbilityScheduler)提供对Ability进行调度管理的能力。
  5. 生命周期调度模块(LifecycleDeal)是Ability管理服务对Ability的生命周期事件进行管理调度的模块。
下面是在刚接触鸿蒙app开发时就会知道的一个代码,代码的功能是connect指定的service并与之通信。
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')      }    });
代码级深入分析鸿蒙ability跨进程通信
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

代码级深入分析鸿蒙ability跨进程通信
以上是自己最近的一点分析,后边的逻辑还在整理。但是今天的文章还没有结束。
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;}
可以看到有一部分函数携带了accountid并且可控,但实际上没有导出。如何才能使用这些函数呢?
方法就是利用this.context的一个隐藏属性__context_impl__
console.log(this.context["__context_impl__"].startServiceExtensionAbilityWithAccount);
代码级深入分析鸿蒙ability跨进程通信
从控制台输出可以看到该函数确实存在。

原文始发于微信公众号(大山子雪人):代码级深入分析鸿蒙ability跨进程通信

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月11日12:51:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   代码级深入分析鸿蒙ability跨进程通信https://cn-sec.com/archives/3603533.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息