I started exploring BeanShell for SL4A because I read that it could access the entire Android API. This would facilitate experimenting with API features and programming ideas without the need for a computer or compilation.
However, much of the API is accessed through a Context, and I don't know how to obtain this. Although both SL4A and BeanShell are well-documented, the combination of the two seems to be very poorly documented.
For example, to access android.net.ConnectivityManager, the developer reference states that I need to call Context.getSystemService(Context.CONNECTIVITY_SERVICE) to get an instance. But without a context, I don't think I'm able to access the methods of the ConnectivityManager.
So how do I obtain the Context?
Dahrrr…
While researching and formulating the question, I found out that this is an unresolved issue:
Notes for Java interpreters
Beanshell and Rhino can both directly access the android api. However, many Android api calls required a context, which, due to the way they are run, these interpreters don't have. A solution is being sought... suggestions appreciated.
I don't know sl4a or beanshell but i know Rhino. So i suppose that you can create scriptable objects too. If this is correct you can do something like this (in java):
// first create a simple scope called -> scope
// inject context.
Object injectObject = Context.javaToJS(android_context, scope); // ('Context' of rhino library)
ScriptableObject.putProperty(scope, "android_context_name", injectObject);
// so then execute your script with the injected object
execute(javascript_context, host, scope, scriptId, source, settings);
When you finish injected the the context you can access him via: "android_context_name". (inside your script).
When you run your bean shell script, it will be thru an android app ?
There are such available
e.g : BeanShell Executor, that will allow you to run a script.
So I assume the context will be passed from the app to the script being executed.
Related
I'm working on a collage project about security in Android. One part of the project attempts to capture and log all API function called by the selected APK. This can't be done with a external programs so in the project we are working with the Android source code to modify the ROM.
At the present time we only have two possible solutions:
DVM JNI Bridge
The API is Java code so, obviously, the Dalvik Virtual Machine needs a bridge to execute JNI code. The function which handle all cases is dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thread* self). In this function we can get the name and the class of the called function.
This function can log all the JNI code executed, which includes API calls. But there is no easy way to distinct between private calls and API calls. And, if we wanted to execute some code depending on the risk of the API call executed, we would have to create a huge and inefficient switch.
API Framework
another solution To log all API calls is creating a new interface for the framework. With a new logging class and a simple inheritance should be easy to log all calls and add a risk parameter. But it would mean changing a lot of code. Also, Java code has worst performance than C, so it might not be the most efficient way.
More over, we would like to ask you a few questions about Android DVM and the API.
1.Which is exactly the call flow between DVM and the API?
2.Could be the DVM monitor a good idea to log the calls?
3.Which role have the shared libraries in all of this?
4.Are all API calls really Java code?
Thanks for your time.
I've been trying to figure out how an android app is installed by browsing AOSP.
The PackageManagerService.java has the gids for the corresponding permissions by parsing the platform.xml file.
PackageInstallerActivity parses and checks for any existing packages and then invokes the InstallAppProgress.
I was able to follow the paths where the package is parsed and validated and PackagerManager.installPackage() method is invoked from InstallAppProgress.initView() to install the package. I know this makes a native call to the JNI library. The corresponding .aidl file is IPackageManager.aidl.
What I want to know is where can I find the implementation of the Stub (or Native code if any) related to this aidl mentioned above?
I'm new to aidl so that is the reason I'm not able to understand its nuances completely. Could somebody kindly point me to the right direction?
So AIDL files are there to define how the service and client talk to each other. They are important for system services because they need to handle multi threading, and there are lots of different apps that may want to talk to it. So IPackageManager.aidl is there to allow clients to communicate to PackageManager.
I took a look at InstallAppProgress.initView() and I don't see a specific call to native code. There is a call to PackageManager here:
pm.installPackageWithVerificationAndEncryption(mPackageURI, observer, installFlags,
installerPackageName, verificationParams, null);
So to explain how this chain works, InstallAppProgress gets the PackageManager from context, which if you follow that chain leads to ContextImpl.getPackageManager() which you will see actually returns the ApplicationPackageManager which extends the abstract PackageManager class.
ApplicationPackageManager has a reference to the actual PackageManagerService which it calls through an interface, which is defined by the aidl file IPackageManager. The manager here is just controlling access to the service, and defining what is and is not actually accessible to the outside world. Apps can not normally get a handle to the PackageManagerService, IIRC it is possible to do so but you must have system privilleges.
To get a better explanation on what aidl files actually are, check out the page on the android site here: Android Interface Definition Language
Consider
PackageInfo info1 = pm.getPackageArchiveInfo(apkPath,PackageManager.GET_PERMISSIONS);
In this statement, by using GET_PERMISSIONS I can get the set of all permissions used in the application.
In the same way can i get the API calls?
Thank you. I am new to this android programming if it is a simple question please forgive
No, you cannot get the API calls by any easy method, and arguably not even by a hard method.
If you had access to the application's installed .apk (and at least on older Android versions you did), you could read through it for obvious invocations of platform functions. (This is a form of "Static Analysis")
However, Java (and hence Dalvik) supports a mechanism called "reflection" which allows looking up and calling functions by name - a name that could be constructed at runtime by circuitous means, or user or network input.
Much of the actual functionality used for calling functionality in the system process is also ultimately performed by name, making another place where functionality not present in the static file could be added at runtime.
Finally, the native underlayers of Android (and likely the DVM as well) permit a determined programmer to dynamically designate arbitrary "data" to be "code" and then execute it.
I'm trying to bind a service from an activity and get possibility to call method of it.
These are in different applications (apk) but uses the same sharedUserId and process.
Since they use the same process, Am I obliged to use AIDL or can I use classic IBinder like for Local Service (described on Android Developer sample) ?
I tried both. AIDL works fine and method for Local Service doesn't works, I have an ClassCastException :
E/AndroidRuntime(17511): java.lang.ClassCastException: com.example.app.MyService$LocalBinder cannot be cast to com.example.app.MyService$LocalBinder
Is it possible to use this method for calling service with two apps in a common "shared" process? Or Is that the use of this shared process still requires an IPC method like AIDL?
If I want to use classic IBinder, it's for keeping my application as simple as possible.
Hope you can help me and sorry for my bad english ;-)
I guess the problem is the following. Even if you use sharedUserId and your applications run in the same process you cannot call methods of your service locally, because your service and application are in different packages. Thus, you can use only AIDL that will create a proxy in your client application.
Your problem is that each app has its own APK containing its own CLASSES.DEX, and classes and interfaces are not shared between them. App1.apk/com.example.Class1 is considered a different type than App2.apk/com.example.Class1. Whether or not they're identical doesn't matter.
There's a few ways you can address this:
1) As you've noticed, you can use AIDL. This is the least efficient mechanism, and obviously limits you to only AIDL-compatible types.
2) You can use Java reflection API's. This is better than AIDL in terms of efficiency, but of course the syntax isn't that great.
3) You can attempt to use custom class loading to somehow finagle it so that both apps have access to the same type. For what you're trying to do, this is going to be more trouble than it's worth.
I need to access com.android.internal.telephony.gsm.GsmSmsDispatcher's sendRawPdu method.
I've done a little research and found that GSMPhone class contains GsmSmsDispatcher instance. I hoped to obtain GSMPhone instance from PhoneFactory but it seems to be uninitialized (it's static variables are null).
Android API version >= 8.
You can't access Android's internal classes using reflection. Each application in Android runs in its own process with its own instance of the Dalvik VM. Classes loaded in one process are not visible to another process. So when you try to access static variables from PhoneFactory, you end up loading the PhoneFactory class with unintialized variables.
Your best will be to do whatever you want to get done using the Android APIs. There are a few ways to get access to some private Android services, but it won't get you too far. The only relevant one for SMS is the isms service. You can look through the methods available in it in the ISms.aidl file present in the com.android.internal.telephony package.