js逆向-浏览器调试

前言

强者从不纠缠,直接买单离场,沉默成本,不参与重大抉择。

不必把自己当成弱者,不必纠结付出,不必直面,

没有矫情,没有内耗,没有抱怨,一切都承受得起。

2025年暴富、少哭、少病、少灾、多乐、多财、多福。

⚠️声明:本文所涉及的爬虫技术及代码仅用于学习、交流与技术研究目的,禁止用于任何商业用途或违反相关法律法规的行为。若因不当使用造成法律责任,概与作者无关。请尊重目标网站的robots.txt协议及相关服务条款,共同维护良好的网络环境。

1.浏览器开发者工具

1.1元素面板

功能:用于查看和编辑页面的 HTML 结构和 CSS 样式。

用途

  • 检查和修改页面的 DOM 结构。
  • 查看和实时修改 CSS 样式。
  • 实时预览样式的修改效果(如颜色、字体、布局)。
  • 动态添加、删除和修改元素(如标签、类、属性等)。

常见操作

  • 右键点击某个元素,选择 "Inspect"(检查)以打开该元素在 DOM 树中的位置。
  • 修改元素的 CSS 样式(如字体大小、颜色、位置等)。

image-20250227183853329

1.2网络面板

功能:用于监控和分析网页加载过程中所有的网络请求。

用途

  • 查看和分析 HTTP 请求和响应。
  • 跟踪资源加载时间(例如,图片、CSS 文件、JavaScript 脚本、API 请求等)。
  • 调试 AJAX 请求和响应,查看请求头、响应头、状态码等信息。
  • 查看网页加载性能,识别瓶颈(如网络延迟、资源大小等)。

常见操作

  • 查看各个请求的详细信息,包括 URL、状态码、请求方法、请求时间、响应时间等。
  • 查看或模拟请求的参数、响应体。
  • 过滤显示特定类型的请求(如只显示 XHR 请求、图片请求等)。

image-20250227183915183

1.3控制台面板

  • 功能:用于显示 JavaScript 输出、日志、警告、错误信息,以及与 JavaScript 进行交互。
  • 用途:
    • 查看 console.log 输出的信息。
    • 捕捉 JavaScript 错误和警告信息。
    • 输入和执行 JavaScript 代码。
    • 在调试过程中进行交互式调试。
  • 常见操作:
    • 打印变量值、函数输出,快速调试代码。
    • 运行 JavaScript 代码片段并查看结果。
    • 捕获并跟踪 JavaScript 异常。

image-20250227183930488

1.4源代码面板

功能:用于查看和调试页面加载的 JavaScript 代码。

用途

  • 查看和编辑页面中的 JavaScript 文件(包括内联脚本和外部文件)。
  • 设置断点、调试代码、查看调用堆栈。
  • 查看当前加载的所有脚本文件。

常见操作

  • 设置断点调试 JavaScript。
  • 单步调试代码(逐行执行、跳过某些函数等)。
  • 查看变量、调用堆栈、作用域链。
  • 修改代码并重新加载页面进行调试。

image-20250227183948242

1.5应用面板

功能:用于查看网页的存储情况,如 Cookies、LocalStorage、SessionStorage、IndexedDB 和缓存数据等。

用途

  • 查看和管理页面使用的本地存储(如 Cookies、localStorage、sessionStorage 等)。
  • 检查页面缓存资源(如 Service Worker、缓存存储等)。
  • 管理与页面交互的后端存储(如 IndexedDB)。

常见操作

  • 查看、修改和删除存储的数据。
  • 管理浏览器缓存、Cookies 和本地存储。
  • 检查和调试 Service Worker。

image-20250227184012157

2.断点

2.1简介

断点(Breakpoint)是调试程序时用于暂停程序执行的标记。当程序运行到断点位置时,执行会暂停,开发者可以查看当前的代码状态、变量值、调用栈等信息,逐步调试代码的行为。断点是调试过程中非常重要的工具,它帮助开发者定位问题、分析程序执行流程。

断点的作用

  1. 暂停执行:断点使得程序在某个特定的代码行处停止,允许开发者查看该行代码执行时的状态。
  2. 逐步调试:断点允许开发者单步执行代码,逐行查看每一步的执行结果。
  3. 查看变量状态:当程序暂停时,开发者可以查看当前作用域中的变量值,检查其是否符合预期。
  4. 检查调用栈:通过断点暂停时,可以查看当前代码调用的堆栈信息,了解程序执行到当前断点的路径。
  5. 修改变量:在调试过程中,开发者可以实时修改变量的值,测试不同的执行路径或条件。

