package com.cuckoodroid.droidmon.utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import org.json.JSONException; import org.json.JSONObject; import com.google.gson.Gson; import de.robv.android.xposed.XC_MethodHook.MethodHookParam; import de.robv.android.xposed.XposedBridge; public class Logger { public static final Gson gson = new Gson(); //private static PrintWriter logWriter = null; //private static final int MAX_LOGFILE_SIZE = 40*1024; public static String LOGTAG_SHELL= "Droidmon-shell-"; public static String LOGTAG_WORKFLOW = "Droidmon-apimonitor-"; public static String LOGTAG_ERROR = "Droidmon-error"; public static String LOG_FILE ="/droidmon.log"; public static String LOG_FILE_OLD ="/droidmon_old.log"; public static String PACKAGENAME; /*public static PrintWriter getLogWriter() { if(logWriter == null) { try { File logFile = new File(Environment.getExternalStorageDirectory().getPath()+LOG_FILE); if (logFile.length() > MAX_LOGFILE_SIZE) logFile.renameTo(new File(Environment.getExternalStorageDirectory().getPath()+LOG_FILE_OLD)); logWriter = new PrintWriter(new FileWriter(logFile, true)); logFile.setReadable(true, false); logFile.setWritable(true, false); } catch (IOException e) { log(e.getMessage()); } } return logWriter; }*/ public static void logHook(JSONObject hookData){ XposedBridge.log(LOGTAG_WORKFLOW+PACKAGENAME+":"+hookData.toString()); //log(LOGTAG_WORKFLOW+PACKAGENAME+":"+hookData.toString()); } public static void logShell(String message){ XposedBridge.log(LOGTAG_SHELL+PACKAGENAME+":"+message); //log(LOGTAG_SHELL+PACKAGENAME+":"+message); } public static void logError(String message){ XposedBridge.log(LOGTAG_ERROR+":"+message); //log(LOGTAG_ERROR+":"+message); } /*public synchronized static void log(String text) { Log.d("Droidmon", text); PrintWriter logger = getLogWriter(); if (logger != null) { logger.println(text); logger.flush(); } }*/ public static void logProcessWriteMethod(MethodHookParam param, boolean mThisObject, MethodApiType mType) throws JSONException { if(param.thisObject == null) return; if(param.thisObject.getClass().toString().contains("ProcessOutputStream")) { JSONObject hookData=ParseGenerator.generateHookDataJson(param,mType); hookData.put("buffer", new String((byte[])param.args[0],(Integer)param.args[1],(Integer)param.args[2]).trim()); Logger.logHook(hookData); } } public static void logProcessReadMethod(MethodHookParam param, boolean mThisObject, MethodApiType mType) throws JSONException { if(param.thisObject == null) return; if(param.thisObject.getClass().toString().contains("ProcessInputStream")) { JSONObject hookData=ParseGenerator.generateHookDataJson(param,mType); hookData.put("buffer", new String((byte[])param.args[0],(Integer)param.args[1],(Integer)param.args[2]).trim()); Logger.logHook(hookData); } } public static void logGenericMethod(MethodHookParam param, boolean mThisObject, MethodApiType mType) throws JSONException { JSONObject hookJson = ParseGenerator.generateHookDataJson(param,mType); if(param.args!=null) hookJson.put("args", ParseGenerator.parseArgs(param,hookJson)); if(param.getResult()!=null) hookJson.put("result", ParseGenerator.parseResults(param,hookJson)); if(param.thisObject!=null && mThisObject) hookJson.put("this",ParseGenerator.parseThis(param,hookJson)); Logger.logHook(hookJson); } public static void logReflectionMethod(MethodHookParam param, boolean mThisObject, MethodApiType mType) throws JSONException { JSONObject hookJson = ParseGenerator.generateHookDataJson(param,mType); hookJson.put("hooked_class", ParseGenerator.parseRefelctionClassName(param, hookJson)); hookJson.put("hooked_method", ParseGenerator.parseRefelctionMethodName(param, hookJson)); if(param.args!=null) hookJson.put("args", ParseGenerator.parseRefelctionArgs(param,hookJson)); if(param.getResult()!=null) hookJson.put("result", ParseGenerator.parseResults(param,hookJson)); Logger.logHook(hookJson); } public static void logTraceReflectionMethod(MethodHookParam param, MethodApiType mType) throws JSONException { JSONObject hookJson = ParseGenerator.generateHookDataJson(param,mType); hookJson.put("hooked_method", ParseGenerator.parseRefelctionMethodName(param, hookJson)); hookJson.put("hooked_class", ParseGenerator.parseRefelctionClassName(param, hookJson)); Logger.logHook(hookJson); } public static void logTraceMethod(MethodHookParam param, MethodApiType mType) throws JSONException { Logger.logHook(ParseGenerator.generateHookDataJson(param,mType)); } public static void logAndDumpFile(MethodHookParam param,boolean mThisObject, MethodApiType mType) throws JSONException, IOException { JSONObject hookJson = ParseGenerator.generateHookDataJson(param,mType); String outDir = ""; String dexPath = (String) param.args[0]; hookJson.put("orig", dexPath); //Ignore loading of files from /system or /data/app if (dexPath.startsWith("/system/") || dexPath.startsWith("/data/app") ) { hookJson.put("dump", false); hookJson.put("path", dexPath); } else { hookJson.put("dump", true); String uniq = UUID.randomUUID().toString(); //outDir = outDir + "/" + PACKAGENAME + dexPath.replace("/", "_") + "-" + uniq; outDir = dexPath + "_" + uniq+".DROPPED_FILE"; InputStream in = new FileInputStream(dexPath); OutputStream out = new FileOutputStream(outDir); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); hookJson.put("path", outDir); } Logger.logHook(hookJson); } }