123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- package de.tudarmstadt.informatik.hostage.system;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import android.app.Activity;
- import android.util.Log;
- import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
- import de.tudarmstadt.informatik.hostage.ui.activity.MainActivity;
- public class Device {
- private static String porthackFilepath = "/data/local/bind";
- private static boolean initialized = false;
- private static boolean root = false; // device is rooted
- private static boolean porthack = false; // porthack installed
- private static boolean iptables = false; // iptables redirection confirmed working
- public static void checkCapabilities() {
- // assume worst case
- initialized = false;
- root = false;
- porthack = false;
- iptables = false;
- porthackFilepath = getPorthackFilepath();
- String porthackExists = "[ -e "+porthackFilepath+" ]"; // checks existence of porthack
- try {
- Process p = new ProcessBuilder("su", "-c", porthackExists).start();
- switch (p.waitFor()) {
- case 0: porthack = true;
- // fall through and don't break
- case 1: root = true; // 0 and 1 are valid return values of the porthack
- break;
- case 127: // command not found or executable
- root = false;
- porthack = false;
- break;
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- final String ipTablesList = "iptables -L -n -t nat"; // list all rules in NAT table
- try {
- Process p = new ProcessBuilder("su", "-c", ipTablesList).start();
- switch (p.waitFor()) {
- case 0: // everything is fine
- iptables = true; // iptables available and working
- break;
- case 3: // no such table
- case 127: // command not found
- default: // unexpected return code
- // while testing code 3 has been returned when table NAT is not available
- iptables = false;
- }
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- initialized = true;
- }
- public static boolean isRooted() {
- assert(initialized);
- return root;
- }
- public static boolean isPorthackInstalled() {
- assert(initialized);
- return porthack;
- }
- public static boolean isPortRedirectionAvailable() { // using iptables
- assert(initialized);
- return iptables;
- }
- /**
- * copies an asset to the local filesystem for later usage
- * (used for port hack and shell scripts)
- * @param assetFilePath
- * @param destFilePath
- * @return true on success
- */
- private static boolean deployAsset(String assetFilePath, String destFilePath) {
- Activity activity = MainActivity.getInstance();
- File file = new File(activity.getFilesDir(), destFilePath);
- try {
- OutputStream os = new FileOutputStream(file);
- try {
- InputStream is = activity.getAssets().open(assetFilePath);
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = is.read(buffer)) != -1) {
- os.write(buffer, 0, bytesRead);
- }
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- os.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- return false;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- //Log.i("FILEPATH", file.getAbsolutePath());
- return true; // SUCCESS!
- }
- public static void executePortRedirectionScript() {
- assert(iptables); // we need iptables for our next trick
- if (deployAsset("payload/redirect-ports.sh", "redirect-ports.sh")) {
- String scriptFilePath = new File(MainActivity.getInstance().getFilesDir(), "redirect-ports.sh").getAbsolutePath();
- Process p = null;
- try {
- p = new ProcessBuilder("su", "-c", "sh "+scriptFilePath).start();
- p.waitFor(); // stall the main thread
- // TODO: check return value?
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * @return name of porthack binary for device architecture
- */
- private static String getPorthackName() {
- String porthack = "bind";
- // determine system architecture to return the correct binary
- String arch = System.getProperty("os.arch");
- // TODO: handle more architectures
- if (arch.equals("i686")) { // this is what genymotion reports
- porthack += ".x86";
- } else if (arch.startsWith("arm")) {
- /*
- possible values:
- armv4
- armv4t
- armv5t
- armv5te
- armv5tej
- armv6
- armv7
- */
- porthack += ".arm";
- } else if (arch.equals("mips")) {
- porthack += ".mips";
- }
- return porthack;
- }
- /**
- * @return filepath to deployed porthack binary
- */
- public static String getPorthackFilepath() {
- File file = new File(MainActivity.getInstance().getFilesDir(), getPorthackName());
- return file.getAbsolutePath();
- }
- public static boolean deployPorthack() {
- String porthack = getPorthackName();
- if (!deployAsset("payload/"+porthack, porthack)) {
- return false; // :(
- }
- // make port hack executable
- try {
- Process p = new ProcessBuilder("su", "-c", "chmod 700 "+getPorthackFilepath()).start();
- if (p.waitFor() != 0) {
- logError(p.getErrorStream());
- return false;
- }
- logOutput(p.getInputStream());
- } catch (IOException e) {
- return false;
- } catch (InterruptedException e) {
- return false;
- }
- return true; // SUCCESS!
- }
- public static void uninstallPorthack() {try {
- Process p = new ProcessBuilder("su", "-c", "rm "+getPorthackFilepath()).start();
- if (p.waitFor() != 0) {
- logError(p.getErrorStream());
- }
- logOutput(p.getInputStream());
- } catch (IOException e) {
- } catch (InterruptedException e) {
- }
- }
- // copied from PrivilegedPort.java
- private static void logOutput(InputStream stdout) throws IOException {
- BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
- String line;
- while ((line = reader.readLine()) != null) {
- Log.i("HelperUtils", line);
- }
- }
- private static void logError(InputStream stderr) throws IOException {
- BufferedReader reader = new BufferedReader(new InputStreamReader(stderr));
- Log.e("HelperUtils", reader.readLine());
- }
- }
|