Java Reflection

Import

1
import java.lang.reflect.*;

Get Class, Field and Method Objects

1
2
3
4
Class<?> class = ClassforName("<className>"");
Field field = class.getDeclaredField("<field_name>");
Method method = class.getDeclaredMethod("<methodName>", Class<?>... parameterTypes)
// e.g. method = class.getDeclaredMethod("func", String.class, String.class);

Make private fields or methods accessible

1
2
field.setAccessible(true);
method.setAccessible(true);

Read and write fields

1
2
field.get(Object instance); // return the value(return type: Object)
field.set(Object instance, Object value);

Invoke methods

1
2
method.invoke(Object instance, Object... args); // return Object
// instance is null for static methods

Modify final fields

1. Get the final field

1
2
3
4
// First get the final field we want to modify
Class<?> class = ClassforName("<className>"");
Field the_final_field = class.getDeclaredField("<field_name>");
the_final_field.setAccessible(true);

2. Cancel the final bit

For general JVM

1
2
3
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(the_final_field, the_final_field.getModifiers() & ~Modifier.FINAL);

For Android

The member of Field representing modifiers is different. modifiers -> accessFlags

1
2
3
4
Field modifiersField = Field.class.getDeclaredField("accessFlags");
// the following code is the same
modifiersField.setAccessible(true);
modifiersField.setInt(the_final_field, the_final_field.getModifiers() & ~Modifier.FINAL);

Reference

java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
Java Reflection Tutorial

Install SGX

For Ubuntu 16.04 LTS.

Download the following installation packages from https://01.org/intel-software-guard-extensions/downloads

  • Intel(R) SGX driver: sgx_linux_x64_driver.bin
  • Intel(R) SGX PSW: sgx_linux_x64_psw_<version>.bin
  • Intel(R) SGX SDK: sgx_linux_x64_sdk_<version>.bin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# Intel(R) SGX PSW Dependecies
sudo apt-get install libssl-dev libcurl4-openssl-dev libprotobuf-dev

# Intel(R) SGX SDK Dependecies
sudo apt-get install build-essential

# (Optional) Download [iclsClient]
# (http://registrationcenter-download.intel.com/akdlm/irc_nas/11414/iclsClient-1.45.449.12-1.x86_64.rpm)
# or (https://software.intel.com/en-us/sgx-sdk/download)
# and install it using the following commands
sudo apt-get install alien
sudo alien --scripts iclsClient-1.45.449.12-1.x86_64.rpm
sudo dpkg -i iclsclient_1.45.449.12-2_amd64.deb

# Download source code from the[dynamic-application-loader-host-inter-face]
# (https://github.com/01org/dynamic-application-loader-host-interface)
# project. In the source code folder build and install the JHI service using
# the following commands
sudo apt-get install uuid-dev libxml2-dev cmake pkg-config libsystemd-dev
git clone https://github.com/intel/dynamic-application-loader-host-interface.git
(cd dynamic-application-loader-host-interface; mkdir build; cd build;cmake ..; make -j; sudo make install; sudo systemctl enable jhi)

sudo apt-get -y install kmod libelf-dev linux-headers-$(uname -r)

# Install the following downloaded packages
# 1. Intel(R) SGX driver
# 2. Intel(R) SGX PSW
# 3. Intel(R) SGX SDK
sudo ./sgx_linux_x64_driver.bin
sudo ./sgx_linux_x64_psw_<version>.bin
# type no and type /opt/intel as the installation path
sudo ./sgx_linux_x64_sdk_<version>.bin

source /opt/intel/sgxsdk/environment

# Use the LocalAttestation to test
cp -r /opt/intel/sgxsdk/SampleCode .
cd SampleCode/LocalAttestation
make SGX_MODE=SIM
./app

Reference

Intel® Software Guard Extensions for Linux* OS
Intel_SGX_Installation_Guide_Linux_2.0_Open_Source
Intel_SGX_SDK_Developer_Reference_Linux_2.0_Open_Source
Intel_SGX_Developer_Guide
Intel® Software Guard Extensions Programming Reference

How to Check If an App is System App or Not

Definition

The definition of system app is not very clear. There are at least three different definitions:

  1. Apps in system partition (/system)
    • These apps will get the flag ApplicationInfo.FLAG_SYSTEM
    • If an updated version is installed (probably not under /system), it will get ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
  2. Apps signed with platform signature
  3. Apps in /system/priv-apps and /system/framework
    • These apps will get the flag ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
    • The flag is set in PackageManagerService.java
    • These apps will be granted signatureOrSystem level permissions (corresponding to the System in signatureOrSystem)
    • For Samsung, apps in /system/carrier/priv-app and /odm/priv-app will also get this flag

Check

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import java.lang.reflect.*;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "XKXXXX";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


PackageManager pm = getApplicationContext().getPackageManager();
List<PackageInfo> list = pm.getInstalledPackages(0);
for(PackageInfo pi : list) {
try {
ApplicationInfo ai = pm.getApplicationInfo(pi.packageName, 0);
String strSignedBySys = isSignedBySystem(pm, pi.packageName)?"SYS_SIGN":"NONSYS_SIGN";
String strUnderSys = isAppInSystemPartition(pm, pi.packageName)?"UNDER_SYS":"NOT_UNDER_SYS";
String strPrivileged = isPrivilegedApp(ai)?"PRIV":"NON_PRIV";
Log.d(TAG, String.format(">>>>>> %s <<<<<<<< %s %s %s %s",
pi.packageName,
ai.publicSourceDir,
strSignedBySys,
strUnderSys,
strPrivileged));
}catch (Exception e) {
Log.d(TAG, "exception ", e);
}
}
}

/**
* Check if an App is under /system or has been installed as an update to a built-in system application.
*/
public static boolean isAppInSystemPartition(PackageManager pm, String packageName) {
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return ((ai.flags & (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0);
}catch (NameNotFoundException e) {
Log.d(TAG, "exception", e);
return false;
}
}

/**
* Check if an App is signed by system or not.
*/
public boolean isSignedBySystem(PackageManager pm, String packageName) {
try {
PackageInfo pi_app = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
PackageInfo pi_sys = pm.getPackageInfo("android", PackageManager.GET_SIGNATURES);
return (pi_app != null
&& pi_app.signatures != null
&& pi_sys.signatures[0].equals(pi_app.signatures[0]));
}catch (NameNotFoundException e) {
Log.d(TAG, "exception", e);
return false;
}
}

/**
* Check if an App has ApplicationInfo.PRIVATE_FLAG_PRIVILEGED (under /system/priv-app or /system/framework)
*/
public static boolean isPrivilegedApp(ApplicationInfo ai) {
try {
Method method = ApplicationInfo.class.getDeclaredMethod("isPrivilegedApp");
return (Boolean)method.invoke(ai);
} catch(Exception e) {
Log.d(TAG, "exception", e);
return false;
}
}
}

Reference

Definition of PRIVATE_FLAG_PRIVILEGED in ApplicationInfo.java
How to check if application is system app or not (By signed signature)
Android permission element

How to Sign Android App with Platform Signature

1
java -jar signapk.jar platform.x509.pem platform.pk8 unsigned.apk signed.apk

signapk.jar can be found under <root-of-android-source-tree>/out/host/<your-host>/framework/
platform.x509.pem and platform.pk8 can be found under <root-of-android-source-tree>/build/target/product/security/

Grant an App the System Uid (Optional)

In the AndroidManifest.xml of your application: in the <manifest> tag, add the attribute android:sharedUserId="android.uid.system".

Reference

How to sign Android app with system signature?