断点的类型

  1. 普通断点:程序在断点位置暂停,开发者可以查看变量、调用堆栈等信息。
  2. 条件断点:当断点设置有特定条件时,只有在条件成立时程序才会在该行暂停。例如,只有当某个变量的值大于特定值时,断点才会触发。
  3. 日志断点(Logpoint):不暂停程序执行,只是在断点处输出日志信息。这对于调试时查看变量值而不需要中断执行非常有用。
  4. 函数断点:在特定的函数入口处设置断点,程序一旦进入该函数就会暂停。
  5. 异常断点:当抛出特定类型的异常时自动暂停,帮助开发者捕捉并调试异常。

2.2断点方法

2.2.1DOM事件断点定位加密

DOM事件断点用于在浏览器的开发者工具中调试和定位与DOM元素相关的事件处理函数。它能帮助开发者在特定的DOM事件(如 click, keypress, submit 等)发生时暂停代码执行,从而让你可以检查事件的触发情况、事件对象、相关的DOM元素等。

DOM事件断点通常用于以下场景:

  • 当你想要调试某个特定的DOM事件(如 click, change, focus 等)时,暂停并查看相关信息。
  • 当你不确定某个事件如何被触发,或者多个事件处理程序对同一个元素产生了影响时。
  • 当你想要分析某个DOM元素交互背后的执行过程,确保事件处理程序的行为符合预期。

DOM断点

image-20250227190018301

然后自己确定需要打断点的事件

image-20250227190913908

2.2.2XHR断点定位加密

XHR 断点(XMLHttpRequest 断点)是调试网页应用程序中的 AJAX 请求(即通过 JavaScript 发送的 HTTP 请求)的一种调试工具。它允许开发者暂停代码执行,查看网络请求的发送、响应的接收过程、请求头和响应内容等信息。这对于调试与服务器交互的部分,尤其是处理异步请求和动态加载数据的场景非常有用。

XHR 断点允许你在浏览器的开发者工具中设置断点,以捕捉 XMLHttpRequestFetch 发出的请求。当发送的请求被触发时,代码会暂停,并允许开发者查看该请求的详情,包括请求的 URL、方法、响应数据等内容。

XHR断点

找到对应的请求,这里以登录请求为例

https://oauth.d.cn/auth/login?display=web&name=peng&pwd=3394f79537cedef69e6ea8815ec36eb04903942b7d4b0eeee047131198f20586b916351714ad6511b6942d40a0cc59793aa1dc6343c993cef1aecdff4471fe0182e112a94446d2e562cef5a791674601dc09a978e8709d3d10fa590a3a8036a7110c21e2ae42d7ac0af6bfca4a5e7ddfc2eb136b240d2cccaaaf4c1a60964bd6&to=https%3A%2F%2Fwww.d.cn%2F&reqId=osapeoitmklxz65qk98zu0zpmhe3wir7&geetest_challenge=5c831e3934a825101987fb62ca07f418&geetest_validate=d24c31dfb3baba02a9db3a98fb0577eb&geetest_seccode=d24c31dfb3baba02a9db3a98fb0577eb%7Cjordan

image-20250227190520190

XHR/提取断点配置需要断点的请求,配置合适的路径即可

/auth/login

image-20250227190726776

发送请求之前会进入断点

image-20250227190631543

2.2.3网站加载时间轴

1.DNS 查询:浏览器通过 DNS 服务器将域名解析为 IP 地址。此步骤确保浏览器能够找到目标服务器。
2.TCP 握手:浏览器与目标服务器建立 TCP 连接,完成三次握手,确保双方能够进行数据通信。
3.TLS 握手(HTTPS):如果网站使用 HTTPS,浏览器与服务器进行安全的 TLS 握手,以加密数据传输。
4.发送 HTTP 请求:建立连接后,浏览器发起 HTTP 请求,获取服务器上的网页内容(如 HTML、CSS、JS 等资源)。
5.服务器响应:服务器接收到请求后,生成响应并返回给浏览器,包含 HTML、CSS、JavaScript、图片等资源。
6.解析 HTML 和构建 DOM 树:浏览器解析 HTML 文件,生成 DOM(文档对象模型)树,表示页面的结构和内容。
7.解析 CSS 和构建 CSSOM 树:同时,浏览器解析 CSS 文件,构建 CSSOM(CSS 对象模型)树,描述页面的样式。
8.执行 JavaScript:浏览器执行页面中的 JavaScript,可能会操作 DOM 或 CSSOM,从而影响页面的渲染。
9.页面渲染:浏览器将 DOM 和 CSSOM 树结合,生成渲染树。然后计算布局(确定元素位置和大小)并绘制页面内容。
10.页面加载完成:页面完全渲染,用户可以看到并与页面交互。
加载Hmtl - 加载JS - 运行JS初始化 - 用户触发某个事件 - 调用某段JS - 加密函数 - 给服务器发信息(XHR-SEND) - 接收到服务器数据 - 解密函数(如果数据加密的话) - 刷新网页渲染

