package com.hermes.xhshook; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; public class Hook implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("com.xingin.xhs")) return; XposedBridge.log("[XHSHook] Loaded into XHS!"); try { Class clz = XposedHelpers.findClass("okhttp3.Request$Builder", lpparam.classLoader); XposedHelpers.findAndHookMethod(clz, "build", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { try { Object url = XposedHelpers.getObjectField(param.thisObject, "url"); String urlStr = url != null ? url.toString() : "null"; // Only log edith.xiaohongshu.com (the signed API endpoint) if (!urlStr.contains("edith.xiaohongshu.com")) return; Object method = XposedHelpers.getObjectField(param.thisObject, "method"); String methodStr = method != null ? method.toString() : "GET"; // headers field is Headers.Builder — call build() to get actual headers Object headersBuilder = XposedHelpers.getObjectField(param.thisObject, "headers"); String headersStr = "null"; if (headersBuilder != null) { Object headers = XposedHelpers.callMethod(headersBuilder, "build"); headersStr = headers != null ? headers.toString() : "null"; } XposedBridge.log("[XHSHook] " + methodStr + " " + urlStr); XposedBridge.log("[XHSHook] Headers:\n" + headersStr); } catch (Throwable t) { XposedBridge.log("[XHSHook] Error in hook: " + t.getMessage()); } } }); XposedBridge.log("[XHSHook] OkHttp Request.Builder.build() hooked!"); } catch (Throwable t) { XposedBridge.log("[XHSHook] Failed to hook OkHttp: " + t.getMessage()); XposedBridge.log(t); } } }