> 技术文档 > JS-RPC实战区块链交易信息获取_jsrpc

JS-RPC实战区块链交易信息获取_jsrpc


JS-RPC实战区块链交易信息获取

在上一篇文章中用老实的js逆向获取了这个区块链网站中的x-apikey加密参数,总体来说还算简单,但是扣代码,补函数,改调用还是很烦的,现在我们用JS-RPC来简化这个复杂的步骤
这是JS-RPC的Github链接
自行下载合适的可执行文件并打开,你会看到如下窗口

JS-RPC实战区块链交易信息获取_jsrpc

看到这个窗口就证明你以及准备好了服务环境,现在要开始对网页注入代码链接上这个服务端了
找到加密函数的位置(上一篇文章中以及说过)然后手动在控制台调用一下这个函数,ok成功获取数据,但是我们在实际获取的时候是不可能让页面停留在断点处的,所以我们尝试将这个函数提升为全局函数

window.abc=h.A.getApiKey

但当我们尝试调用abc函数获取x-apikey参数的时候会发现报错了
JS-RPC实战区块链交易信息获取_jsrpc
不要慌张,此时开始从调用堆栈中一步一步找
JS-RPC实战区块链交易信息获取_jsrpc
在控制台中输入第二个函数的调用代码,可以看到控制台正常输出这个结果
JS-RPC实战区块链交易信息获取_jsrpc
开始尝试将这个函数改为全局函数

window.vv=v

尝试调用这个函数
JS-RPC实战区块链交易信息获取_jsrpc
成功运行,此时就不再需要断点了,将说有断点删除,开始向控制台中输入链接之前开启的JS-RPC服务端的代码(在该项目的Github里面有,考虑到网络问题将这些代码附上)

var rpc_client_id, Hlclient = function (wsURL) { this.wsURL = wsURL; this.handlers = { _execjs: function (resolve, param) { var res = eval(param) if (!res) { resolve(\"没有返回值\") } else { resolve(res) } } }; this.socket = undefined; if (!wsURL) { throw new Error(\'wsURL can not be empty!!\') } this.connect()}Hlclient.prototype.connect = function () { if (this.wsURL.indexOf(\"clientId=\") === -1 && rpc_client_id) { this.wsURL += \"&clientId=\" + rpc_client_id } console.log(\'begin of connect to wsURL: \' + this.wsURL); var _this = this; try { this.socket = new WebSocket(this.wsURL); this.socket.onmessage = function (e) { _this.handlerRequest(e.data) } } catch (e) { console.log(\"connection failed,reconnect after 10s\"); setTimeout(function () { _this.connect() }, 10000) } this.socket.onclose = function () { console.log(\'rpc已关闭\'); setTimeout(function () { _this.connect() }, 10000) } this.socket.addEventListener(\'open\', (event) => { console.log(\"rpc连接成功\"); }); this.socket.addEventListener(\'error\', (event) => { console.error(\'rpc连接出错,请检查是否打开服务端:\', event.error); })};Hlclient.prototype.send = function (msg) { this.socket.send(msg)}Hlclient.prototype.regAction = function (func_name, func) { if (typeof func_name !== \'string\') { throw new Error(\"an func_name must be string\"); } if (typeof func !== \'function\') { throw new Error(\"must be function\"); } console.log(\"register func_name: \" + func_name); this.handlers[func_name] = func; return true}Hlclient.prototype.handlerRequest = function (requestJson) { var _this = this; try { var result = JSON.parse(requestJson) } catch (error) { console.log(\"请求信息解析错误\", requestJson); return } if (result[\"registerId\"]) { rpc_client_id = result[\'registerId\'] return } if (!result[\'action\'] || !result[\"message_id\"]) { console.warn(\'没有方法或者消息id,不处理\'); return } var action = result[\"action\"], message_id = result[\"message_id\"] var theHandler = this.handlers[action]; if (!theHandler) { this.sendResult(action, message_id, \'action没找到\'); return } try { if (!result[\"param\"]) { theHandler(function (response) { _this.sendResult(action, message_id, response); }) return } var param = result[\"param\"] try { param = JSON.parse(param) } catch (e) { } theHandler(function (response) { _this.sendResult(action, message_id, response); }, param) } catch (e) { console.log(\"error: \" + e); _this.sendResult(action, message_id, e); }}Hlclient.prototype.sendResult = function (action, message_id, e) { if (typeof e === \'object\' && e !== null) { try { e = JSON.stringify(e) } catch (v) { console.log(v)//不是json无需操作 } } this.send(JSON.stringify({\"action\": action, \"message_id\": message_id, \"response_data\": e}));}

连接自己的服务端,并向JsRPC中注册这个函数,控制台再次输入

var nx = new Hlclient(\"ws://127.0.0.1:12080/ws?group=nx\");nx.regAction(\"vv\", function (resolve,param) { var res = vv(JSON.parse(param.replace(/\'/g, \'\"\'))); console.log(res) resolve(res);})

看到这个返回就代表以及成功了
JS-RPC实战区块链交易信息获取_jsrpc
JS-RPC实战区块链交易信息获取_jsrpc
现在就可以直接获取加密参数了,有了这个工具就相当于开启了一个web服务可以让我们通过访问本机的web端来获取网页中js代码的执行结果(想要了解更多的话可以访问项目的Github地址查看)

其实就是向本机的12080端口发送get请求,在url中带上group组名,action注册的函数名,param传参就可以了

import requests,jsonpage = {\"offset\": str(1),\"limit\": \"1\"}#offset是开始的条位置,limit是一次返回的数据数量限制params = { \"group\": \"nx\", \"action\": \"vv\", \"param\" : str(page)}print(params)response = requests.get(\"http://127.0.0.1:12080/go\", params=params)headers_=json.loads(response.json()[\"data\"])[\"headers\"]#获取返回的headersresponse = requests.get(\"https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict\",params=page,headers=headers_,)print(response.json())

运行这段代码就会得到想要的结果啦
JS-RPC实战区块链交易信息获取_jsrpc
和普通的扣代码比起来这个方法似乎没有多大差别,都挺繁琐的,但是当遇到目标环境的加密很复杂,还有复杂的对象操作的时候,这个方法就可以算得上so easy了,方法多种多样关键的是要有灵活的头脑去处理,方法选择不存在绝对最优解,只有基于当前条件的相对高效路径
下一篇将会讲解通过WebSocket 来实现这个JSRPC