精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何優(yōu)雅地 Hack 用戶的代碼

開(kāi)發(fā) 前端
本文介紹一些一種在 JS 層面 hack 用戶代碼的方式。

前言:做基礎(chǔ)技術(shù)的時(shí)候,會(huì)經(jīng)常碰到一個(gè)問(wèn)題就是如何讓自己提供的代碼對(duì)用戶少侵入,無(wú)感。比如我提供了一個(gè) SDK 收集 Node.js 進(jìn)程的 HTTP 請(qǐng)求耗時(shí),最簡(jiǎn)單的方式就是給用戶提供一個(gè) request 方法,然后讓用戶統(tǒng)一調(diào)用,這樣我就可以在 request 里拿到這些數(shù)據(jù)。但是這種方式很多時(shí)候并不方便,這時(shí)候我們就需要去 hack Node.js 的 HTTP 模塊或者給 Node.js 提 PR。在操作系統(tǒng)層面,有提供很多技術(shù)解決這種問(wèn)題,比如 ebpf、uprobe、kprobe。但是應(yīng)用層無(wú)法使用這種技術(shù)解決我們的問(wèn)題,因?yàn)椴僮飨到y(tǒng)的這些技術(shù)針對(duì)的是底層的函數(shù),比如我想知道一個(gè) JS 函數(shù)的耗時(shí),只能在 V8 層面或者 JS 層面去解決,V8 這方面似乎也沒(méi)有提供很好能力,所以目前我們更多是考慮純 JS 或者 Node.js 內(nèi)核層面。本文介紹一些一種在 JS 層面 hack 用戶代碼的方式。

在 Node.js 中,統(tǒng)計(jì) JS 函數(shù)的耗時(shí)通常的做法是 cpu profile,但是這種方式只能拿到一段時(shí)間的耗時(shí),如果我想實(shí)時(shí)收集耗時(shí)數(shù)據(jù),cpu profile 就有點(diǎn)難搞,最直接的就是定時(shí)收集 cpu profile 數(shù)據(jù),然后我們手動(dòng)去解析 profile 數(shù)據(jù)然后上報(bào)。除了這種方式外,本文介紹另外一種方式。就是通過(guò) hack JS 代碼的方式。假如有以下一個(gè)函數(shù)。

function compute() {
// do something
}

如果我們想統(tǒng)計(jì)這種函數(shù)的執(zhí)行耗時(shí),最自然的方式就是在函數(shù)的開(kāi)始和結(jié)束的地方插入一些代碼。但是我們不希望這種事情讓用戶手動(dòng)去做,而是使用一種更優(yōu)雅的方式。那就是通過(guò)分析源碼,拿到 AST,然后重寫 AST。我們看看怎么做。

const acorn = require('acorn');
const escodegen = require('escodegen');
const b = require('ast-types').builders;
const walk = require("acorn-walk");
const fs = require('fs');

// 分析源碼,拿到 AST
const ast = acorn.parse(fs.readFileSync('./test.js', 'utf-8'), {
ecmaVersion: 'latest',
});

function inject(node) {
// 在函數(shù)前后插入代碼
const entryNode = b.variableDeclaration('const', [b.variableDeclarator(b.identifier('start'), b.callExpression(
b.identifier('(() => { return Date.now(); })'), [],
))]);
const exitNode = b.returnStatement(b.callExpression(
b.identifier('((start) => {console.log(Date.now() - start);})'), [
b.identifier('start')
],
));

if (node.body.body) {
node.body.body.unshift(entryNode);
node.body.body.push(exitNode);
}
}

// 遍歷 AST,修改 AST
walk.simple(ast, {
ArrowFunctionExpression: inject,
ArrowFunctionDeclaration: inject,
FunctionDeclaration: inject,
FunctionExpression: inject
});

// 根據(jù)修改的 AST 重新生成代碼
const newCode = escodegen.generate(ast);

fs.writeFileSync('test.js', newCode)

執(zhí)行上面的代碼后拿到如下結(jié)果。

function compute() {
const start = (() => { return Date.now(); })();
return ((start) => {console.log(Date.now() - start);})(start);
}

