Can I enumerate all native methods in java, those that have to be
implemented in c/c++ using JNI?
Can I enumerate native methods by
name (there could be multiple overloads with the same name)?
How can I retrieve method signature to be able to generate the method
signature used by JNI?
Is there a way to check if all native jni methods have been bound properly, instead of trying to call them and get java.lang.UnsatisfiedLinkError exceptions. Sometimes method signature changes on either side without properly updating java or c++ side and I'd like to add some debugging code to detect these issues and handle them (perhaps by generating proper method signature and printing it to the log so I can easily fix the code).
I prefer JNI solution, but if something can be done with help on java side then it's ok also.
If I use registerNatives and register methods that weren't declared in java then it fails and prints it to logcat:
E/dalvikvm( 1445): ERROR: couldn't find native method
E/dalvikvm( 1445): Requested: Lcom/bla/bla/bla/Test;.nativeTestXX:()Z
but I'd like to catch this error and handle it myself. Is it possible to do it?
EDIT:
In my JNI code I have a static nativeInit (as suggested in Android JNI tips) that registers all native methods. In that same function I'd like to verify that all native methods are properly bound. That is, I don't need to wait till some uninitialized method is called and the app exists. The problem that I have: there is a lot of jni code written at different times by different ppl and some methods simply became incorrect, but they are used only in some obscure conditions. The best way for me, I think, is to check that all native methods are bound to some c++ function. The other problem, is that part of JNI code uses binding by exporting all these Long_java_names where method signature changes on either side cannot be detected.
There is no call to check for "unbound" native methods. Using RegisterNatives to perform explicit registration ensures that all methods you register have a matching declaration in the Java sources, but there is no way to check for native-declared methods for which there is no implementation (other than calling it and catching the exception).
At the point where a method with a native implementation is called, if nothing has yet been registered then Dalvik will search through the various shared libraries to find a match. What it sounds like you want is a way to force this search and check the result without actually calling the method. There is no such thing.
There are various ways to generate lists of native-declared methods, either statically or at runtime, but you also need a way to determine if an implementation is available. You're better off in the long run having unit tests that exercise the code.
Related
I'm considering using Proguard as my app comes closer to production to make it lighter.
On Android, there's the 65K method limit in addition to low storage devices. I know that Proguard removes unused methods, but does it remove methods which are used only in one place? I mean, I'm writing some methods just to make the code cleaner, but it would save a method call (one of the most expensive operation with return for the CPU and RAM, I studied microcode) and a method in the 65K max count as well as some bytes in the final package.
Does Proguard detect such cases and remove methods? Do I have to configure it myself? What about stacktrace deobfuscation if so?
It does not remove them since the code is used.
If you have the method/inlining/unique optimization enabled, it will inline such methods: the method call is removed and the method code is inserted in the place where the method call was.
What about stacktrace deobfuscation if so?
If there's an exception in the inlined method, it will show up in the stacktrace at the method call site (where the call was removed).
If used proguard will not remove the method.
And, If you already know one such method, why don't you just build an apk with proguard enabled and test out the functionality in the app which makes the method call and check for yourself?
I have been using premain() with addTransformer(). Since, it gives javassist.ClassNotFound exceptions for certain classes when i run the agent with a server, i thought to try the agentMain() with redefineClasses(). I went through many links, but so far i am unable to find a piece of code that gives me clear idea on how to set up a simple java agent using these two methods. Some help would be really appreciated.
Can we use redefineClasses() with premain()? (When we use redefineClasses() do we still need the transform method?)
I am trying to instrument set of methods of set of classes, where i know the fully qualified name of those classes as com.test.Foo. I wanted to instrument them without going through the entire set of classes loaded onto JVM. I have been reading those documents back and forth, but still i am unable to get a clear idea on how to use that redefineClasses method?
You can call redefineClasses from anywhere, also from a premain method which is nothing but an extension to a normal Java program run by the same JVM process previous to a main method.
A trivial example for running a redefinition is:
instrumentation.redefineClasses(new ClassDefinition(Foo.class, new byte[] {...}));
This way, Foo is set to be represented by the byte array that must contain a valid class file for Foo where all signatures of fields and methods are the same as by the loaded Foo.class. You can use a tool like ASM for instrumenting the class.
If you really only want to instrument Foo, then this might just be the way to go instead of using a ClassFileTransformer.
I'm making software (for Android) to read out meter values from sensors.
The software is expected to receive updates very often in order to support more sensors. The functionality to read out the meter data voor these sensors is implemented in native libraries that are downloaded on runtime by the app.
I've got a list of shared objects and an entry function that should be called (the return value is saved):
libprintf.so,hookPrintf
libharx.so,hookHarx
Each library is loaded at runtime: System.loadLibrary("printf");
The signature of each function would look like this:
public native int hookPrintf();
public native int hookHarx();
The problem is that I don't know beforehand (at compile time) which shared objects will have to be loaded, and thus I can not add these signatures in the java source.
I tried using Reflection to call the methods dynamically as follows:
Method entryMethod = Expat.class.getMethod(hookMethod);
Object test = entryMethod.invoke(this);
System.out.writeln(test.toString());
However, if the signature is not present, this will still fail with a NoSuchMethodException. Is there another way to be able to call native methods without needing to have them defined beforehand?
Edit:
Using the RegisterNatives function, I can register my functions dynamically from the shared object, but that still requires the method signature to be defined in the class.
What does the registerNatives() method do?
You probably can have a Java class with only two native methods, and rely on RegisterNatives and UnregisterNatives and switch the loaded native implementations at runtime. With that, I would rather use a native wrapper library with native methods
private static native void hook(String libName, String hookName);
This wrapper will use dlopen() or LoadLibraryEx() and also unload the external libraries when necessary.
In some JVMs you can dynamically create new classes, but that is quite tricky.
You have a fundamental design issue. I would suggesting going back and create a JNI library that implements a single method like public native int createHook() or something equivalent. Then make the choice in your native code based on some conditional. If you still want/need to load the libraries at runtime, create non-jni libs for libprintf.so and libharx.so and use either dlopen to dynamically load the library or weakly link the libraries to the jni library.
I have a code like below in project. Here by casting with interface we are calling the method authenticate() of the service IAuthenticateService. Now there are 5 subclasses which have the same method implementation and Implementing the same interface IAuthenticateService. By seeing the code how will I come to know which class method implementation has been called? I'm little bit confused of interface design.
((IAuthenticateService) AuthServiceApp.getInstance().getContext()
.getService(ServiceEnum.CredentialService.name()))
.authenticate(inputParams);
You can't know just by reading this code.
But, the program will know at runtime which implementation to call : the object returned by AuthServiceApp.getInstance().getContext() will have a type, which one will have a single implementation of the method getService, and this implementation will be called.
As a programmer, you don't need to know more. The programming by contract paradigm allows you not to bother about which implementation will be called. All you need to know is that given a certain environment, you will get an instance of a context on which you can call getService(), AND it will provide you with a service.
The rest is details, you don't have to worry about it.
Of course, when you are debugging, that's a different story : you want to know which implementation is executed as it might be buggy. In that case, just follow the debugger to see which code is really executed, but otherwise, you should not care, that's all what polymorphism is about : gaining abstraction.
Well you not being able to tell what implementation of IAuthentication is being returned is the whole point of interfaces. We use interfaces to segment parts of code away from each other. This makes programs more extensible and versatile which drives code reuse. It is a very powerful concept and the corner stone of modern software development. The client (the code using the interface's methods) does not care what is on the other side of the interface (ie the implementer of the interface). This allows for the client side to change at runtime. The fact that you don't know is what gives its power. In order to understand this concept you have to think about how the compiler works and what it does when it compiles code.
In compiled languages the compiler translates source code into machine instructions. When it is translating a method into a machine code the method receives an address in memory where the method starts. When another piece of code calls that method that memory address is written in the code on the client code. That memory address is fixed so that piece of code can't call any other method at runtime. It will always call that one method and never a different method.
For example say we have something like this:
private int someMethod() { ... }
The compiler says someMethod is located at 003. So when it's compiling code like this:
public myMethod() {
this.someMethod();
}
It says myMethod calls someMethod, and looks up where in memory someMethod lives. Roughly it will write out something like:
// myMethod
call 003
Now that method invocation (aka call site) can only ever call someMethod forever. It will never call any other method but that exact method.
But in OO languages we can vary which actual method is called at runtime. That means the compiler can't write that memory address into the callers code when it is compiling the class. Instead it has to look up that method address at runtime. How it does that is by looking up the method by name in the object it is passed at runtime. So the compiler might do something like this:
// myMethod
methodAddress = this.methodsAddresses['someMethod']
call methodAddress
It's that lookup (sometimes called the virtual pointer table) that enables methods to change depending on what someObject points to, and that lookup allows it to vary at runtime.
This is all well and good until you need to debug something. If you are trying to debug something its easiest if you use a debugger, and drop a break point in your client code and you can easily look at that an many other things along with stepping into the code. You can also print someObject.getClass().getName() to find the name, but that is just the beginning if you are debugging.
I am working on developing a library that needs to instantiate and return untrusted objects downloaded from an external website. At a high-level, the library works as follows:
Clients of the library requests a class from a remote source.
My library instantiates that object, then returns it to the user.
This is a major security risk, since the untrusted code can do just about anything. To address this, my library has the following design:
I enable the SecurityManager and, when instantiating the untrusted object, I use an AccessController to handle the instantiation in a context where there are no privileges.
Before returning the object back to the client, I wrap the object in a decorator that uses an AccessController to forward all method requests to the underlying object in a way that ensures that the untrusted code is never run with any permissions.
It occurs to me, though, that this might not be the most elegant solution. Fundamentally, I want to strip away all permissions from any object of any type downloaded from the remote source. My current use of AccessController is simply a way of faking this up by intercepting all requests and dropping privileges before executing them. The AccessController approach also has its own issues:
If the wrapped object has any methods that return objects, those returned objects have to themselves be wrapped.
The wrapper code will potentially be thousands of lines long, since every exported method has to be secured.
All of the methods exported by the downloaded object have to be known in advance in order to be wrapped.
My question is this: is there a way to load classes into the JVM (probably using a custom ClassLoader) such that any instances of those classes execute their methods with no permissions?
Thanks!
You will want to call defineClass with an untrusted ProtectionDomain.
Your current solution has a number of problems. It doesn't appear to cover the static initialiser. It may be possible to install code into some mutable arguments. Methods that use the immediate caller will still be privileged (AccessController.doPrivileged, say). But most of all, it falls about when rubbing up against any kind of global - for instance running a finaliser.
Don't know if there's a way to directly do what you asked, but I think your approach can be simplified by using interfaces and dynamic proxies. Basically, if you have an interface for the object to be returned, and all its methods return either simple types or interfaces, then you can wrap all the methods and their return values automatically, without knowing the methods in advance. Just implement an InvocationHandler that does the AccessController magic in its invoke method, and create proxies using Proxy.newProxyInstance(...).