GitHub Copilot逆向分析:AI破解混淆JS代码实战
摘要
GitHub Copilot插件经webpack打包、Babel压缩、字符串编码及控制流扁平化处理的extension js代码并
GitHub Copilot插件经webpack打包、Babel压缩、字符串编码及控制流扁平化处理的extension.js代码并非不可解析。借助AI工具,可逐层拆解混淆逻辑,追踪用户输入采集、prompt构建与模型调用的完整路径,无需数周手动AST分析、模块切割与变量语义猜测。

Webpack模块分离与提取策略
第一步的目标是使代码可拆解。Copilot主文件(如extension.js)本质为大型IIFE,内含__webpack_modules__对象,键为数字ID,值为模块函数。人工正则匹配易出错,需借助AST解析精准提取。
使用@babel/parser将整个文件解析为AST树,再通过@babel/traverse遍历节点,定位VariableDeclarator中id为__webpack_modules__的声明,提取其init.properties数组——每个元素即独立模块。
需注意:模块value可能是ArrowFunctionExpression或FunctionExpression,需统一转换为函数体内容。若遇到ObjectExpression嵌套或SequenceExpression干扰,直接跳过该模块并记录警告,避免生成无效JS文件。
对每个模块执行generate(),输出独立xxx.js至./modules/目录——此时即可获得700多个原始模块文件,命名对应webpack ID(如123.js、456.js)。
模块间依赖关系重建
单个模块文件仍处于混淆状态:参数名简化为a,b,c,require替换为r,exports变为e,仅看模块难以识别引用关系。必须还原作用域绑定,才能沿依赖链定位关键路径。
方法一:检查每个模块顶层函数的params,若长度3且名字分别为a、b、c,基本可判定为function(module, exports, require)标准签名。
方法二更直接:在函数体内搜索CallExpression,若callee为Identifier且name为r或__webpack_require__,且第一个argument为NumericLiteral——提取该数字,即目标模块ID。
关键前提:必须先完成模块分离,否则require调用无法映射至真实文件路径。将所有模块ID与文件路径存入Map,然后批量重写每个模块中的r(123)为require('./123.js'),同时将a.exports = {...}展开为具名导出。
字符串解码与控制流还原
许多关键逻辑隐藏在_0x21a4=['x73x65x74','x63x6fx6f','x6bx69x65','x6cx6fx67']这类数组中,直接eval风险高且不可控。此时可引入AI:将整个字符串数组喂给本地小模型(如Phi-3-mini),提示词设为“请将下列十六进制Unicode字符串数组解码为明文,并推测每个字符串在JS上下文中最可能的用途(如set、cookie、log等)”。模型返回类似['set', 'coo', 'kie', 'log'] → 补全为['set', 'cookie', 'key', 'log']的结果。
控制流扁平化(如while(true){switch(t%8){case0:...break;case1:...break;}})无需硬拆,改用AST转换:识别WhileStatement内嵌SwitchStatement且test为true,将每个case分支提取为独立IfStatement,利用t的初始值与增量模拟执行顺序,最终生成线性if-else链。
此步操作简单,直接将处理后的AST传给@babel/generator输出即可。但注意——若某case内包含continue或break跳转至非相邻case,则需保留原switch结构,强制线性化反而会打乱逻辑。
利用AI定位核心Prompt构造逻辑
无需通读全部752个模块,AI可帮你聚焦。先将所有模块按文件大小排序,优先检查体积前10大的JS(通常主逻辑在其中),再用三步过滤关键文件:
第一步,在每个大模块中搜索正则/prompt|context|jaccard|snippet/i,提取包含匹配词的函数体;
第二步,对这些函数体做摘要并喂给AI:“请用一句话说明此段JS的核心功能,重点指出它是否参与构造发送给模型端的prompt,若是,请指出prompt由哪些变量拼接而成”;
第三步,验证AI结论:找到AI指出的变量(如userCode + clipboard + recentFiles),向上追溯其赋值来源,确认是否来自VS Code API调用(如vscode.env.clipboard.readText()、vscode.workspace.textDocuments)。
最终你将定位到类似buildPrompt.js的模块(实际ID可能是682.js),其内部明确组装三部分:当前编辑器内容、剪贴板文本、通过Jaccard相似度从最近打开文件中筛选的top3代码块——这正是Copilot“理解上下文”的技术落点。
来源:互联网
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。