Skip to content

Commit 2919ecd

Browse files
authored
Merge pull request #8 from JSREI/dev
feat: 调试通了流程
2 parents f10c3db + 9aa885c commit 2919ecd

File tree

6 files changed

+71
-34
lines changed

6 files changed

+71
-34
lines changed

src/analyzer/request-analyzer.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,22 @@ class RequestAnalyzer {
5050
if (typeof unsafeWindow[param.value] !== "function") {
5151
// 如果都没有对应的全局函数存在的话,则直接判定为0分
5252
return 0;
53+
}
54+
let jsonpScore = 100;
5355

54-
let jsonpScore = 100;
55-
56-
// 判断参数中的jsonp参数特征,参数名
57-
const paramName = param.name.toLowerCase();
58-
if (paramName.indexOf("callback") !== -1) {
59-
jsonpScore += 10;
60-
}
61-
62-
// 参数值,寻找时间戳特征
63-
const timestampRegexp = /\b(\d{10}|\d{13})\b/g;
64-
const match = timestampRegexp.exec(param.value);
65-
if (match && this.isValidJsonpTimestamp(match)) {
66-
jsonpScore += 50;
67-
}
56+
// 判断参数中的jsonp参数特征,参数名
57+
const paramName = param.name.toLowerCase();
58+
if (paramName.indexOf("callback") !== -1) {
59+
jsonpScore += 10;
60+
}
6861

69-
return jsonpScore;
62+
// 参数值,寻找时间戳特征
63+
const match = new RegExp(/(\d{13}|\d{10})/).exec(param.value);
64+
if (match && this.isValidJsonpTimestamp(match[0])) {
65+
jsonpScore += 50;
7066
}
67+
68+
return jsonpScore;
7169
}
7270

