console.log("Script loaded successfully"); // hook_okhttp_client() if (Java.available) { hook_json() Java.perform(function () { try { var OkHttpClient = Java.use("okhttp3.OkHttpClient"); console.log(OkHttpClient.toString()) if (OkHttpClient != null){ hook_okhttp_client(); log_info("OkHttp detected in the app"); } } catch (e) { log_info("OkHttp not detected in the app"); } }); Java.perform(function () { log_info("start hook java.net.URL"); var URL = Java.use('java.net.URL'); URL.$init.overload('java.lang.String').implementation = function (spec) { // console.log("URL request:" + spec) log_info("URL request: " + spec) if (spec.includes("appsflyer")) { // console.log("URL request: " + spec); if (spec.includes("conversions")) { var stackTrace = Java.use('java.lang.Exception').$new().getStackTrace().toString(); // console.log(stackTrace); } } return this.$init(spec); }; }); } function printMethods(className) { log_info("start print methods.") var jclass = Java.use(className); var methods = jclass.class.getDeclaredMethods(); console.log("Printing methods of " + className + ":\n"); methods.forEach(function (method) { // console.log(method); log_info("The methods under the class" + className + " are: " + method); }); } function hook_okhttp_client() { if (Java.available) { Java.perform(function () { log_info("start hook_okhttp_client.") try { var OkHttpClient = Java.use("okhttp3.OkHttpClient"); // log_info("OkHttpClient: " + OkHttpClient.toString()); var class_name = OkHttpClient.$className; console.log(class_name+ "-------") printMethods(OkHttpClient.toString()); OkHttpClient.newCall.overload('okhttp3.Request').implementation = function (request) { var requestUrl = request.url(); if (requestUrl) { console.log("OkHttp Request URL: " + requestUrl.toString()); } else { console.log("OkHttp Request URL is not available"); } // console.log("OkHttp Request Headers: " + request.headers().toString()); // if (request.method() == "POST") { // console.log("OkHttp Request Body: " + request.body().contentType().toString()); // } var call = this.newCall(request); var response = call.execute(); console.log("OkHttp Response: " + response.body().string()); return call; }; } catch (e) { console.log("Error hooking OkHttp: " + e); } }); } } function hook_HttpURLConnection_stream() { console.log("start hook_HttpURLConnection_stream") if (Java.available) { Java.perform(function () { var HttpURLConnection = Java.use("java.net.HttpURLConnection"); HttpURLConnection.getOutputStream.implementation = function () { var outputStream = this.getOutputStream(); var OutputStreamWrapper = Java.use("java.io.OutputStream"); var newOutputStream = Java.registerClass({ name: "CustomOutputStream", superClass: OutputStreamWrapper, methods: { write: function (buffer, byteOffset, byteCount) { var data = Array.prototype.slice.call(buffer.slice(byteOffset, byteOffset + byteCount)); console.log("Request data: " + String.fromCharCode.apply(null, data)); outputStream.write(buffer, byteOffset, byteCount); } } }); return newOutputStream.$new(outputStream); }; HttpURLConnection.getInputStream.implementation = function () { var inputStream = this.getInputStream(); var InputStreamWrapper = Java.use("java.io.InputStream"); var newInputStream = Java.registerClass({ name: "CustomInputStream", superClass: InputStreamWrapper, methods: { read: function (buffer, byteOffset, byteCount) { var bytesRead = inputStream.read(buffer, byteOffset, byteCount); if (bytesRead != -1) { var data = Array.prototype.slice.call(buffer.slice(byteOffset, byteOffset + bytesRead)); console.log("Response data: " + String.fromCharCode.apply(null, data)); } return bytesRead; } } }); return newInputStream.$new(inputStream); }; }); } } function hook_retrofit() { Java.perform(function () { var retrofitBuilder = Java.use("retrofit2.Retrofit$Builder"); retrofitBuilder.build.implementation = function () { var retrofit = this.build(); var httpClient = retrofit.callFactory().clone(); httpClient.interceptors().add(new Java.use('okhttp3.Interceptor')({ intercept: function (chain) { console.log("HTTP Request -> " + chain.request().toString()) var response = chain.proceed(chain.request()); console.log("HTTP Response -> " + response.toString()); return response; } })) return retrofit.newBuilder() .callFactory(httpClient) .build(); } }); } function hook_json() { Java.perform(function () { var JSONObject = Java.use('org.json.JSONObject'); JSONObject.toString.overload().implementation = function () { var result = this.toString.call(this); // console.log("Serialized JSONObject: " + result); log_info("Serialized JSONObject: " + result) return result; }; }); } function log_info(messages) { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); const milliseconds = String(now.getMilliseconds()).padStart(3, '0'); const timestamp = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}:${milliseconds}`; console.log(`${timestamp} - ${messages}`); }