13

I'm doing research for a static analysis tool to help detect malware in Android applications. I'm wondering if it is possible to perform code injection on Android without using a class loader. I know it is possible to load byte code at runtime using the Dex class loader, but I'd like to know if its possible to do this without using a class loader. I've found projects like https://github.com/miktam/Disabler, which use things like AspectJ to add logging and tracing at runtime. Correct me if I'm wrong but I think this probably uses a class loader somewhere deep down in the AspectJ library.

I'm thinking something more along the lines of overwriting/implementing a method at runtime with arbitrary byte code of a class that is already loaded, so that the next time it is called it performs some malicious/undeclared action from the original source implementation. Is this possible? If so how would one go about doing so?


Update: Trying to clarify my question a bit more.

I'm not interested in calling native code directly or using Runtime.exec. I have already examined those Java API's in my tool. Let me give a rough code idea of something I was thinking.

public static void main(String[] args){
    hello(); // BENIGN
    evil("hello", getFile("com.blah.MyClass"));
    hello(); // MALWARE, or alternatively since it might not be loaded also BENIGN until next time application is run.
}

public static void hello(){System.out.println("Hi!");}

public static void evil(String methodName, File classFile){
    byte[] evilMethodImplementation = {0x...}; // some crafted byte code to replace the body of a method in a class file
    RandomAccessFile raf = new RandomAccessFile(classFile, "rw");
    raf.seek(findMethodBody(methodName, classFile)); // seek to the body contents of the method
    raf.write(evilMethodImplementation); // overwrite the current implementation with malicious implementation
    raf.close();
}

This is just an idea of something I was considering to see if it was possible. Basically I want to know if its possibly to do Reflection without using the reflection interfaces as some sort of messy hack that would bypass my detection.

Ben Holland
  • 505
  • 1
  • 5
  • 13
  • 1
    Specifically I don't want to have to use java.lang.reflect.*, and if I do I'd like its use to be minimal....if its even possible. – Ben Holland Feb 08 '13 at 22:57
  • Why do you want to do code injection without using a class loader? What are the real constraints/requirements that lead to you rejecting using a class loader? (Those constraints may prohibit other approaches as well -- or they may not.) – D.W. Feb 09 '13 at 04:45
  • 2
    I want to know if there is a way to inject code without a class loader because currently my static analysis looks for uses of class loaders. If there is a way to inject code without using a class loader I will need to address those techniques as well. It wouldn't be a very good analysis if I only detected the easy/common techniques :P – Ben Holland Feb 10 '13 at 06:02

1 Answers1

13

Yes, absolutely, there are other ways to do code injection. For instance, a malicious app can execute native code directly, and that doesn't require any class loader.

More generally, in the Android security model, the only security boundary is at the process level (not at the JVM level). So, nothing in Android prevents code injection into a process that you already control. As the Android docs state, untrusted code cannot be safely isolated within the Dalvik VM. That's just a fundamental consequence of Android's security architecture.

(As additional examples, you may also be able to invoke Runtime.getRuntime().exec() to execute native code, disable the Java Security Manager, call setAccessible(., true) and then take over the process, exploit vulnerabilities in any of the Java libraries, or use any of a number of other methods.)

(Also, in Java, some security checks are done by the compiler and are not duplicated by the JVM. Consequently, malicious bytecode can bypass these checks. These checks include, e.g., access control for inner classes, exception safety, final fields, and others. I don't know if the same holds for Dalvik as well, but there are many hairy details here that might allow malicious bytecode to attack class libraries.)

D.W.
  • 98,420
  • 30
  • 267
  • 572
  • Thanks those are great answers to what I ended up giving as a poor question. I already know about JNI and the Runtime.exec. The setAccessible method is a good example (I'm currently detecting this as well). I guess I'm wondering if there is anyway to run arbitrary code outside of Reflection/JNI/Process. My thought was that if it was possible, the byte code would have to be loaded somehow, and if you couldn't use a class loader you would be stuck modifying a class that is already loaded or would be loaded through the program as part of the normal execution. Maybe I'm going about it wrong? – Ben Holland Feb 10 '13 at 06:38