I was assigned to do a project in which I should write an app for Android to intercept all communicating Intents passing around in the framework. In fact, I would like to intercept all ICCs (inter-component communication) going on now in a device including all IPCs.
AFAIK, there are two general ways to do an ICC in Android listed below.
Intent passing (between Activities, Services and Receivers).
Bound Services to which Activities can bind themselves.
For getting this project done, should I manipulate Android framework to hook some specific modules? (Although I would not to do so).
I rather more interested in creating an app to intercept all ICCs without manipulating the framework. Is it possible at all?
If I should touch the framework, please tell me at which module(s)/component(s) all ICCs would be handled?
Should I manipulate Android framework to hook some specific modules?
Yes. Because of process sand-boxing feature of Linux kernel, your app cannot access other apps' information or what is going on there.
I rather more interested in creating an app to intercept all ICCs without manipulating the framework. Is it possible at all?
Absolutely No.
If I should touch the framework, please tell me at which module(s)/component(s) all ICCs would be handled?
For intercepting all ICCs, including starting Activities, starting Services, binding to services and sending broadcasts, you could manipulate Activity Manager service.
Whenever in your app, you call startActivity() (and of all its flavors e.g. startActivityForResult()), sendBroadcast(), startService and bindService (of which both RPC and using Messenger), the following steps will be taken. (behind the hood !)
Your app contact Service Manager through Binder mechanism presented in the Kernel.
Service Manager acts like an index to registered system services. So it would return back a handle to the Activity Manager to your app via Binder mechanism.
Your app now call the method specified on the Activity Manager instance it just got.
In Activity Manager further steps will be taken, such as: Intent resolution (via resolveIntent() method of Package Manager) and also Permission checking.
Two options for your case:
Manipulate Activity Manager codes directly.
Define your own a system service that acts like a proxy for the Activity Manager and register it to Service Manager. Recommended
Related
I recently hooked an app, and I've found some methods that I can call them in it, like I hooked a before onCreate method in the main activity, then I can call some method as well. That's perfect.
But I want to call them directly via my app, I can do it through BroadCast, but the broadcast can't run more than 10 seconds, it's very bad run some big task, and sometimes I prefer a result can be returned.
So seems it's wonderful I can add my service in the remote app and start it, but the problem is it isn't in the AndroidManifest.xml.
By the way, how can I get the ClassLoader from the remote app, I am not sure it will be working if I got the ClassLoader.
Welcome to correct me!
Thank you all. Waiting for your opinions.
Feel free to contact me with email shiqwang#gmail.com or Wechat(id:imwangshiqi)
How can I add my service into remote app and start it which I injected
by Xposed?
Short answer: You cannot start a service without registering it in the 3rd party app manifest. While with Xposed you could likely modify this behavior, it is likely a bad idea, not only because you would be messing with Android internals but also because there are easier alternatives to perform "remote invocations".
Long answer: If i understood correctly you want to build your own application that is able to control other Android applications hooked via Xposed.
If such is the case, understand that both apps will be completely isolated (different VM), you cannot simply pass an object from the 3rd party app (i.e., hooked app) to your app and expect any invocations on this object to be performed on the 3rd party app. You should check Remote Method Invocation (RMI) to understand these concepts. This answers your question regarding the class loader.
Nonetheless, if all you want is to invoke one method of yours remotely on that app, then you can surely do that. As you mentioned you cannot launch a service in a 3rd party app if it is not specified in its manifest (well at least not without major hacking). But if you launch the service in your app, you can force the 3rd party app to bind to it, and implement message handlers that invoke your methods on the 3rd party app (via IPC).
In fact I have done so before using the Android Messenger for performing this communication (i have written a detailed post on it). You will need to hook the app Activities (and other starting points as well if you want, e.g., broadcast receivers) to bind to the remote service. Then the service can send messages to to trigger actions on the hooked app.
I've written a library starting a service in the background. It runs perfectly in all applications.
In order to reduce the RAM usage, I want to avoid running multiple services for different applications. Actually, it's pretty enough to use only one service to get things done.
Firstly, I've written an AIDL file to make IPC between applications/libraries. Defined the service as exported/enabled with signature permission. Since all applications are the exactly the same service, it's not possible to check if any one is up or down. While binding the service to check the condition of the service, it always creates and destroys the own service because of the nature of BIND_AUTO_CREATE flag. That's why not possible to get any kind of info from the exported service if it's really up and running.
Then, I tried to define a Content Provider to the manifest of the library. My aim is to share the service info through it. It's really good mechanism to communicate between exported service and application main process. But it is not usable for multiple instances. Because applications which gets the content provider info from the library use the same authority and so it's not possible to install the second one. It gives an DUPLICATE_PROVIDER_AUTHORITY error.
What's your suggestion about the issue? Is there any option to create a master/slave mechanism? Is it possible to make the service singleton for the application uses the library project?
P.S: Tried broadcast and shared preferences techniques. But they're not effective to listen the callback from the exported service.
You need to put the Service in an APK of its own. It needs to have its own unique package name (in the manifest) which is different from the package names of any of the applications that use it. This is how you make the Service behave as a singleton. Now you can use AIDL and bind to the Service in order to have two-way communication.
Note that in more recent versions of Android, it has become necessary to start a Service using an explicit Intent (ie: the Component must be explicitly specified, you can't use just an ACTION).
Alternative 1:
If the use case permits I think you should not implement the Service.
Make your client implement a service a call your library code. This
is how MediaPlayer and other default android APIs work.
Alternative 2:
Host the service in a separate app..and download the app when the
first call is made from any client. From here onwards there will be
single service handling all the client request.This is how some APIs like adobe
air/ MDM solutions from Airwatch works.
There is no good way you can control a component which is running in other app,unless using broadcast receivers and all.
to understand the AIDL in android, i want one real life example, means the at what scenario of development we need to use AIDL.
by reading the Android Docs ... It puts me in confusion and so many question, so it is hard to read whole doc for me, can anyone help me
is it for communicating with outside the phone.
or to communicating with different apps, (why we need to communicate with other apps)
what kind of service they are talking in docs
AIDL is used for Binder. Binder is a mechanism to do RPC calls on/from an Android Service.
When to use AIDL? When you need a Service. When do you need a Service? If you want to share data and control something in another application, you need a service using AIDL as an interface. (A Content Provider is used when sharing data only).
Services can be used within your application as the model roll in the MVC-pattern.
AIDL is Android Interface Definition Language. This basically allows you to do IPC calls.
Use: There are situations where one process would need to talk to other to obtain certain information.
Example: Process A needs info of Call status to determine whether it needs to change Call Type (for example Audio to Video Call or Vice-versa). You may get call status from certain listeners but to change Call type from Audio to Video, Process A needs a hook to change. This "Hook" or way of changing calls is typically part of Telephony Classes which are part of Telephony Process. So in order to obtain such an information from Telephony process, One may write a telephony service (which runs as a part of android telephony process), which will allow you to query or change call type. Since Process A(Client) here is using this remote Service which communicates with Telephony process to alter call type, it needs to have an interface to talk to service. Since Telephony service is the provider, and Process A (client) is the user, they both need to agree on an interface (protocol) they can understand and adhere to. Such an interface is AIDL, which allows you to talk (via a remote service) to Telephony process and get some work done.
Simply put in laymen terms, AIDL is an "agreement" Client gets, which tells it about how to talk to service. Service itself will have a copy of that agreement(since it published for it's clients). Service will then implement details on how it handles once a request arrives or say when someone is talking to it
So process A requests to change call via Service, Service gets the request, it talks to telephony process(since it's part of it) and changes call to video.
An important point to note is, AIDL is only necessary for multithreading environment. You could do away with Binders if you don't need to deal with multithreaded arch.
Another real world example is Google Play License is using AIDL.
I have the same thinking about an example of AIDL, it's very difficult to find an idea to make an example app which uses AIDL. Then I have an idea about it create a LocalLogServerApp. Maybe it can not become a production app but it still shows some value in using AIDL
The main function of this app is
Receive the local log from other local apps (another app need to implement AIDL to send log)
Save the log to datastore
Display the logs
Maybe do something with the local log (eg: search, delete)
Maybe notify developer when error log happened
The benefit of this app
The local log can use when you have some very strange issues which sometimes happened in a few moments and in some specific device. In this case, common Log won't help, debug won't help, Firebase Log may help but Firebase receive log from multiple device.
Reusable, many apps can use it with less code
Hope you find this idea helpful to find another better AIDL example
https://github.com/PhanVanLinh/AndroidLocalLogServer
https://github.com/PhanVanLinh/AndroidLocalLogClientTest
1 - is it for communicating with outside the phone.
Its communicating with outside the app.
2 - or to communicating with different apps, (why we need to communicate with other apps)
As #GodOnScooter mentioned, when your app communicates with telephony service which is actually an other part.
3 - what kind of service they are talking in docs?
This is a service which runs in different process of a system, To bind to this service you need IPC(inter process communication), AIDL is used to implement this.
My Application has an Activity for the UI and a Service for background polling fun. Seems like standard fare.
Can AlarmManager trigger the Service Intent without Activity OnCreate being called?
Is there any benefit to putting the Activity & Service into different Applications? Would this create 2 apk's and make it impossible to put into Market as one app? Can you put 2 applications into one manifest somehow?
Regarding communication between the two:
-If Activity & Service are part of the same Application - can't I just store common objects (like User object) at the Application scope for the 2 to share?
-It seems like I don't even need to bother with AIDL - the two could just have weak references to each other at the Application scope as well - and they can call methods on each other that way? Or should they pub/sub each other with some kind of Observer Pattern or BroadcastListener thing?
Can AlarmManager trigger the Service Intent without Activity OnCreate being called?
Yes.
Is there any benefit to putting the Activity & Service into different Applications?
IMHO, no.
Would this create 2 apk's and make it impossible to put into Market as one app?
Yes.
Can you put 2 applications into one manifest somehow?
From a pure XML standpoint, there is room in the manifest for more than one <application> element. However, AFAIK, only one is supported.
If Activity & Service are part of the same Application - can't I just store common objects (like User object) at the Application scope for the 2 to share?
For very quick things, yes. However, bear in mind that your service may get shut down (by Android, by user, etc.), after which your process may get terminated, and your Application object goes poof. I'd use this for light caching only.
It seems like I don't even need to bother with AIDL
Correct -- that is only needed for inter-process service binding.
the two could just have weak references to each other at the Application scope as well
I wouldn't do that in a million years. Please use the platform responsibly. There are plenty of ways for activities and services to communicate yet remain loosely coupled (or, in the case of the local binding pattern, tightly-coupled in an Android-aware fashion).
Or should they pub/sub each other with some kind of Observer Pattern or BroadcastListener thing?
Something along those lines would be preferable. While the activity and the service may be co-resident in the same process at the same time, they are not designed to be directly linked to one another.
I'm writing an app, that has a somewhat modular system. It has a core app, and some apps, that consist of a single Service, that implements the desired interface. I followed the guide to create the IPC communication. But now I need to get all the services, installed on the system, that my core app can wotk with. How do I do this? I mean, is there any way to mark my Service apps with some kind of a tag, and then filter results, presented by the PackageManager#getInstalledPackages() based on that tag value? What's the common practice of doing so?
Create a custom Intent to which your activities will respond. You can then use PackageManager.queryIntentServices to get your list of matching services. You can get the package info, etc. from the information embedded in the ResolveInfos.
Ideally you'd actually use these intents for invoking the services, but you could always just use them as identification tags and fall back on the binding mechanism you were using before.