這樣我們就可以拿到每個(gè)函數(shù)的耗時(shí)數(shù)據(jù)了。但是這種方式是靜態(tài)分析源碼,落地起來(lái)需要用戶主動(dòng)操作,并不是那么友好。那么基于這個(gè)基礎(chǔ)我們利用 V8 調(diào)試協(xié)議中的 Debugger Domain 實(shí)現(xiàn)動(dòng)態(tài)重寫,這種方式還能重寫 Node.js 內(nèi)部的 JS 代碼。首先改一下測(cè)試代碼。

function compute() {
// do something
}

setInterval(compute, 1000)

然后再看改寫代碼的邏輯。

const { Session } = require('inspector');
const acorn = require('acorn');
const escodegen = require('escodegen');
const b = require('ast-types').builders;
const walk = require("acorn-walk");
const session = new Session();
session.connect();

require('./test_ast');
// 監(jiān)聽(tīng) JS 代碼解析事件,拿到所有的 JS
session.on('Debugger.scriptParsed', (message) => {
// 只處理這個(gè)文件
if (message.params.url.indexOf('test_ast') === -1) {
return;
}
// 拿到源碼
session.post('Debugger.getScriptSource', {scriptId: message.params.scriptId}, (err, ret) => {
const ast = acorn.parse(ret.scriptSource, {
ecmaVersion: 'latest',
});
function inject(node) {
const entry = b.variableDeclaration('const', [b.variableDeclarator(b.identifier('start'), b.callExpression(
b.identifier('(() => { return Date.now(); })'), [],
))]);
const exit = b.returnStatement(b.callExpression(
b.identifier('((start) => {console.log(Date.now() - start);})'), [
b.identifier('start')
],
));

if (node.body.body) {
node.body.body.unshift(entry);
node.body.body.push(exit);
}
}
walk.simple(ast, {
ArrowFunctionExpression: inject,
ArrowFunctionDeclaration: inject,
FunctionDeclaration: inject,
FunctionExpression: inject
});
const newCode = escodegen.generate(ast);
// 分析完,重寫 AST后生成新的代碼,并重寫
session.post('Debugger.setScriptSource', {
scriptId: message.params.scriptId,
scriptSource: newCode,
dryRun: false
});
})
});

session.post('Debugger.enable', () => {});

正常來(lái)說(shuō),setInterval 執(zhí)行的函數(shù)沒(méi)有東西輸出,但是我們發(fā)現(xiàn)會(huì)不斷輸出 0,也就是耗時(shí),因?yàn)檫@里使用毫秒級(jí)的統(tǒng)計(jì),所以是 0,不過(guò)我們不需要關(guān)注這個(gè)。這樣我們就完成了 hack 用戶的代碼,而對(duì)用戶來(lái)說(shuō)是無(wú)感的,唯一需要做的事情就是引入我們提供的一個(gè) SDK。不過(guò)這種方式的難點(diǎn)在重寫代碼的邏輯,風(fēng)險(xiǎn)也比較大,但是如果我們解決了這個(gè)問(wèn)題后,我們就可以隨便 hack 用戶的代碼,做我們想做的事情,當(dāng)然,是正事。

責(zé)任編輯:姜華 來(lái)源: 編程雜技
相關(guān)推薦

2025-06-12 09:42:08

2025-10-09 11:00:00

前端代碼JavaScript

2023-06-06 08:51:06

2021-03-24 10:20:50

Fonts前端代碼

2024-11-13 16:37:00

Java線程池

2021-05-12 22:07:43

并發(fā)編排任務(wù)

2020-03-26 11:04:00

Linux命令光標(biāo)

2022-05-13 21:20:23

組件庫(kù)樣式選擇器

2021-01-18 13:17:04

鴻蒙HarmonyOSAPP

2019-04-11 18:25:29

Android Q權(quán)限位置

2024-04-24 12:34:08

Spring事務(wù)編程

2021-01-28 14:53:19

PHP編碼開(kāi)發(fā)

2020-07-09 10:15:55

空值Bug語(yǔ)言

2021-09-08 08:34:37

Go 文檔Goland

2020-12-08 08:08:51

Java接口數(shù)據(jù)

2020-10-22 10:15:33

優(yōu)化Windows電腦

2018-08-20 10:40:09

Redis位圖操作

2023-02-13 14:37:13

開(kāi)發(fā)web瀏覽器

2020-04-03 13:45:16