3.方法栈

栈是一种先进后出的特殊线性表结构

方法栈(也称为 调用栈栈帧)是一个存储函数调用和执行顺序的数据结构。在程序运行过程中,每当一个函数被调用时,程序会将该函数的信息(如参数、局部变量等)压入栈中;当函数执行完成后,其信息会被弹出栈外。方法栈用于跟踪函数调用的顺序和程序的执行状态。

代码


function cc(a, b) {
    debugger
    console.log(a + b)
    console.log('调用的cc函数')
}


function bb(a, b){
    debugger
    console.log(a + b)
    cc()
    console.log('调用的bb函数')
}

function aa(a, b) {
    debugger
    bb(a, b)
    console.log('调用的aa函数')
}

aa(1, 2)

image-20250227191440761

4.debugger原理

4.1代码

定时器中会每100ms执行debugger,所以打开浏览器开发者工具会一直进入断点。

这算是一种反爬措施

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<h1 id="box"></h1>
<body>
<script>
    var ss = document.getElementById('box')
    function ff() {
        debugger;
    }
    setInterval(ff,100);
    ss.innerHTML = "大家好";
</script>
</body>
</html>

4.2浏览器过debugger

鼠标右键:一律不在此处暂停

image-20250227192721607

4.3编辑断点过debugger

编辑断点

  • 当定义器运行到这个debugger这个代码的时候,那么这个时候它为true,它肯定执行我们的debugger代码,那我们可以用浏览器的功能给他改成false
  • 鼠标右击行号,添加条件断点,添加一个不成立的条件
  • 写个1===0的先验条件,永远为假,就永远不会进入这个断点了。

添加条件断点

image-20250227193053099

1===0永远为false,所以不会执行

image-20250227193013901

4.4方法置空过debugger

无限debugger产生的原因是第七行代码ff这个函数造成的,所以我们可以重写这个函数,使无限debugger失效.在控制台中输入function ff(){}即可

一定要在debugger进入之前

在定时器执行前断点

image-20250227193442057

然后在控制台执行function ff(){}

image-20250227193511789

4.5替换文件过debugger

JS文件保存到本地修改,修改范围主要是将debugger相关的代码删除或者改写,可以使用文件替换方式

选择需要替换的文件,右键替换内容

image-20250227212506639

注释代码,ctrl+s保存

首次的时候需要允许浏览器访问本地文件,我这里没来得及截图

image-20250227212558795

4.6注入代码过debugger

地址:https://www.spolicy.com/

打开网站,发现一样会被卡在debugger

找到调用堆栈,向上分析

image-20250227213444328

我们分析一下这段代码

[c(0, "%!po", 1151) + u(839, 893, 0, 928, "YXL!") + "r"](a[h(0, 1436, 1302, "aD)^")](a[p(0, 1762, 1351, "7uI(", 1607)], a[p(0, 1075, 1396, "60A#", 1144)]))[u(886, 1223, 0, 1050, "60A#")](a[f(0, 0, "&@RT", 767)])

image-20250227213707681

这行代码的意思如下

constructor('debugger').call.action

image-20250227214041129

修改 JavaScript Function.prototype.constructor 方法来注入自定义的行为。它基于传入的参数 s 判断是否为 "debugger",如果是,它会打印出 s 的值并返回 null,否则调用原始的构造函数。

var _constructor = constructor;
Function.prototype.constructor = function(s) {
    
    if ( s== "debugger") {
        console.log(s);
        return null;
    }
    return _constructor(s);
}


// 保存原始的 Function.prototype.constructor
var _constructor = Function.prototype.constructor;
// 重写 constructor 方法
Function.prototype.constructor = function(s) {
    // 判断是否是 'debugger'
    if (s === "debugger") {
        console.log("Skipping debugger...");
        return null;  // 跳过 debugger 语句
    }
    return _constructor.apply(this, arguments);
};

这里好像报错了,记录一下

image-20250227215541882

📌 创作不易,感谢支持!
每一篇内容都凝聚了心血与热情,如果我的内容对您有帮助,欢迎请我喝杯咖啡☕,您的支持是我持续分享的最大动力!

wxzf
posted @ 2025-04-09 16:01  peng_boke  阅读(171)  评论(0)    收藏  举报