js逆向之远程调用(rpc)免去抠代码补环境

1.项目地址

js逆向之远程调用(rpc)免去抠代码补环境

https://github.com/jxhczhl/JsRpc

2.使用

2.1 下载可执行文件

在Windows中下载Windows_amd64.exe文件,双击执行

2.2 浏览器对应的网页执行

https://github.com/jxhczhl/JsRpc/blob/main/resouces/JsEnv_Dev.js

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}));
}

2.3 链接通信

// 注入环境后连接通信
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz");
// 可选  
//var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=zzz&clientId=hliang/"+new Date().getTime())

执行之后浏览器 提示rpc链接成功

2.4 与python 交互

"""
@Time    : 2025/3/20 11:28
@Author  : white.tie
@File    : demo.py
@Desc    : jSrpc与浏览器交互
"""
import requests

js_code = """
(function(){
    console.log("test")
    return "执行成功"
})()
"""

url = "http://localhost:12080/execjs"
data = {
    "group": "zzz",
    "code": js_code
}
res = requests.post(url, data=data)
print(res.text)

执行完成之后可以看到浏览器打印test

### JavaScript逆向工程中全运行环境的通用代码实现 在进行JavaScript逆向工程时,许多加密代码依赖于特定的浏览器环境(如`window`、`document`、`navigator`等全局对象)以及相关的API(如`DOM`操作、`XMLHttpRequest`等)。为了在非浏览器环境下执行这些代码,必须对这些环境依赖进行全。以下是基于Node.js环境的通用代码实现,用于模拟浏览器环境全相关依赖[^1]。 #### 1. 全全局对象 以下代码展示了如何通过Node.js中的`jsdom`库来创建一个虚拟的浏览器环境,并全常见的全局对象(如`window`和`document`)。 ```javascript const { JSDOM } = require("jsdom"); // 创建虚拟的浏览器环境 const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, { url: "https://example.org/", }); // 全全局对象 global.window = dom.window; global.document = dom.window.document; global.navigator = { userAgent: "Node.js", // 模拟 navigator.userAgent }; global.XMLHttpRequest = dom.window.XMLHttpRequest; // 确保其他依赖也能正常工作 global.Image = class Image {}; ``` #### 2. 全事件循环机制 在Node.js环境中,需要模拟浏览器的事件循环机制。可以通过`setImmediate`或`process.nextTick`来实现简单的事件队列管理。对于更复杂的场景,可以使用`puppeteer`或其他工具来模拟完整的浏览器行为[^3]。 ```javascript function simulateEventLoop(callback) { setImmediate(() => { console.log("Simulating event loop..."); callback(); }); } simulateEventLoop(() => { console.log("Event loop tick completed."); }); ``` #### 3. 全 XMLHttpRequest 请求 如果目标代码依赖于`XMLHttpRequest`进行网络请求,可以在Node.js环境中使用`axios`或`node-fetch`来替代原生的`XMLHttpRequest`实现[^4]。 ```javascript const axios = require("axios"); global.XMLHttpRequest = class XMLHttpRequest { open(method, url) { this.method = method; this.url = url; } send(data) { axios[this.method.toLowerCase()](this.url, data).then((response) => { this.onreadystatechange(); this.responseText = response.data; }); } onreadystatechange() { if (this.onreadystatechange && typeof this.onreadystatechange === "function") { this.onreadystatechange(); } } }; ``` #### 4. 调试与日志记录 在逆向工程过程中,调试是不可或缺的一部分。可以通过添加日志记录或断点来跟踪代码执行过程[^2]。 ```javascript function BinaryExpression(path) { console.log("当前节点:", path.node); debugger; // 在浏览器开发者工具中暂停 } ``` 以上代码片段展示了如何在Node.js环境JavaScript代码所需的运行环境。通过结合`jsdom`、`axios`以及其他工具,可以有效模拟浏览器环境并解决依赖问题。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值