copilot激活器是如何制作的

296 阅读2分钟

首先从最好搞的 vscode 开始

  1. 用vscode自己攻克自己 code ~/.vscode/extensions/github.copilot-1.176.0
  2. 打开文件夹中的 dist/extensions.js 使用 prettier 美化一下代码

image.png 3. 创建一个 .vscode/launch.json ,然后打个断点,就可以 f5 开始调试了

{
    "version": "0.2.0",
    "configurations": [
            {
                    "args": [
                            "--extensionDevelopmentPath=${workspaceFolder}"
                    ],
                    "name": "Launch Extension",
                    "outFiles": [
                            "${workspaceFolder}/out/**/*.js"
                    ],
                    "request": "launch",
                    "type": "extensionHost"
            }
    ]
}
  1. 一番摸索发现插件使用的 tls.connect 方法校验了证书,所以就算我信任了 charles 的证书也不能抓包,把它 hook 掉
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
    const tls = require("tls");
    const _connect = tls.connect;
    function wrappedConnect(port, host, options, secureConnectListener) {
    	if (typeof port === "object") {
    		options = port;
    		secureConnectListener = host;
    	} else if (typeof host === "object") {
    		options = host;
    		options.port = port;
    		secureConnectListener = options;
    	} else {
    		options = options || {};
    		options.port = port;
    		options.host = host;
    	}
    	console.log("xxx", options);
    	options.rejectUnauthorized = false; // 验证不通过也别报错
    	return _connect(options, secureConnectListener);
    }
    tls.connect = wrappedConnect;
    
  2. 后面就顺利抓到 chat 和 代码补全的请求啦
  3. 抓到请求后就是拦截和转发了, 试试拦截https的request方法
    [https, http].forEach((module) => {
    	module.request = (function (fn) {
    		console.log(`request: ${url.host}${url.pathname}`);
    		return function (url, opts) {
    			if (
    				["api.github.com", "api.githubcopilot.com", "copilot-proxy.githubusercontent.com"].indexOf(
    					url.host
    				) >= 0
    			) {
    				url.host = "xxx.micosoft.icu";
    				if (opts) {
    					opts.headers = {
    						...opts.headers,
    						host: url.host,
    						authorization: 'token ' + process.env.GITHUB_TOKEN,
    					};
    				}
    			}
    			return fn.apply(this, arguments);
    		};
    	})(module.request);
    });
    
  4. 结果不行啊,只拦截到一些无关紧要的请求,又是一番断点分析后发现他是用的 http2 发起的请求 😭,http2 拦截起来太麻烦了,不如不让他用 http2 吧,于是在 hook tls.connect的代码中加上
    if (options.ALPNProtocols) {
    	options.ALPNProtocols = options.ALPNProtocols.filter((protocol) => protocol !== "h2");
    }
    
  5. 至此请求拦截的工作就基本完成了,后面就是写代码来找到插件并 hook 插件就行啦。

总结:当然这只是其中我认为比较好的一种修改插件的方式哈,相比直接去修改 extensions.js 中间的代码,这种 hook 的方式维护起来更方便

然后是 RStudio,Vim, HBuilder, Qt 之流

  1. 下载安装好插件后,发现跟 vscode 大差不差,只是入口文件从 extensions.js 变成了 agent.js,有了vscode的经验, 用同样的方式一把梭,没一会就搞定了。

最后是 JetBrains 和 Visual Studio

  1. 一开始看见 copilot-agent-win.exe 这玩意我也是懵逼的,但是。。。诶,这图标不是 nodejs 的图标吗? image.png
  2. 于是我开始搜索将 nodejs 代码打包为 exe 的方法,就找到了它 www.npmjs.com/package/pkg
  3. 再进一步一看,这不js源码不和 copilot-agent-win.exe 在一起的吗

image.png 4. 既然这么良心,就按照 hook RStudio 的方式把 dist 目录的源码修改后,重新用pkg打包成 copilot-agent-win.exe 就行啦

附上激活器链接

注意一定要使用我的特种邀请码 0003b7 不仅可以得7天会员,还可以激活chat哦

下载地址: copilot激活器