javascript - 以编程方式过滤 V8 堆快照中不需要的字符串(无需开发工具 GUI)
问题描述
我有一个 Node 应用程序,它将 JavaScript 源代码作为字符串发送到在 Node 的 VM api 中执行它的工作线程。我只拍摄工作线程堆的快照。这是为了检测 JavaScript 源代码中的任何字符串分配。但是,我得到了很多晦涩的注释,因为字符串会使堆膨胀。
我最初怀疑这是由于 Node VM 如何将代码作为字符串执行,所以我评论了我的代码的 VM 部分,但我仍然得到这些不需要的字符串。也许这是由于使用require()
and import
?
我的代码如下。同样,app.js
只需将源代码作为字符串传递给我的工作线程,worker.mjs
. worker.mjs
将在 VM 沙箱中运行传递的字符串数据,然后将其堆快照写入文件。
// App.js file
const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
// JavaScript source code passed as String.
let workerData = `
var nop = unescape("%u9090%u9090");
while (nop.length <= 0x100000/2) {nop += nop;}`;
const worker = new Worker('./worker.mjs', { workerData });
worker.once('message', (filename) => {
console.log(`worker heapdump: ${filename}`);
});
// Tell the worker to create a heapdump.
worker.postMessage('heapdump');
};
// worker.mjs
import { workerData, parentPort, threadId } from 'worker_threads';
import { createContext, runInContext } from 'vm';
import { writeHeapSnapshot, getHeapSnapshot } from 'v8';
parentPort.once('message', (message) => {
if (message === 'heapdump') {
const sandbox = {};
const strict = '"use strict";'
createContext(sandbox);
runInContext(strict+workerData, sandbox, {timeout: 10000 });
parentPort.postMessage(writeHeapSnapshot());
}
});
我的最终目标是收集仅从字符串源代码中创建的所有字符串和串联字符串workerData
。在这个例子中,nop
变量的值。
但如图所示,连接字符串中也有很多绒毛数据。
"encodingOps.ucs2.byteLength"@29509
"encodingOps.utf16le.byteLength"@29531
"encodingOps.latin1.byteLength"@29555
"encodingOps.ascii.byteLength"@29579
"encodingOps.base64.byteLength"@29603
"encodingOps.hex.byteLength"@29627
"module.exports.getModuleFromWrap"@39059
...
...
"internal/modules/package_json_reader.js"@10997
"internal/modules/esm/translators.js"@11001
"internal/modules/esm/transform_source.js"@11011
"internal/modules/esm/resolve.js"@11021
"internal/modules/esm/module_map.js"@11025
"internal/modules/esm/module_job.js"@11029
"internal/modules/esm/loader.js"@11033
"internal/modules/esm/get_source.js"@11043
"internal/modules/esm/get_format.js"
vm 模块支持在 V8 虚拟机上下文中编译和运行代码。vm 模块不是安全机制。不要使用它来运行不受信任的代码。https://nodejs.org/api/vm.html
我了解 Node VM 在其自己的上下文中执行代码。是否可以检索 VM 的上下文 id,然后过滤堆快照以查找存在于该特定上下文中的字符串?在这种情况下,我只想要nop
变量。我希望有某种方法可以在不使用chrome dev-tools
.
解决方案
也许这是由于使用
require()
andimport
?
基本上是的。你想要所有的字符串,你得到所有的字符串。JavaScript 使用大量字符串。(具体的导入机制无关紧要。如果您执行任何代码,您将在堆快照中看到它的字符串/等。)
是否可以检索 VM 的上下文 id,然后过滤堆快照以查找存在于该特定上下文中的字符串?
不,堆对象和上下文之间没有关联。
推荐阅读
- ssh - ssh 卡在 debug1:已发送 SSH2_MSG_KEX_DH_GEX_REQUEST(2048<3072<8192)
- django - 获取 Django API 调用以使用简单的 json 进行响应
- ffmpeg - ffmpeg 创建不需要的临时文件
- android - 将向上/向下滑动事件从 ViewPager2 传播到父 BottomSheet
- vb.net - Crystal Report 根据 IF 条件添加年份或月份
- python - 尝试在同一台 apache2 服务器上托管 2 个 django 网站时遇到问题
- escaping - 雪花中的文件格式问题 - Tilda(字段分隔符),两个双引号
- json - ARM 数据库错误:无法对嵌套资源执行请求的操作。未找到父资源
- google-chrome - 使用 chrome 扩展收听通知
- postgresql - 在 sqlalchemy 中手动设置 id 时的竞争条件