We know from Droidplugin's official documentation.
2 using plug-in com.morgoo.droidplugin.PluginApplication in Androidmanifest.xml:
Or, in the OnCreate () function of the custom application, call Pluginhelper.getinstance (). Applicationoncreate (Getbasecontext ());
In the application Attachbasecontext () function, call the
Pluginhelper.getinstance (). Applicationattachbasecontext (base);
The next step is to analyze pluginhelper.applicationoncreate ();
The first step pluginhelper.applicationoncreate ();
publicvoidapplicationOnCreate(final Context baseContext) { mContext = baseContext; initPlugin(baseContext);}
This function is relatively simple, just save the incoming context object, and then call Pluginhelper's Initplugin function.
The second step is pluginhelper. The Initplugin () function is as follows:
private void Initplugin (Context basecontext) {fixmiuilbesecurity ();Pluginpatchmanager. getinstance(). Init(Basecontext);Pluginprocessmanager. Installhook(Basecontext);if (Pluginprocessmanager. Ispluginprocess(Basecontext)) {Pluginprocessmanager. Sethookenable(true);} else {Pluginprocessmanager. Sethookenable(false);} PlugInManager. getinstance(). Addserviceconnection(Pluginhelper. this);PlugInManager. getinstance(). Init(Basecontext);}
A suitable for Xiaomi system fixmiuilbesecurity
First call the Fixmiuilbesecurity function as follows:
//Address Xiaomi JLB22.0 4.1.1 System comes with Xiaomi Security Center (LBE.SECURITY.MIUI) ad blocker caused by plugin white screen problem Private void fixmiuilbesecurity(){//Remove lbe safe applicationloaders.mloaders hooksClass applicationloaders = Class.forName ("Android.app.ApplicationLoaders"); Object applicationloaders = Methodutils.invokestaticmethod (Applicationloaders,"Getdefault"); Object mloaders = Fieldutils.readfield (Applicationloaders,"Mloaders",true);if(Mloaders instanceof HashMap) {HashMap OldValue = ((HASHMAP) mloaders);if("Com.lbe.security.client.clientcontainer$monitoredloadermap". Equals (Mloaders.getclass (). GetName ())) {HashMapvalue=NewHashMap ();value. Putall (OldValue); Fieldutils.writefield (Applicationloaders,"Mloaders",value,true); } }//Remove lbe safe activitythread.mpackages hooksObject currentactivitythread = Activitythreadcompat.currentactivitythread (); Object mpackages = Fieldutils.readfield (Currentactivitythread,"Mpackages",true);if(Mpackages instanceof HashMap) {HashMap OldValue = ((HASHMAP) mpackages);if("Com.lbe.security.client.clientcontainer$monitoredpackagemap". Equals (Mpackages.getclass (). GetName ())) {HashMapvalue=NewHashMap ();value. Putall (OldValue); Fieldutils.writefield (Currentactivitythread,"Mpackages",value,true); } }//Current all messages in the main thread message queue, find the LBE message and remove the if(Looper.getmainlooper () = = Looper.mylooper ()) {Final MessageQueue queue = Looper.myqueue (); Object mmessages = Fieldutils.readfield (Queue,"Mmessages",true);if(Mmessages instanceof Message) {Findlbemessageandremoveit (Message) mmessages); } }
In fact, the function of the comment has been very clear, millet a mobile phone comes with a lbe security software,
The internal custom Monitoredloadermap class of this software should be inherited from the map class, replacing the original member variable mloaders in the Applicationloaders class to manage the ClassLoader of the application in the Android system. A member variable Mclassloader within a loadedapk is created by Applicationloaders. Unloading the hooks here is to replace the mloaders with the native HashMap object.
Another class Monitoredpackagemap replaces the Mpackages object of Activitythread, Mpackages is the HashMap class object to apply as the Key,loadedapk object instance as value. Removing the hook here means replacing the Mpackages object with the native HashMap object.
During activity startup, our plug-in activity instantiation is done by saving the loadedapk object of the plugin APK package name to the Activitythread member variable mpackages in advance. By the way, replace the Mclassloader in loadedapk with Pluginclassloader. So pluginclassloader can load the class in the plug-in. (This will be analyzed in detail in the plugin activity startup)
Perhaps because of the impact of the plug-in activity startup process, so need to deal with.
Finally, all the LBE messages inside the main thread are deleted.
B plug-in exception handling pluginpatchmanager.getinstance (). Init ()
publicvoidinit(Context context){ mContext = context; }
This initialization is to save the context to the Pluginpatchmanager member variable mcontext, where the context object is saved primarily to delay the activation of the plugin activity. This class is mainly in the activation plug-in activity process, will call Pluginpatchmanager function canstartpluginactivity Judge Pluginmanagerservice This plug-in management service has started, If you do not start, you call Pluginpatchmanager's function startpluginactivity delay start plug-in activity waits for Pluginmanagerservice start to complete. It will be analyzed later in the activity-related article.
C initialization of the hook system plug-in need to use the relevant services
Pluginprocessmanager.installhook (Basecontext);
This function is primarily called hookfactory.getinstance (). Installhook (Hostcontext, NULL); Hook system related services. (The hook process will be analyzed in detail later)
D Host Process close hook switch wait pluginmanagerservice start after open
if (PluginProcessManager.isPluginProcess(baseContext)) { PluginProcessManager.setHookEnable(true); else { PluginProcessManager.setHookEnable(false); }
Judging by pluginprocessmanager.ispluginprocess, if the plug-in process opens the hook switch, if the host process temporarily closes the hook switch. It will wait until the Pluginmanagerservice boot is complete before opening the hook switch.
PluginProcessManager.isPluginProcess函数如下: publicstaticfinalbooleanisPluginProcess(Context context) { String currentProcessName = getCurrentProcessName(context); if (TextUtils.equals(currentProcessName, context.getPackageName())) returnfalse; initProcessList(context); return !sProcessList.contains(currentProcessName); }
First get the name of the current process and then determine if it is the same as the host process package name, if the same description is not the plug-in process. If the difference still needs to be judged whether it is another process that the host app leaves (except that Droidplugin has pre-defined n processes for the plug-in), Initprocesslist will save the other process that the host application is in Sprocesslist.
Here's why if the host process needs to close the hook first? Because the hook is mainly to deceive the system to ensure that the plug-in APK is not installed in the case of normal operation, Pluginmanagerservice has not started, the installed plug-in APK is not loaded in. Also, if the plug-in process is in progress, the hook switch can be opened directly after the hook is completed because the Pluginmanagerservice is running in the host process.
E Registration Service Connection callback start Pluginmanagerservice
Pluginmanager.getinstance (). Addserviceconnection (Pluginhelper.this);
Pluginmanager.getinstance (). Init (Basecontext);
First register the service connection, wait for the service to start to complete, call the Pluginprocessmanager.sethookenable (true) function to open the hook switch.
Then call PlugInManager's init function, which is primarily to start pluginmanagerservice.
F initiates the Pluginmanagerservice initialization of the Ipluginmanagerimpl object.
PluginManagerService的onCreate函数。 publicvoidonCreate() { keepAlive(); new IPluginManagerImpl(this); mPluginPackageManager.onCreate();}
First, the process priority of the service is raised.
To create a Ipluginmanagerimpl object, the Ipluginmanagerimpl constructor is relatively simple, but it creates a Myactivitymanagerservice object that is primarily used for plug-in process management.
Then call Ipluginmanagerimpl's OnCreate function.
The main OnCreate function is to start a thread and run the Oncreateinner function.
G load the installed plug-in to get the permissions declared by the host process
privatevoidonCreateInner() { loadAllPlugin(mContext); loadHostRequestedPermission(); mHasLoadedOk.set(true); synchronized (mLock) { mLock.notifyAll(); }}
The function Loadallplugin () is mainly from/data/data/com. HOST. Under the Package/plugin directory, locate the installed plug-in package, create the Pluginpackageparser object and cache it, and then cache the signature. These are basically in the Droidplugin source analysis installation and uninstallation of the analysis.
function Loadhostrequestedpermission () is primarily the collection of permission information for the declaration of the host process.
H creates and saves the Ipluginmanagerimpl proxy object, creates the thread, waits for the Ipluginmanagerimpl initialization to complete, and the distribution Service connection listens successfully, registering the service death callback.
Public void onserviceconnected(FinalComponentName ComponentName,FinalIBinder ibinder) {Mpluginmanager = IPluginManager.Stub.asInterface (IBinder);NewThread () {@Override Public void Run() {mpluginmanager.waitforready (); Mpluginmanager.registerapplicationcallback (NewIapplicationcallback.stub () {@Override PublicBundleOnCallback(Bundle extra)throwsremoteexception {returnExtra } }); iterator<weakreference<serviceconnection>> Iterator = Sserviceconnection.iterator (); while(Iterator.hasnext ()) {weakreference<serviceconnection> WSC = Iterator.next (); Serviceconnection SC = WSC! =NULL? Wsc.get ():NULL;if(SC! =NULL) {sc.onserviceconnected (componentname, IBinder); }Else{Iterator.remove (); }} mpluginmanager.asbinder (). Linktodeath (NewIbinder.deathrecipient () {@Override Public void binderdied() {onservicedisconnected (componentname); } },0); }}}.start ();}
The function first saves the Ipluginmanagerimpl Proxy object into the Mpluginmanger,
Then call Mpluginmanager.waitforready () to see if the service initialization is complete and wait if it is not completed.
After completion, the distribution of this service connection is successfully monitored. In e-step, you receive the service connection success callback, set the hook switch to true.
Last registered binder death is destroyed, and when the Ipluginmanagerimpl local binder object is destroyed, we receive a binder death notification and then restart Pluginmanagerservice in the notification.
Step three: In Application's Attachbasecontext () function, call the
PluginHelper.getInstance().applicationAttachBaseContext(base) publicvoidapplicationAttachBaseContext(Context baseContext) { MyCrashHandler.getInstance().register(baseContext);}
This function is primarily to register a Uncaughtexceptionhandler to save crash exception information when the application exits unexpectedly.
To the end of this plugin run environment initialization process, summarize:
- 1 fit Xiaomi Phone preinstalled Lbe, replace the applicationloaders member variable mloaders, replace the activitythread member variable mpackages, and remove all LBE related messages from the main thread queue.
- 2 Initialize plug-in exception handling and initialize hook system related services. If the hook switch is closed first in the host process, open the hook switch if it is not.
- 3 Register the Pluginmanagerservice service Connection listener object, then start the Pluginmanagerservice service, create the Myactivitymanagerservice object in the service, and manage all the plug-in processes. Then mount all installed plugins apk. After the service starts, the service listens to the callback and opens the hook switch.
From this we can know the main duties of Pluginmanagerservice, loading installed plugins apk, plugin apk installation and uninstall, plugin apk information query, and plugin process management etc.
Next blog We will analyze the hook initialization process.
Droidplugin Source analysis plug-in runtime environment initialization