亚马逊以图实物接口 Frida hook代码

parent 81881461
Java.perform(function () {
// 定位 Credentials 类(确保类名正确)
const Credentials = Java.use("com.amazon.vsearch.lens.api.config.Credentials");
// 明确指定要 Hook 的构造函数:4个参数(String, String, String, boolean)
Credentials.$init.overload(
"java.lang.String", // username
"java.lang.String", // secret
"java.lang.String", // application
"boolean" // removeCredentialsGate(实验开关)
).implementation = function (username, secret, application, removeCredentialsGate) {
console.log("\n=== Credentials 4参数构造函数被调用 ===");
console.log("1. username: " + username);
console.log("2. secret: " + secret);
console.log("3. application: " + application);
console.log("4. removeCredentialsGate(实验开关): " + removeCredentialsGate);
console.log("\n调用栈:");
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
// 调用原构造函数,不影响正常逻辑
this.$init(username, secret, application, removeCredentialsGate);
};
});
\ No newline at end of file
Java.perform(function () {
const A9VSAuthenticator = Java.use("com.amazon.vsearch.lens.network.internal.A9VSAuthenticator");
const Map = Java.use("java.util.Map");
const Arrays = Java.use("java.util.Arrays");
// 1. Hook 构造函数
A9VSAuthenticator.$init.implementation = function (credentials) {
console.log("\n[+] A9VSAuthenticator 构造函数被调用");
try {
console.log(" Credentials 详情:");
console.log(" username: " + credentials.getUsername());
console.log(" secret: " + credentials.getSecret());
console.log(" application: " + credentials.getApplication());
console.log(" disableAuthTokenGeneration: " + credentials.getDisableAuthTokenGeneration());
} catch (e) {
console.log(" 获取 Credentials 失败: " + e.message);
}
this.$init(credentials);
};
// 2. Hook generateAuthParams(通过反射获取所有键,确保完整性)
A9VSAuthenticator.generateAuthParams.overload().implementation = function () {
console.log("\n[+] 调用 generateAuthParams()");
const authParams = this.generateAuthParams();
const castedMap = Java.cast(authParams, Map);
console.log(" 返回的完整认证参数:");
try {
// 反射调用 keySet() 获取所有键,转换为数组
const keySet = castedMap.keySet();
const keyArray = Java.array('java.lang.Object', keySet.toArray()); // 转换为 JS 可遍历的数组
// 遍历所有键
for (let i = 0; i < keyArray.length; i++) {
const key = keyArray[i];
const value = castedMap.get(key);
console.log(` ${key}: ${value}`);
}
} catch (e) {
console.log(" 遍历参数失败,使用已知参数 fallback:");
// 已知参数 fallback(确保至少能获取核心参数)
const knownKeys = ["application", "username", "ts", "authtoken"];
knownKeys.forEach(key => {
if (castedMap.containsKey(key)) {
console.log(` ${key}: ${castedMap.get(key)}`);
}
});
}
return authParams;
};
// 3. Hook generateAuthToken
A9VSAuthenticator.generateAuthToken.overload("java.lang.String").implementation = function (timestamp) {
console.log("\n[+] 调用 generateAuthToken(timestamp)");
console.log(" 入参 timestamp: " + timestamp);
const authToken = this.generateAuthToken(timestamp);
console.log(" 返回的 authtoken: " + authToken);
return authToken;
};
});
\ No newline at end of file
Java.perform(function () {
try {
// 直接 Hook OkHttp 请求发送,读取完整表单
const OkHttpClient = Java.use("okhttp3.OkHttpClient");
OkHttpClient.newCall.implementation = function (request) {
const url = request.url().toString();
if (url.includes("/vsearch/2.0")) {
const body = request.body();
if (body && body.contentType().toString().includes("multipart/form-data")) {
try {
// 读取完整请求体
const buffer = Java.use("okio.Buffer").$new();
body.writeTo(buffer);
const formData = buffer.readUtf8();
// 提取 query_metadata(不做格式校验)
const qPos = formData.indexOf('name="query_metadata"');
if (qPos !== -1) {
// 从字段名位置向后取 2000 字符(覆盖大多数情况)
const qValue = formData.substring(qPos + 20, qPos + 2020).split("\r\n--")[0];
console.log("\nquery_metadata 值:\n" + decodeURIComponent(qValue.trim()));
}
// 提取 authtoken(不做格式校验)
const aPos = formData.indexOf('name="authtoken"');
if (aPos !== -1) {
// 从字段名位置向后取 500 字符
const aValue = formData.substring(aPos + 18, aPos + 518).split("\r\n--")[0];
console.log("\nauthtoken 值:\n" + decodeURIComponent(aValue.trim()));
}
} catch (e) {
console.log("提取失败: " + e.message);
}
}
}
return this.newCall(request);
};
console.log("脚本已启动,触发操作后将打印参数");
} catch (e) {
console.log("Hook 失败: " + e.message);
}
});
\ No newline at end of file
Java.perform(function () {
const Adapter = Java.use("com.amazon.vsearch.lens.core.internal.search.image.VisualSearchNetworkCallToFutureAdapter");
Adapter.$init.implementation = function (networkManager, sessionHolder, additionalBodyParams, storage, z) {
console.log("\n=== Adapter 构造函数传入的 additionalBodyParams ===");
try {
const gson = Java.use("com.google.gson.Gson").$new();
console.log(gson.toJson(additionalBodyParams));
} catch (e) {
console.log(additionalBodyParams.toString());
}
return this.$init(networkManager, sessionHolder, additionalBodyParams, storage, z);
};
});
\ No newline at end of file
Java.perform(function () {
// 定位目标类:com.amazon.vsearch.lens.network.internal.NetworkManagerImpl
const NetworkManagerImpl = Java.use("com.amazon.vsearch.lens.network.internal.NetworkManagerImpl");
// Hook createParamsMapForNetworkCall 方法
NetworkManagerImpl.createParamsMapForNetworkCall.implementation = function (additionalBodyParams) {
console.log("\n=== 检测到 createParamsMapForNetworkCall 被调用 ===");
// 1. 打印调用者信息(调用栈)
console.log("调用栈:");
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
// 2. 打印传入的参数 additionalBodyParams(业务参数)
console.log("\n传入的 additionalBodyParams 参数:");
try {
// 将 Map 转换为 JSON 字符串打印(便于阅读)
const gson = Java.use("com.google.gson.Gson").$new();
const paramsJson = gson.toJson(additionalBodyParams);
console.log(paramsJson);
} catch (e) {
// 若没有 Gson,直接打印 Map 内容
console.log(additionalBodyParams.toString());
}
// 3. 调用原方法,获取返回值
const result = this.createParamsMapForNetworkCall(additionalBodyParams);
// 4. 打印返回值(组装后的完整请求参数,含 query_metadata)
console.log("\n返回的完整请求参数:");
try {
const gson = Java.use("com.google.gson.Gson").$new();
const resultJson = gson.toJson(result);
console.log(resultJson);
} catch (e) {
console.log(result.toString());
}
// 返回原方法的结果,不影响正常流程
return result;
};
console.log("✅ 已成功 Hook createParamsMapForNetworkCall 方法");
});
\ No newline at end of file
Java.perform(function () {
try {
// 1. Hook 系统 CookieManager 的 setCookie 方法(指定重载版本:url + cookie 字符串)
const AndroidCookieManager = Java.use("android.webkit.CookieManager");
// 明确选择两个 String 参数的重载:setCookie(String url, String value)
AndroidCookieManager.setCookie.overload('java.lang.String', 'java.lang.String').implementation = function (url, value) {
// 检查 Cookie 中是否包含 session-id(amznSessionId 的源头)
if (value && value.includes("session-id=")) {
console.log("\n=== 捕获 session-id Cookie ===");
console.log("服务器 URL: " + url);
console.log("Cookie 内容: " + value);
// 解析 URL 中的参数
if (url) {
try {
const urlObj = new URL(url);
const params = urlObj.searchParams;
if (params.size > 0) {
console.log("URL 参数:");
params.forEach((v, k) => console.log(` ${k}=${v}`));
} else {
console.log("URL 参数: 无");
}
} catch (e) {
console.log("URL 解析失败(非标准格式): " + url);
}
}
}
// 调用原方法,不影响正常逻辑
return this.setCookie(url, value);
};
// 2. Hook CookieBridge 的 put 方法(处理服务器响应的 Set-Cookie 头)
const CookieBridge = Java.use("com.amazon.mShop.net.CookieBridge");
CookieBridge.put.implementation = function (uri, responseHeaders) {
const url = uri.toString();
// 提取响应头中的 Set-Cookie 字段(可能包含 session-id)
const setCookieHeaders = responseHeaders.get("Set-Cookie") || responseHeaders.get("set-cookie");
if (setCookieHeaders && setCookieHeaders.length > 0) {
for (const cookie of setCookieHeaders) {
if (cookie.includes("session-id=")) {
console.log("\n=== 服务器响应中包含 session-id ===");
console.log("请求的 URL: " + url);
break;
}
}
}
// 调用原方法
this.put(uri, responseHeaders);
};
console.log("✅ 已成功 Hook,等待 session-id 下发...");
} catch (e) {
console.log("❌ Hook 失败: " + e.message);
}
});
\ No newline at end of file
Java.perform(function () {
try {
const TrackingInfo = Java.use("com.amazon.vsearch.lens.api.config.TrackingInfo");
// 遍历所有构造方法(重点关注传入9个参数的构造方法)
TrackingInfo.$init.overloads.forEach((ctor, index) => {
ctor.implementation = function () {
// 只关注9个参数的构造方法(已确认的核心构造)
if (arguments.length === 9) {
console.log("\n=== 检测到 9 参数的 TrackingInfo 构造函数被调用 ===");
console.log("调用栈(谁在创建 TrackingInfo):");
// 打印完整调用栈
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}
return this.$init.apply(this, arguments);
};
});
console.log("✅ 已 Hook TrackingInfo 构造函数(跟踪调用者)");
} catch (e) {
console.log("❌ Hook 失败: " + e.message);
}
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment