使用js hook获取netflix元数据
背景
netflix获取视频元数据使用的一个get请求
https://www.netflix.com/nq/website/memberapi/v033d5825/metadata?movieid=<id>&imageFormat=jpg&withSize=true&materialize=true&_=<timestamp>
eg.
https://www.netflix.com/nq/website/memberapi/v033d5825/metadata?movieid=80994709&imageFormat=jpg&withSize=true&materialize=true&_=1694665109875
它的响应是这样的
这个不好直接使用get请求,因为它需要登录的cookies,那实在太麻烦,所以我打算使用js hook的技术去截取响应数据,思路大概是这样的,我定位到渲染进程接受响应数据的位置,然后观察是否使用了什么原生api处理响应数据,然后使用hook技术,筛选出我需要的数据
定位发送请求位置
首先是定位到关键的地方,结合这次分析的切入点是一个网络请求,所以我使用XHR断点,这个可以定位到发送请求的地方
如上图,通过筛选出url中的metadata来打上XHR条件断点
如上图,断下后,我们发现发送请求时i对象使用了send方法,这个i对象是由上面的自调用匿名函数获取的,这个函数返回了对象t,而这个t对象是XHLHttpRequest
定位获取响应数据位置
我们使用chatgpt搜索js XMLHttpRequest 发送请求并获得请求结果
它的意思是通过监听XMLHttpRequest的onreadystatechange字段的函数获取响应数据,可是我在上面的代码中没有看到监听onreadystatechange方法的操作
只有onload、onerror、ontimeout等方法,其它的都好理解,只有onload的不知道,我们再用chatgpt搜索一下这个字段
发现onload也可以获取响应内容,接下来我们的目标是分析赋值给onload的函数是哪个
我们在上面XMLHttpRequest open url的时候打上条件断点,当url包含metadata
的时候,断住程序。断下后单步至i.onload赋值出,观察o函数的返回值,最后跳转到目标函数
观察o函数的返回值
跳转到目标函数
我单步这个函数的时候,居然发现这个请求的返回类型是json,所以它不用调用任何原生函数就直接获取返回的数据对象,可恶,我的算盘打空了。
编写hook代码
但是我灵机一动,我可以hook XMLHttpRequest 啊,chatgpt搜索网页中有一个请求为XMLHttpRequest,我如何hook它,以获取响应内容
chatgpt太给力了啊,最后我对代码稍加润色。
// 保存原始的 XMLHttpRequest 构造函数
const RealXMLHttpRequest = window.XMLHttpRequest;
// 创建一个代理构造函数
function ProxyXMLHttpRequest() {
const xhr = new RealXMLHttpRequest();
// 添加一个事件监听器,以便在请求完成时获取响应内容
xhr.addEventListener("load", function() {
if(xhr.status == 200 && xhr.responseType == "json"){
// 响应内容可以通过 xhr.responseText 获取
const response = xhr.response;
if(response && response.video && response.video.title && response.video.type){
console.log("拦截到的响应内容:", response);
}
}
});
return xhr;
}
// 用代理构造函数替换原始的 XMLHttpRequest 构造函数
window.XMLHttpRequest = ProxyXMLHttpRequest;
拦截效果: