package com.cuckoodroid.droidmon.utils;
import android.content.Intent;
import android.os.Bundle;
import com.google.gson.Gson;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.Set;
import javax.crypto.Cipher;
import javax.net.ssl.HttpsURLConnection;
public class ParseGenerator {
private static Gson gson = new Gson();
public static Object parse(Object obj) throws Exception {
Object returnObj=null;
if(obj instanceof byte[])
returnObj = byteArrayParse(obj);
else if(obj instanceof HttpRequestBase)
returnObj = httpRequestBaseParse(obj);
else if(obj instanceof HttpResponse)
returnObj = httpResponseParse(obj);
else if(obj instanceof HttpURLConnection || obj instanceof HttpsURLConnection )
returnObj = URLConnectionParse(obj);
else if(obj instanceof URL)
returnObj = URLParse(obj);
else if(obj instanceof MessageDigest)
returnObj = messageDigestParse(obj);
else if(obj instanceof Cipher)
returnObj = cipherParse(obj);
else if(obj instanceof Intent)
returnObj = intentParse(obj);
else
returnObj = genericParse(obj);
return returnObj;
}
private static Object URLParse(Object obj) {
URL url = (URL) obj;
return url.toString();
}
private static String byteArrayParse(Object obj) {
if(Strings.isAsciiPrintable((byte[]) obj))
return new String((byte[])obj);
else
return HexDump.dumpHexString((byte[]) obj);
}
private static JSONObject cipherParse(Object obj) throws JSONException {
JSONObject json=new JSONObject();
JSONObject cipher = new JSONObject(gson.toJson(obj));
json.put("mode", cipher.get("mode"));
return json;
}
private static Object genericParse(Object obj) {
try {
return new JSONObject(gson.toJson(obj));
} catch (Exception e) {
try {
return new JSONArray(gson.toJson(obj));
} catch (Exception e1) {
return obj.toString();
}
}
}
private static String httpRequestBaseParse(Object obj) throws IOException {
HttpRequestBase request = (HttpRequestBase)obj;
StringBuilder sb = new StringBuilder();
Header[] headers = request.getAllHeaders();
sb.append(request.getRequestLine().toString()+"\n");
for (Header header : headers) {
sb.append(header.getName() + ": " + header.getValue()+"\n");
}
sb.append("\n");
if(request instanceof HttpPost)
sb.append( EntityUtils.toString(((HttpPost) request).getEntity()));
return sb.toString();
}
private static Object httpResponseParse(Object obj) throws IOException {
HttpResponse response = (HttpResponse)obj;
return response.getStatusLine().toString();
}
private static Object intentParse(Object obj){
JSONObject json=new JSONObject();
Intent intent = (Intent) obj;
Bundle bundle = intent.getExtras();
String cmp;
try {
cmp = intent.getComponent().flattenToString();
json.put("cmp",cmp);
} catch (Exception e1) {
}
try {
String action = intent.getAction();
json.put("act", action);
} catch (Exception e1) {
}
JSONArray extraData = new JSONArray();
try {
Set<String> set = bundle.keySet();
for (String key : set) {
JSONObject extra= new JSONObject();
extra.put("key",key);
extra.put("value",bundle.get(key).toString());
extraData.put(extra);
}
json.put("extras", extraData);
} catch (Exception e) {
}
return json;
}
private static JSONObject URLConnectionParse(Object obj) throws IOException, JSONException {
HttpURLConnection con = (HttpURLConnection) obj;
JSONObject urlConnectionObject=new JSONObject();
urlConnectionObject.put("response_code", con.getResponseCode());
urlConnectionObject.put("response_message", con.getResponseMessage());
urlConnectionObject.put("request_method",con.getRequestMethod());
urlConnectionObject.put("url",con.getURL());
urlConnectionObject.put("version","HTTP/1.1");
return urlConnectionObject;
}
private static String messageDigestParse(Object obj) {
return "";
}
public static JSONObject generateHookDataJson(MethodHookParam param,MethodApiType type) throws JSONException
{
JSONObject hookData= new JSONObject();
hookData.put("class",param.method.getDeclaringClass().getName());
hookData.put("method", param.method.getName());
hookData.put("timestamp", System.currentTimeMillis());
hookData.put("type", type.toString());
return hookData;
}
public static JSONArray parseArgs(MethodHookParam param,JSONObject hookJson)
{
JSONArray args = new JSONArray();
for (Object object : (Object[]) param.args) {
try {
if(object!=null)
args.put(ParseGenerator.parse(object));
} catch (Exception e) {
Logger.logShell("args error: " + e.getMessage()+" "+hookJson.toString());
}
}
return args;
}
public static Object parseResults(MethodHookParam param,JSONObject hookJson)
{
try {
return ParseGenerator.parse(param.getResult());
} catch (Exception e) {
Logger.logShell("result error: " + e.getMessage()+" "+hookJson.toString());
return "";
}
}
public static Object parseThis(MethodHookParam param,JSONObject hookJson)
{
try {
return ParseGenerator.parse(param.thisObject);
} catch (Exception e) {
Logger.logShell("thisObject error: " + e.getMessage()+" "+hookJson.toString());
return "";
}
}
public static String parseRefelctionMethodName(MethodHookParam param,JSONObject hookJson) {
Method method = (Method) param.thisObject;
if(method!=null)
return method.getName();
else
return "";
}
public static String parseRefelctionClassName(MethodHookParam param,JSONObject hookJson) {
if(param.args[0]!=null)
return param.args[0].getClass().getName();
else
return "";
}
public static JSONArray parseRefelctionArgs(MethodHookParam param,JSONObject hookJson) {
JSONArray args = new JSONArray();
if((Object[]) param.args[1]!=null)
{
for (Object object : (Object[]) param.args[1]) {
try {
if(object!=null)
args.put(ParseGenerator.parse(object));
} catch (Exception e) {
Logger.logShell("reflection args error: " + e.getMessage()+" "+hookJson.toString());
}
}
}
return args;
}
}