刪除Linux垃圾文件

2024-06-24 14:19:48

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲成人精品在线观看| 国产成人综合视频| 深夜成人在线观看| 337p日本欧洲亚洲大胆张筱雨 | www插插插无码视频网站| 午夜视频福利在线| 九九在线精品视频| 97在线视频一区| 自拍偷拍你懂的| 成人高潮视频| 欧美日韩一区二区在线视频| 男人的天堂avav| 黄色国产在线| 丁香激情综合五月| 国产精品美女免费| 日本五十熟hd丰满| 久久国产综合| 日韩www在线| 免费不卡av网站| 欧美色网在线| 精品福利在线观看| 免费看污污视频| 国产露出视频在线观看| 国产白丝精品91爽爽久久| 国产精品免费一区豆花| 日韩手机在线观看| 欧美精选在线| 播播国产欧美激情| 调教驯服丰满美艳麻麻在线视频| 国产精品xxx在线观看| 555夜色666亚洲国产免| 欧美在线观看视频网站| 女人让男人操自己视频在线观看| 亚洲精品欧美激情| 亚洲午夜激情| 高h视频在线| 久久久国产精华| 精品久久久久久中文字幕动漫| 亚洲怡红院av| 日韩黄色小视频| 日韩av电影手机在线观看| 国产精品成人av久久| 中文无码久久精品| 久久精品国产一区二区电影| 黄色片在线观看免费| 亚洲深夜福利在线观看| 亚洲精品在线免费观看视频| 在线免费黄色小视频| 996久久国产精品线观看| 欧美三区在线观看| 91网址在线播放| www成人在线视频| 欧美日韩在线一区| 日本久久久精品视频| 国内激情视频在线观看| 亚洲国产日产av| 日本精品久久久久久久久久| 黑人玩欧美人三根一起进| 亚洲精品成人精品456| 天天干天天色天天爽| av在线看片| 一区二区三区在线观看国产| 黄色特一级视频| 欧美hdxxxxx| 性久久久久久久| 欧美精品99久久| 92国产精品| 欧美视频日韩视频| 亚洲一级片av| 91成人午夜| 亚洲国产天堂久久综合| 一卡二卡三卡四卡| 欧美日韩在线观看视频小说| 中文字幕日韩av电影| 中文字幕在线有码| 亚洲三级影院| 国产精品免费久久久久影院| 夜夜狠狠擅视频| 国产精品456露脸| 久久精品国产综合精品| 国产黄色在线| 亚洲精品乱码久久久久久久久 | 免费看电影在线| 五月天婷婷综合| 99久久激情视频| 欧美日韩卡一| 亚洲精品一区二区三区影院| 久操视频免费看| 一区二区三区网站| 国产91精品青草社区| 做爰视频毛片视频| 成熟亚洲日本毛茸茸凸凹| 久久一区二区三区av| 在线毛片网站| 午夜成人免费视频| 超碰超碰在线观看| 噜噜噜狠狠夜夜躁精品仙踪林| 一区二区三区 在线观看视| √天堂中文官网8在线| 在线亚洲自拍| 91欧美视频网站| 婷婷色在线视频| 国产精品萝li| 每日在线更新av| 国产日韩欧美中文在线| 亚洲欧美日韩成人| 免费毛片在线播放免费| 免费视频最近日韩| 久久国产精品免费一区| 黄色网址免费在线观看| 一本一道久久a久久精品综合蜜臀| 一区二区三区四区毛片| 国产精品片aa在线观看| 欧美极品美女视频网站在线观看免费 | 国产91|九色| 亚洲免费视频网| 国产精品成人免费精品自在线观看 | 成人在线观看黄色| 亚洲国产aⅴ天堂久久| 亚洲娇小娇小娇小| 国产成人精品一区二区免费看京| 欧美国产日产韩国视频| 在线观看免费中文字幕| 久久九九全国免费| 欧美 日韩 亚洲 一区| 国产午夜久久av| 中文国产成人精品| 中文字幕在线播| 97超碰欧美中文字幕| 日韩黄色短视频| 九九九九九九精品任你躁| 最近日韩中文字幕中文| 久久青青草原亚洲av无码麻豆| 成人综合婷婷国产精品久久| 强伦女教师2:伦理在线观看| 国产黄色精品| 色噜噜国产精品视频一区二区| 在线免费一区二区| 久久久无码精品亚洲日韩按摩| 青青草综合在线| 在线精品国产亚洲| 欧美国产日韩在线| 国产小视频一区| 亚洲一二三四在线| 人妻体内射精一区二区三区| 国内精品福利| 国产欧美在线一区二区| 97人人爽人人澡人人精品| 欧美精品一区二区三| 日本中文字幕免费观看| 成人毛片老司机大片| 福利视频一区二区三区四区| 国产厕拍一区| 97色伦亚洲国产| 日韩亚洲视频在线观看| 日韩欧美中文在线| 微拍福利一区二区| 青青草国产精品97视觉盛宴| 亚洲视频欧美在线| 成人在线分类| 久久久久久久久久久国产| 蜜桃久久一区二区三区| 午夜精品一区在线观看| 国产ts丝袜人妖系列视频| 久久久水蜜桃av免费网站| 欧美婷婷久久| 高清不卡一区| 欧美国产精品va在线观看| 人妻精品一区一区三区蜜桃91| 婷婷综合在线观看| 制服 丝袜 综合 日韩 欧美| 美女视频一区二区三区| 女女百合国产免费网站| 精品国产导航| 国产精品美女午夜av| 亚洲七七久久综合桃花剧情介绍| 精品福利一二区| 日韩电影在线观看一区二区| 中日韩av电影| 色综合久久久无码中文字幕波多| av成人天堂| 亚洲国产午夜伦理片大全在线观看网站 | 色综合久久88色综合天天免费| 日本不卡一区视频| 粉嫩久久99精品久久久久久夜 | 久久国产在线视频| 91色婷婷久久久久合中文| 亚洲最大成人在线观看| 国产精品久久| 奇米影视首页 狠狠色丁香婷婷久久综合 | 超碰在线97av| 国产精品伦一区二区| 欧美激情免费视频| eeuss影院在线观看| 日韩精品在线一区二区| 伊人久久中文字幕| 亚洲综合视频在线| 国产精品酒店视频| 99久久精品免费观看| 亚洲va在线va天堂va偷拍| 夜夜嗨av一区二区三区网站四季av| 先锋影音亚洲资源| 麻豆成人入口| 亚洲伊人成综合成人网| 日本免费一区二区三区四区| 欧美大片网站在线观看| 川上优的av在线一区二区| 精品第一国产综合精品aⅴ| 亚洲午夜在线播放| 欧美日韩亚洲系列| 久久久久黄色片| 国产精品蜜臀在线观看| 亚洲第一香蕉网| 国产成a人亚洲| 中文字幕资源在线观看| 久久免费高清| 精品中文字幕av| 在线免费高清一区二区三区| 中文字幕成人一区| 欧美色图一区| 日本精品二区| 校花撩起jk露出白色内裤国产精品| 亚洲综合精品伊人久久| 黑人一区二区三区| 国产成人在线一区二区| 午夜激情电影在线播放| 久久久久国产一区二区三区| 黄色网在线免费观看| 最近中文字幕2019免费| 男女污污视频在线观看| 日韩精品免费电影| 污污的视频网站在线观看| 日韩你懂的在线播放| 国产精品系列视频| 欧美精品自拍偷拍动漫精品| 久草视频在线免费| 欧美制服丝袜第一页| 波多野结衣日韩| 色婷婷久久99综合精品jk白丝 | 欧美精品色综合| 中文字幕精品一区二| 欧美三区免费完整视频在线观看| 国产精品久久久久久久久夜色| 欧美视频在线免费| 天天干天天色综合| 日本高清不卡一区| 中日韩黄色大片| 午夜精品视频一区| 久久一区二区三区视频| 都市激情亚洲色图| 97久久久久久久| 色综合咪咪久久| 国产99免费视频| 欧美日韩国产首页| 国产精品女人久久久| 日韩一级片在线观看| 亚洲第一视频在线| 亚洲精品国产精品国产自| 色在线免费视频| 最近2019年手机中文字幕| 欧美激情二区| 色在人av网站天堂精品| 九色porny视频在线观看| 日本电影亚洲天堂| 久久久久久久性潮| 91精品国产一区二区三区动漫| 澳门成人av| 日本公妇乱淫免费视频一区三区| 精品视频日韩| 免费的av在线| 亚洲国产导航| 少妇黄色一级片| 国内精品在线播放| 精品视频站长推荐| 国产偷v国产偷v亚洲高清 | 亚洲mv在线观看| 波多野结衣高清视频| 91精品一区二区三区在线观看| 亚洲精品久久久久avwww潮水| 亚洲电影免费观看| 啊v在线视频| 久久999免费视频| 在线看的毛片| 91久久综合亚洲鲁鲁五月天| 国产伦精品一区二区三区在线播放 | 一区二区成人在线| 亚洲欧美另类在线视频| 欧美老年两性高潮| 午夜视频免费在线| 久久艳片www.17c.com | 好看的av在线不卡观看| 久久久噜噜噜www成人网| 精东粉嫩av免费一区二区三区| 91亚洲一线产区二线产区| 国产欧美日韩麻豆91| 久草资源在线视频| 欧美日韩精品欧美日韩精品| 性生交大片免费看女人按摩| 亚洲三级 欧美三级| 国产在线xxx| 国产又爽又黄的激情精品视频| 女一区二区三区| 青青草影院在线观看| 久久裸体视频| 成熟妇人a片免费看网站| 国产精品乱人伦一区二区| www.日本精品| 日韩一级黄色大片| 9色在线视频| 日韩免费在线观看视频| 99这里只有精品视频| 在线免费观看成人网| 久久久噜噜噜| 中文字幕免费高清视频| 亚洲美女精品一区| 亚洲一区二区色| 国产亚洲欧洲在线| 91久久国产综合久久91猫猫| 国产乱码精品一区二区三区卡 | 亚洲第一区中文字幕| 一级片视频免费观看| 粉嫩aⅴ一区二区三区四区五区| 精品人妻中文无码av在线| 午夜精品爽啪视频| 亚洲成人黄色片| 少妇高潮久久77777| 91另类视频| 日本精品一区二区三区不卡无字幕| 亚洲精品人人| 国产ts在线观看| 一区二区三区在线观看国产| 91美女精品网站| 中文字幕亚洲无线码在线一区| 日韩av首页| 日韩欧美视频一区二区三区四区| 亚洲一区二区三区高清不卡| 美女露出粉嫩尿囗让男人桶| 亚洲精品欧美在线| 精品国产区一区二| 久久99精品国产99久久6尤物| 激情综合婷婷| 免费观看国产视频在线| 国产在线不卡一区| 国产色无码精品视频国产| 欧美日韩亚洲国产综合| 风间由美一区| 国产精品一区久久久| 成人精品视频| xx欧美撒尿嘘撒尿xx| 中文字幕一区日韩精品欧美| 一道本在线视频| 久久视频在线观看免费| 伊人久久大香线蕉综合影院首页| 艳色歌舞团一区二区三区| 韩国成人在线视频| 欧美日韩三级在线观看| 日韩欧美一级特黄在线播放| 成人直播在线| 国产98在线|日韩| 亚洲激情国产| 中文字幕一区二区三区人妻| 欧美自拍偷拍一区| 黄网站免费在线观看| 999热视频| 亚洲永久网站| 一二三四在线观看视频| 欧美日韩高清一区二区| a视频在线观看免费| 精品国产第一页| 久久综合中文| 在线日韩国产网站| 精品对白一区国产伦| 亚洲精品动漫| 色呦呦网站入口| av一区二区三区四区| aaa在线视频| 欧美成人性色生活仑片| 国产伦精品一区二区三区在线播放 | 欧美狂野另类xxxxoooo| 直接在线观看的三级网址| 九九九久久久| 久久国产精品72免费观看| 久久免费黄色网址| 亚洲另类图片色| 国产精品一站二站| 久久视频这里有精品| 国产精品国产自产拍高清av王其| 国产成人免费看一级大黄| 日本亚洲欧洲色α| 亚洲精品国产首次亮相| 给我免费观看片在线电影的| 欧美亚洲综合久久| 免费在线观看av电影| 日韩精品最新在线观看| 粉嫩高潮美女一区二区三区 | 欧美亚洲精品日韩| 国产老女人精品毛片久久| 麻豆成人免费视频| 欧美成人剧情片在线观看| 精品视频99|