androidåLinuxçåºå«ï¼
æ以ä¸ä¸ç¹åºå«ï¼1ãAndroid没ææ¬å°çªå£ç³»ç»ï¼èLinuxæ¯æXçªå£ç³»ç»ã
2ãAndroid没æglibcæ¯æï¼èLinuxæ¯æglibcæ¯æçã
3ãAndroidæ¯æèªå·±ä¸æç驱å¨ç¨åºã
è½ç¶AndroidåºäºLinuxå æ ¸ï¼ä½æ¯å®ä¸Linuxä¹é´è¿æ¯æå¾å¤§çå·®å«ã
æ©å±èµæ
Androidä¸æç驱å¨ç¨åº
1ãAndroid Binder åºäºOpenBinderæ¡æ¶çä¸ä¸ªé©±å¨ï¼ç¨äºæä¾ Androidå¹³å°çè¿ç¨é´éä¿¡(InterProcess Communicationï¼IPC)åè½ãæºä»£ç ä½äºdrivers/staging/android/binder.cã
2ãAndroidçµæºç®¡ç(PM) ä¸ä¸ªåºäºæ åLinuxçµæºç®¡çç³»ç»çè½»é级Androidçµæºç®¡ç驱å¨ï¼é对åµå ¥å¼è®¾å¤åäºå¾å¤ä¼åãæºä»£ç ä½äºï¼
kernel/power/earlysuspend.c
kernel/power/consoleearlysuspend.c
kernel/power/fbearlysuspend.c
kernel/power/wakelock.c
kernel/power/userwakelock.c
3ãä½å å管çå¨(Low Memory Killer) æ¯Linuxçæ åçOOM(Out Of Memory)æºå¶æ´å çµæ´»ï¼å®å¯ä»¥æ ¹æ®éè¦ææ»è¿ç¨ä»¥éæ¾éè¦çå åãæºä»£ç ä½äº drivers/staging/ android/lowmemorykiller.cã
4ãå¿åå ±äº«å å(Ashmem) 为è¿ç¨é´æä¾å¤§åå ±äº«å åï¼åæ¶ä¸ºå æ ¸æä¾åæ¶å管çè¿ä¸ªå åçæºå¶ãæºä»£ç ä½äºmm/ashmem.cã
5ãAndroid PMEM(Physical) PMEMç¨äºåç¨æ·ç©ºé´æä¾è¿ç»çç©çå ååºåï¼DSPåæäºè®¾å¤åªè½å·¥ä½å¨è¿ç»çç©çå åä¸ãæºä»£ç ä½äºdrivers/misc/pmem.cã
6ãAndroid Logger ä¸ä¸ªè½»é级çæ¥å¿è®¾å¤ï¼ç¨äºæåAndroidç³»ç»çåç§æ¥å¿ãæºä»£ç ä½äºdrivers/staging/android/logger.cã
7ãAndroid Alarm æä¾äºä¸ä¸ªå®æ¶å¨ï¼ç¨äºæ设å¤ä»ç¡ç ç¶æå¤éï¼åæ¶å®è¿æä¾äºä¸ä¸ªå³ä½¿å¨è®¾å¤ç¡ç æ¶ä¹ä¼è¿è¡çæ¶éåºåãæºä»£ç ä½äºdrivers/rtc/alarm.cã
8ãUSB Gadgeté©±å¨ ä¸ä¸ªåºäºæ å Linux USB gadget驱å¨æ¡æ¶ç设å¤é©±å¨ï¼AndroidçUSB驱å¨æ¯åºäºgaegetæ¡æ¶çãæºä»£ç ä½äºdrivers/usb/gadget/ã
9ãAndroid Ram Console 为äºæä¾è°è¯åè½ï¼Androidå 许å°è°è¯æ¥å¿ä¿¡æ¯åå ¥ä¸ä¸ªè¢«ç§°ä¸ºRAM Consoleç设å¤éï¼å®æ¯ä¸ä¸ªåºäºRAMçBufferãæºä»£ç ä½äºdrivers/staging/android / ram_console.cã
ãAndroid timed device æä¾äºå¯¹è®¾å¤è¿è¡å®æ¶æ§å¶çåè½ï¼ç®åæ¯ævibratoråLED设å¤ãæºä»£ç ä½äºdrivers/staging/android /timed_output.c(timed_gpio.c)ã
åèèµæï¼ç¾åº¦ç¾ç§ââAndroid
ç¾åº¦ç¾ç§ââlinux
Framework层的Binder(源码分析篇)
本文以android-.0.0_r的AOSP分支为基础,解析framework层的代码的源代码Binder工作原理。
从ServiceManager的源码getService方法入手,其核心代码是安卓安卓通过getIServiceManager().getService(name)获取服务。首先,代码的源代码ServiceManager的源码一二三指标源码实现与进程中的ProcessState密切相关,ProcessState是安卓安卓单例,负责打开和映射Binder驱动。代码的源代码构造函数中,源码它会初始化驱动、安卓安卓验证版本并设置线程数,代码的源代码接着进行binder映射。源码
在ProcessState的安卓安卓getContextObject方法中,调用native函数android_util_Binder.cpp中的代码的源代码getContextObject()。这个函数通过handle 0(ServiceManager的源码handle)获取BpBinder对象,然后通过javaObjectForIBinder函数将其转换为Java中的类型。
进一步分析,BpBinder与java层的Binder之间存在对应关系,通过BinderProxy NativeData创建单例的BinderProxy。然后,每个服务的BinderProxy实例化和计数处理都在这个过程中完成。ServiceManagerNative.asInterface方法简化了getIServiceManager的电商补流量源码调用,通过调用asInterface实例化ServiceManagerProxy。
IServiceManager接口通过AIDL生成,其代理类ServiceManagerProxy实际上是不必要的。aidl文件在编译时生成对应java代码,用于binder通信。通过aidl文件,我们可以看到如queryLocalInterface等方法的实现细节。
在Parcel的协助下,客户端与服务端进行数据传递,通过序列化和反序列化进行交互。在transact函数中,对Parcel大小进行检查,避免数据传输过大导致的问题。最后,客户端与binder驱动的通信过程涉及了Transaction数据的写入、等待响应、数据处理和内存回收等步骤。
总的来说,framework层的Binder工作涉及服务管理、数据转换、通信协议和内存管理等环节,会员变盘指标源码理解这些有助于深入掌握Binder的工作机制。
深度分析Binder线程池的启动流程
理论基础Binder
Binder它是Android中的一种进程间通信机制,它主要采用的是CS架构模式。Binder框架中主要涉及到4个角色Client、Server、ServiceManager及Binder驱动,其中Client、Server、ServiceManager运行在用户空间,Binder驱动运行在内核空间。
线程池线程池它是一种用于多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
简单的说:线程池就是创建一些线程,它们的集合称为线程池。
Binder线程池启动流程我们知道一个新的app应用程序进程在创建完成之后,它会通过调用RunTimeInit类的士兵扫雷源码福利包静态成员函数zygoteInitNative来进行启动Binder线程池。
Binder线程池启动过程中,主要调用几个关键函数:ZygoteInitNative--->onZygoteInit--->startThreadPool。
下面的源码分析主要是以android5.0版本为例。
ZygoteInitNative源码分析由于ZygoteInitNative函数是java实现的代码,实践上最终调用的是由C++实现的JNI方法。以下代码来源于系统的/frameworks/base/core/jni/androidRuntime.cpp文件中
staticvoidcom_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv*env,jobjectclazz){ //gCurRuntime是个全局的变量,后面跟上的是另外实现的方法。gCurRuntime->onZygoteInit();}onZygoteInit源码分析onZygoteInit函数在需要源码的位置:/frameworks/base/cmds/app_process/app_main.cpp文件中。
该函数是个虚函数,并且是一个无返回值和无参数的函数virtualvoidonZygoteInit(){ //Re-enabletracingnowthatwe'renolongerinZygote.atrace_set_tracing_enabled(true);//获取进程的状态信息sp<ProcessState>proc=ProcessState::self();//打印日志信息ALOGV("Appprocess:startingthreadpool.\n");//启动线程池proc->startThreadPool();}startThreadPool源码分析startThreadPool系统实现在\frameworks\native\libs\binder\ProcessState.cpp文件中。
每一个支持Binder进程间通信机制的进程内都有一个唯一的ProcessState对象,当这个ProcessState对象的成员函数StartThreadPool函数被第一次调用的时候,它就会在当前进程中启动一个线程池,并将mThreadPoolStarted这个成员变量设置为true。
//该函数是个无参数,无返回值的函数voidProcessState::startThreadPool(){ AutoMutex_l(mLock);//判断线程池是否启动状态,启动的话就将标志信息设置为true属性。if(!mThreadPoolStarted){ mThreadPoolStarted=true;spawnPooledThread(true);}}总结Binder在android底层中是一个非常重要的机制,我们在实际的项目调用过程中,我们在app应用程序中只要实现自己的Binder本地对象的时候,跟其他服务一样,合成游戏红包版源码只需要将它进行启动起来,并且进行注册到ServerMananger就可以了。至于内部的实现一般是不需要去关心的。
Android Activity Deeplink启动来源获取源码分析
Deeplink在业务模块中作为外部应用的入口提供,不同跳转类型可能会导致应用提供不一致的服务,通常通过反射调用Activity中的mReferrer字段获取跳转来源的包名。然而,mReferrer存在被伪造的风险,可能导致业务逻辑出错或经济损失。因此,我们需要深入分析mReferrer的来源,并寻找更为安全的获取方法。
为了深入了解mReferrer的来源,我们首先使用搜索功能在Activity类中查找mReferrer,发现其在Attach方法中进行赋值。进一步通过断点调试跟踪调用栈,发现Attach方法是由ActivityThread.performLaunchActivity调用的。而performLaunchActivity在调用Attach时,传入的referrer参数实际上是一个ActivityClientRecord对象的referrer属性。深入分析后,发现referrer是在ActivityClientRecord的构造函数中被赋值的。通过进一步的调试发现,ActivityClientRecord的实例化来自于LaunchActivityItem的mReferrer属性。接着,我们分析了mReferrer的来源,发现它最终是由ActivityStarter的setCallingPackage方法注入的。而这个setCallingPackage方法的调用者是ActivityTaskManagerService的startActivity方法,进一步追踪调用链路,我们发现其源头是在App进程中的ActivityTaskManager.getService()方法调用。
在分析了远程服务Binder调用的过程后,我们发现获取IActivityTaskManager.Stub的方法是ActivityTaskManager.getService()。这使得我们能够追踪到startActivity方法的调用,进而找到发起Deeplink的应用调用的具体位置。通过这个过程,我们确定了mReferrer实际上是通过Activity的getBasePackageName()方法获取的。
为了防止包名被伪造,我们注意到ActivityRecord中还包含PID和Uid。通过使用Uid结合包管理器的方法来获取对应的包名,可以避免包名被伪造。通过验证Uid的来源,我们发现Uid实际上是通过Binder.getCallingUid方法获取的,且Binder进程是无法被应用层干涉的,因此Uid是相对安全的。接下来,我们可以通过Uid来置换包名,进一步提高安全性。
总结,mReferrer容易被伪造,应谨慎使用。通过使用Uid来获取包名,可以提供一种更为安全的获取方式。此过程涉及对源代码的深入分析和调试,作者Chen Long为vivo互联网客户端团队成员。
一文分析Binder机制和AIDL的理解
深入了解Android进程间通信机制,如同破解系统奥秘的钥匙,它在源码探索和问题解决中扮演着核心角色。Binder机制,源自OpenBinder,正是这个领域的主角,它弥补了Linux原生通信方式在性能和安全性的短板。它的运作涉及驱动层与应用层的无缝对接,包括与系统服务如Activity Manager Service (AMS) 的深度协作。 Binder,作为Java编写的通信工具包,是Android多进程通信的基石。尽管AIDL(Android Interface Definition Language)常用于简化这一过程,但并非不可或缺。让我们通过一个实例,不依赖AIDL,来揭示Binder通信的内在机制。想象一个简单的场景:一个客户端(ClientBinder)与服务端(ServerBinder,继承自Binder并实现onTransact方法)之间的字符串传递,透彻理解Binder通信的运作原理。 项目框架中,服务端在Service的onBind方法中返回一个ServerBinder实例。对比手动实现与AIDL生成的代码,AIDL的便捷性便一目了然。客户端通过ServiceConnection,如下面这段代码,与远程服务建立连接:1. 创建ServiceConnection,获取远程服务的IBinder
2. intent设置服务类名:"com.binder.server.RemoteService"
3. bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
4. 若未连接,尝试bindService
5. 传递数据:通过IBinder调用mStingEditText的文本,如data.writeString(text)
6. 成功连接后,调用transact方法传递请求
接收数据的环节,服务端将数据展示在tvShowMessage上,通过新线程处理,如`new Handler().post(() -> ServerMainActivity.tvShowMessage.setText(message));`。当连接断开时,serviceConnection的onServiceDisconnected方法会被触发。 关键在于客户端如何通过IBinder获取服务端对象并调用transact进行跨进程通信。AIDL的引入让这个过程更加优雅,例如在ClientMainActivityUseAidl中,服务连接成功后,通过IBinder代理mServer,调用自定义接口IShowMessageAidlInterface的showMessage方法。 在交互过程中,客户端通过IShowMessageAidlInterface的Stub内部类,将本地的IBinder转换为接口,这样数据的发送就通过showMessage方法进行。AIDL的asInterface方法负责封装本地或远程处理,Proxy类则负责数据的打包和跨进程传输,确保数据的无缝传递。 总结来说,客户端利用AIDL的asInterface处理远程IBinder,而Proxy类则是这一切的幕后功臣。服务端的onBind方法返回AIDL生成的Stub,它在客户端调用transact时负责接收和处理请求,执行showMessage方法。这样,AIDL生成的Stub和Proxy成为客户端发送数据的桥梁,而在服务端,它们则是数据处理的核心所在。 掌握Binder机制和AIDL的精髓,你将解锁Android进程间通信的无尽可能,为你的应用开发增添无限力量。无论何时,当你深入探索Android源码,这些核心原理都将是你不可或缺的指南。Android Binder Hookçå®ç°
Binder Hook å¯ä»¥ Hook æå½åè¿ç¨ç¨å°çç³»ç» Service æå¡ã以 LocationManager 为ä¾ï¼å¨è·åä¸ä¸ª LocationManager æ¶å为两æ¥ï¼
(1) è·å IBinder 对象ï¼
(2) éè¿ IBinder ç asInterface() æ¹æ³è½¬å为 LocationMangerService 对象ï¼æ¥çåå§å LocationManager ã
application å±ç¨å°çé½æ¯ LocationManager 对象ã
åçï¼
æ´ä¸ªè¿ç¨éè¦å©ç¨åå°è®¾ç½®ä¸ä¸ªèªå®ä¹ç Binder 对象åä¸ä¸ªèªå®ä¹ç Service 对象ãç±äºæä»¬åª Hook å ¶ä¸ä¸é¨åçåè½ï¼å ¶ä»åè½è¿éè¦ä¿çï¼æ以è¦ç¨å¨æ代ççæ¹å¼å建èªå®ä¹å¯¹è±¡ã
å¨ç解åé¢çå 容åä½ éè¦äºè§£è¿äºç¥è¯ç¹ï¼
Activity çç±»å¨è·åç³»ç» Service æ¶ï¼é½æ¯è°ç¨ getSystemService(serviceName) æ¹æ³è·åçã
Context # getSystemService() æ¹æ³æç»ä¼è°ç¨å° ServiceManager # getService() æ¹æ³ä¸ã以 LocationManager 对åºç ServiceFetcher 为ä¾ï¼å®ç createService() æ¹æ³æºç å¦ä¸ï¼
åå¦æä»¬è¦ Hook æ LocationManager # getLastKnownLocation() æ¹æ³ï¼ä¸æé½æ¯ï¼ãæ们è¦åçå°±æ¯è®©
ServiceManager.getService(Context.LOCATION_SERVICE) è¿åæ们èªå®ä¹ç Binder 对象ã
å çä¸ä¸è¿ä¸ªæ¹æ³çæºç ï¼
sCache æ¯ä¸ä¸ª Mapï¼ç¼åäºå·²ç»åç³»ç»è¯·æ±è¿ç Binderãå¦æéè¦è®©è¿ä¸ªæ¹æ³è¿åæ们èªå·±ç binder 对象ï¼åªéè¦äºå å¾ sCache ä¸ put ä¸ä¸ªèªå®ä¹ç Binder 对象就è¡äºã
å¨ put ä¹åï¼éè¦å å建åºä¸ä¸ªèªå®ä¹ç Binderãè¿ä¸ª Binder å¨è¢« ILocationManager.Stub.asInterface å¤çåï¼å¯ä»¥è¿åä¸ä¸ªèªå®ä¹ç LocationManagerService 对象ã
å çä¸ä¸ Binder ç asInterface() çå®ç°ï¼
å¦ææ queryLocalInterface()æ¹æ³è¿åä¸ä¸ªèªå®ä¹çServiceï¼ä½¿å¾èµ° if è¯å¥å é¨ï¼ä¸èµ° elseï¼é£å°±ç®æ¯Hook æåäºã
å设æ们æ³è®©ç³»ç»ç LocationManager è¿åçä½ç½®ä¿¡æ¯å ¨æ¯å¨å¤©å®é¨(., .)ãé£æ们éè¦ä½¿å¾ LocatitionManagerService ç getLastLocation() æ¹æ³ è¿åçå ¨æ¯ (., .)ã
ç±äºæ们ä¸è½ç´æ¥æ¿å°ç³»ç»çè¿ä¸ªService对象ï¼å¯ä»¥å ç¨åå°çæ¹å¼æ¿å°ç³»ç»çLocationManagerServiceãç¶åæ¦æª getLastLocation() æ¹æ³ã
åççBinder对象å¨è°ç¨ queryLocalInterface() æ¹æ³æ¶ä¼è¿ååççService对象ãæ们å¸æè¿å3.1ä¸çèªå®ä¹Serviceãæ以è¿éæ¦æª queryLocalInterface() æ¹æ³ã
æäºèªå®ä¹ç Binder åï¼å°å®æ³¨å ¥å° ServiceManger ç sCache åéä¸å°±å®æ Hook äº~
å½onClick被è°ç¨çæ¶åï¼ToaståLogé½ä¼æ¾ç¤ºå¤©å®é¨çåæ (., .)ãè¯æHookæåï¼
ä½ çè³å¯ä»¥ç¨Binder Hookçæ¹å¼Hookæ ActivityManagerã
2024-11-15 00:31
2024-11-14 23:35
2024-11-14 23:12
2024-11-14 22:48
2024-11-14 22:26