This commit is contained in:
parent
1ee8013522
commit
c87fe714a9
7 changed files with 127 additions and 6 deletions
93
6_theseus/1_static_transformation.typ
Normal file
93
6_theseus/1_static_transformation.typ
Normal file
|
@ -0,0 +1,93 @@
|
|||
#import "../lib.typ": todo, APK, DEX, JAR, OAT, eg
|
||||
|
||||
== Code Transformation <sec:th-trans>
|
||||
|
||||
#todo[Define code loading and reflection somewhere]
|
||||
#todo[This is a draft, clean this up]
|
||||
#todo[Reflectif call? Reflection call?]
|
||||
|
||||
In this section, we will see how we can transform the application code to make dynamic codeloading and reflexif calls analysable by static analysis tools.
|
||||
|
||||
=== Reflection <sec:th-trans-ref>
|
||||
|
||||
In Android, reflection can be used to do two things: instanciate a class, or call a method.
|
||||
Either way, reflection starts by retreiving the `Class` object representing the class to use.
|
||||
This class is usually retrived using a `ClassLoader` object, but can also be retrieved directly from the classloader of the class defining the calling method.
|
||||
// elaborate? const-class dalvik instruction / MyClass.class in java?
|
||||
One the class is retrieve, it can be instanciated using the deprecated method `Class.newInstance()`, like shown in @lst:-th-expl-cl-new-instance, or a specific method can be retrieved.
|
||||
The current approche to instanciate a class is to retrieve the specific `Constructor` object, then calling `Constructor.newInstance(..)` like in @lst:-th-expl-cl-cnstr.
|
||||
Similarly, to call a method, the `Method` object must be retrieved, then called using `Method.invoke(..)`, like shown in @lst:-th-expl-cl-call.
|
||||
|
||||
Although the process seems to differ between class instanciation and method call from the Java stand point, the runtime opperations are very similar.
|
||||
When instanciating an object with `Object obj = cst.newInstance("Hello Void")`, the constructor method `<init>(Ljava/lang/String;)V`, represented by the `Constructor` `cst`, is called on the object `obj`.
|
||||
|
||||
#figure(
|
||||
```java
|
||||
ClassLoader cl = MainActivity.class.getClassLoader();
|
||||
Class clz = cl.loadClass("com.example.Reflectee");
|
||||
Object obj = clz.newInstance();
|
||||
```,
|
||||
caption: [Instanciating a class using `Class.newInstance()`]
|
||||
) <lst:-th-expl-cl-new-instance>
|
||||
|
||||
#figure(
|
||||
```java
|
||||
Constructor cst = clz.getDeclaredConstructor(String.class);
|
||||
Object obj = cst.newInstance("Hello Void");
|
||||
```,
|
||||
caption: [Instanciating a class using `Constructor.newInstance(..)`]
|
||||
) <lst:-th-expl-cl-cnstr>
|
||||
|
||||
#figure(
|
||||
```java
|
||||
Method mth = clz.getMethod("myMethod", String.class);
|
||||
String retData = (String) mth.invoke(obj, "an argument");
|
||||
```,
|
||||
caption: [Calling a method using reflection]
|
||||
) <lst:-th-expl-cl-call>
|
||||
|
||||
To allow static analysis tools to analyse an application that use reflection, we want to replace the reflection call by the bytecode that does the actual calls.
|
||||
|
||||
One of the main reason to use reflection is to access classes not from the application.
|
||||
Although allows the use classes that do not exist in the application in bytecode, at runtime, if the classes are not found in the current classloader, the application will crash.
|
||||
Similarly, some analysis tools might have trouble analysis application calling non existing classes.
|
||||
@sec:th-trans-cl deals with the issue of adding dynamically loaded bytecode to the application.
|
||||
|
||||
A notable issue is that a specific reflection call can call different methods.
|
||||
@lst:th-worst-case-ref illustrate a worst case scenario where any method can be call at the same reflection call.
|
||||
In those situation, we cannot garanty that we know all the methodes that can be called (#eg the name of the method called could be retrieved from a remote server).
|
||||
|
||||
|
||||
#figure(
|
||||
```java
|
||||
Object myInvoke(Object obj, Method mth, Object[] args) throws .. {
|
||||
return mth.invoke(obj, args);
|
||||
}
|
||||
```,
|
||||
caption: [A reflection call that can call any method]
|
||||
) <lst:th-worst-case-ref>
|
||||
|
||||
=== Code loading <sec:th-trans-cl>
|
||||
|
||||
#todo[custom class loaders]
|
||||
|
||||
An application can dynamically import code from several format like #DEX, #APK, #JAR or #OAT, either stored in memory or in a file.
|
||||
Because it is an internal, platform dependant format, we elected to ignore the #OAT format.
|
||||
Practically, #JAR and #APK files are zip files containing #DEX files.
|
||||
This means that we only need to find a way to integrate #DEX files to the application.
|
||||
|
||||
We elected to simply add the dex files to the application, using the multi-dex feature introduced by the SDK 21 now used by all applications.
|
||||
This gives access to the dynamically loaded code to static analysis tool.
|
||||
|
||||
#todo[add drawing of dex insertion]
|
||||
|
||||
We decided to leave untouched the original code that load the bytecode.
|
||||
At runtime, although the bytecode is already present in the application, the application will still dynamically load the code.
|
||||
This ensure that the application keep working as intended even if the transformation we applied are incomplete.
|
||||
Specifically, to call dynamically loaded code, an application needs to use reflection, and we saw in @sec:th-trans-ref that we need to keep reflecton calls, and in order to keep reflection calls, we need the classloader created when loading bytecode.
|
||||
|
||||
=== Class Collisions <sec:th-class-collision>
|
||||
|
||||
=== Pitfalls
|
||||
|
||||
#todo[interupting try blocks: catch block might expect temporary registers to still stored the saved value]
|
7
6_theseus/3_results.typ
Normal file
7
6_theseus/3_results.typ
Normal file
|
@ -0,0 +1,7 @@
|
|||
#import "../lib.typ": todo
|
||||
|
||||
== Results #todo[better section name] <sec:th-res>
|
||||
|
||||
=== Bytecode Loaded by Application <sec:th-code-collected>
|
||||
|
||||
#todo[Bytecode collected: facebook, google, appsflyer]
|
9
6_theseus/4_ttv.typ
Normal file
9
6_theseus/4_ttv.typ
Normal file
|
@ -0,0 +1,9 @@
|
|||
#import "../lib.typ": todo
|
||||
|
||||
== Limits and Threat to Validity <sec-ttv>
|
||||
|
||||
#todo[redaction]
|
||||
|
||||
- Use multidex: min SDK >= 21 (android 5.0, published in 2014, should be ok)
|
||||
- No support for OAT (platform dependent)
|
||||
|
7
6_theseus/main.typ
Normal file
7
6_theseus/main.typ
Normal file
|
@ -0,0 +1,7 @@
|
|||
#import "../lib.typ": todo
|
||||
|
||||
= #todo[theseus chapter title]
|
||||
|
||||
#include("1_static_transformation.typ")
|
||||
#include("3_results.typ")
|
||||
#include("4_ttv.typ")
|
Loading…
Add table
Add a link
Reference in a new issue