7371
/**

src/debugger/debugger-manager.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,39 @@
1+
/**
2+
* 用来接收外部设置的断点,以及在请求时测试断点是否生效
3+
*/
14
class DebuggerManager {
2-
static testAll() {
35

6+
constructor() {
7+
// 用来存储所有的断点
8+
// Array<Debugger>
9+
this.debuggers = [];
410
}
11+
12+
/**
13+
* 执行测试所有断点,看看是否有条件命中啥的
14+
*
15+
* @param scriptContext {ScriptContext}
16+
*/
17+
testAll(scriptContext) {
18+
for (let jsonpDebugger of this.debuggers) {
19+
jsonpDebugger.test(scriptContext);
20+
}
21+
}
22+
23+
/**
24+
* 添加一个断点
25+
*
26+
* @param jsonpDebugger {Debugger}
27+
*/
28+
addDebugger(jsonpDebugger) {
29+
this.debuggers.push(jsonpDebugger);
30+
}
31+
532
}
633

34+
const debuggerManager = new DebuggerManager();
35+
736
module.exports = {
8-
DebuggerManager
37+
DebuggerManager,
38+
debuggerManager
939
}

src/debugger/debugger.js

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ const {getUnsafeWindow} = require("../utils/scope-util");
33
const {JsonpCallbackFunctionAnalyzer} = require("../analyzer/response-analyzer");
44

55
/**
6-
* 表示一个条件断点
6+
* 表示一个jsonp的条件断点
77
*/
88
class Debugger {
99

1010
/**
1111
* 创建一个断点
1212
*
13-
* @param urlPattern {String | RegExp} 用于与script类型的请求的URL做匹配进入断点
14-
* @param enableRequestDebugger {Boolean} 是否开启请求断点,开启请求断点会在请求发送之前进入断点
15-
* @param enableResponseDebugger {Boolean} 是否开启响应断点,开启响应断点会在响应处理之前进入断点
16-
* @param callbackFunctionParamName {String} 传递jsonp回调函数名字的参数,比如 "callback"
13+
* @param urlPattern {String | RegExp} 用于与script类型的请求的URL做匹配进入断点,只有这一个是必须指定的
14+
* @param enableRequestDebugger {Boolean} 是否开启请求断点,开启请求断点会在请求发送之前进入断点,不指定的话默认开启
15+
* @param enableResponseDebugger {Boolean} 是否开启响应断点,开启响应断点会在响应处理之前进入断点,不指定的话默认开启
16+
* @param callbackFunctionParamName {String} 传递jsonp回调函数名字的参数,比如 "callback",如果不指定的话会自动推测
1717
*/
18-
constructor(urlPattern, enableRequestDebugger, enableResponseDebugger, callbackFunctionParamName) {
18+
constructor(urlPattern, enableRequestDebugger = true, enableResponseDebugger = true, callbackFunctionParamName) {
1919
this.urlPattern = urlPattern;
2020
this.enableRequestDebugger = enableRequestDebugger;
2121
this.enableResponseDebugger = enableResponseDebugger;
@@ -31,7 +31,7 @@ class Debugger {
3131
test(scriptContext) {
3232

3333
// 首先URL要能够匹配得上
34-
if (!this.testUrlPattern(scriptContext.URL)) {
34+
if (!this.testUrlPattern(scriptContext.url)) {
3535
return;
3636
}
3737

@@ -44,16 +44,20 @@ class Debugger {
4444
if (this.enableResponseDebugger) {
4545

4646
// 如果没有指定jsonp函数的名字的话,则尝试自动抽取函数名字
47-
if (!this.callbackFunctionParamName) {
48-
this.callbackFunctionParamName = new JsonpCallbackFunctionAnalyzer().parseScriptContext(scriptContext);
47+
let jsonpCallbackFunctionName = this.callbackFunctionParamName;
48+
if (!jsonpCallbackFunctionName) {
49+
jsonpCallbackFunctionName = scriptContext.requestContext.getJsonpCallbackFuncName();
4950
}
50-
if (!this.callbackFunctionParamName) {
51+
if (!jsonpCallbackFunctionName) {
5152
// TODO 2023-8-22 01:00:27 完善错误提示信息
5253
throw new Error("must give me analyzer function param name, example: callback");
5354
}
5455

5556
// 为响应体中的回调函数增加hook
56-
new ObjectFunctionHook(getUnsafeWindow(), this.callbackFunctionParamName).addHook();
57+
new ObjectFunctionHook(getUnsafeWindow(), jsonpCallbackFunctionName).addHook(function () {
58+
// 这里是脚本的响应断点,已经拦截到响应,跟进去holder函数就行了
59+
debugger;
60+
});
5761
}
5862

5963
}

src/hook/object-function-hook.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ class ObjectFunctionHook {
1717

1818
/**
1919
*
20+
* @param hookCallbackFunction
2021
*/
21-
addHook() {
22+
addHook(hookCallbackFunction) {
2223

2324
// 要Hook的函数必须存在
2425
const functionHolder = this.object[this.functionName];
@@ -38,9 +39,8 @@ class ObjectFunctionHook {
3839
this.object[this.functionName] = function () {
3940

4041
// TODO 2023-8-21 22:15:09 在函数执行的时候尝试触发各种断点
42+
hookCallbackFunction.apply(this)
4143

42-
// 这里是脚本的响应断点,已经拦截到响应,跟进去holder函数就行了
43-
debugger;
4444
return functionHolder.apply(this, arguments);
4545
}
4646
// 设置标记位,防止重复Hook

src/hook/script-hook.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const Debugger = require("../debugger/debugger");
2-
const {DebuggerManager} = require("../debugger/debugger-manager");
2+
const {DebuggerManager, debuggerManager} = require("../debugger/debugger-manager");
33
const {JsonpCallbackFunctionAnalyzer} = require("../analyzer/response-analyzer");
44
const {ScriptContext} = require("../context/script/script-context");
55
const {RequestContext} = require("../context/request/request-context");
@@ -34,13 +34,12 @@ class ScriptHook {
3434
const requestContext = RequestContext.parseRequestContext(newSrc);
3535
const scriptContext = new ScriptContext(newSrc, requestContext, null);
3636

37-
debugger;
3837
const requestAnalyzer = new RequestAnalyzer();
3938
requestAnalyzer.analyze(requestContext);
4039

4140
// 在请求发送之前测试断点
4241

43-
DebuggerManager.testAll(scriptContext);
42+
debuggerManager.testAll(scriptContext);
4443

4544
// 这里认为script不会被复用,所以添加的hook在设置src的时候就会被删除掉,会有script复用的情况吗?
4645
delete _this.script.src;

src/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
const {DocumentHook} = require("./hook/document-hook");
22
const {getUnsafeWindow} = require("./utils/scope-util");
3+
const {debuggerManager} = require("./debugger/debugger-manager");
4+
const {Debugger} = require("./debugger/debugger");
35

46

57
(async () => {
68
// 增加可视化的配置
79

10+
// 增加一个测试断点
11+
const jsonpDebugger = new Debugger("http://localhost:10010/?jsonp_callback=jsonpCallback_1734635066");
12+
debuggerManager.addDebugger(jsonpDebugger)
13+
814
// 为document增加hook点
915
const unsafeWindow = getUnsafeWindow();
1016
new DocumentHook(unsafeWindow.document).addHook();

0 commit comments

Comments
 (0)