JS 有什么手段可以判断一个函数是不是原生代码吗?

2021-05-08 16:22:07 +08:00
 xieqiqiang00

比如 XMLHttpRequest,有没有什么手段可以知道这个东西有没有被人为重写?
网站找了不少方法都做不到
下面是我做的一些尝试,这些检测方法都能被绕过

{
    function isNative(api) {
        return /native code/.test(api.toString()) && typeof api !== 'undefined'
    }

    let test = function (input, fake) {
        console.log("------------------------")
        console.log("是否是伪造:", fake)
        console.log("toString:", input.toString())
        console.log("toString.toString:", input.toString)
        console.log("prototype 方法", input.hasOwnProperty("prototype"))
        console.log("toString.call","方法",Function.prototype.toString.call(input))
        console.log("网传最不靠谱方法:isNative", isNative(input))
    }
    test(XMLHttpRequest, false)
    {
        let XMLHttpRequest = function () {
            "[native code]"
        }
        XMLHttpRequest.toString = function () {
            return "function XMLHttpRequest() { [native code] }"
        }
        let toString = function () {
            return "function toString() { [native code] }"
        }
        toString.toString = toString
        XMLHttpRequest.toString.toString = toString
        Function.prototype.toString = toString
        delete XMLHttpRequest.prototype
        test(XMLHttpRequest, true)
        // XMLHttpRequest.prototype = undefined
        // test(XMLHttpRequest, true)
    }
}
5821 次点击
所在节点    JavaScript
80 条回复
3dwelcome
2021-05-08 17:50:16 +08:00
用 websocket+自定义协议就可以避免被简单抓包。

类似一个主流网络游戏的自定义加密通讯协议,绝对没那么容易破解。

或者学微信,自己造 HTTPS/SSL 轮子,也没那么容易被破解。直接用标准的 http/https 确实很不安全,客户端注入 JS,解开后就是明文了。
renmu123
2021-05-08 17:50:16 +08:00
如果可以直接改你的代码,你代码底裤都被看到了,那么你防止修改 xhr 又有什么用。
代码混淆再找找有什么好的加壳工具吧
xieqiqiang00
2021-05-08 17:52:52 +08:00
@chogath 代码保护这块我打算用 vm 编译成字节码,但如果运行环境事先被修改了一样会上钩
xieqiqiang00
2021-05-08 17:53:39 +08:00
@renmu123 不想被看到请求了什么接口,代码加密现在有 JS 预编译,够了
xieqiqiang00
2021-05-08 17:54:14 +08:00
@maichael 没有绝对的安全嘛,提高一下门槛
BoringTu
2021-05-08 18:00:30 +08:00
emmmm,我来给你个正确答案吧~ 思路其实很简单,给你个小 demo~

window.ABC = function() {
console.log('origin ABC');
};

window.tempABC = window.ABC;

window.ABC = function() {
window.tempABC.call(this, arguments);
console.log('new ABC');
}

有思路没~
我只是模拟了一下被人为覆盖浏览器内置函数的逻辑

那现在公布答案~

在 HTML head 标签里所有 script 标签的最前面加上一个 script,里面:
window.originXMLHttpRequest = window.XMLHttpRequest;

然后在你想判断的时候:
originXMLHttpRequest === XMLHttpRequest
其实换句话说,window.originXMLHttpRequest 这东西就是浏览器原装内置函数,因为人为覆盖的逻辑肯定在后面执行的

是不是豁然开朗?(手动抠鼻
xieqiqiang00
2021-05-08 18:03:04 +08:00
@BoringTu 在这之前执行了替换的话不就 GG
BoringTu
2021-05-08 18:04:55 +08:00
@xieqiqiang00 都在所有脚本执行之前了,你这疑问不成立啊
ch2
2021-05-08 18:06:19 +08:00
你首先得保证你的检测代码不能被修改
des
2021-05-08 18:07:02 +08:00
既然你是 electron 程序,建议在 c++层面动手脚
js 层面加东西不说白费功夫,但起码能力有限
carlclone
2021-05-08 18:07:16 +08:00
运行的时候下断点, 在 console 输入函数名, 会输出一个可以点击跳转的函数定义位置
luofeii
2021-05-08 18:12:25 +08:00
建立沙箱比如 iframe,需要用到哪个函数直接从 iframe 生成的 window 对象调用就可以
xieqiqiang00
2021-05-08 18:20:11 +08:00
要是这么简单就能解决我的顾虑,我就不提这个问题了
xieqiqiang00
2021-05-08 18:20:30 +08:00
@BoringTu 要是这么简单就能解决我的顾虑,我就不提这个问题了
xieqiqiang00
2021-05-08 18:21:45 +08:00
@ch2 检测部分打算预编译成字节码,就当他是改不了的
xieqiqiang00
2021-05-08 18:21:58 +08:00
@des 魔改 electron 哈哈哈
xieqiqiang00
2021-05-08 18:22:29 +08:00
@carlclone 这个是可以改的,vm 就可以
BoringTu
2021-05-08 18:29:08 +08:00
楼上的各位都想啥呢。。
也就 @luofeii 这位大佬的靠谱点,跟我的逻辑很像,但你的逻辑是行不通的,因为并不是同一个对象

let iframe = document.createElement('iframe');
iframe.id = 'iframe';
document.body.append(iframe);
iframe = document.getElementById('iframe');
iframe.contentWindow.XMLHttpRequest === window.XMLHttpRequest // false
BoringTu
2021-05-08 18:30:34 +08:00
@xieqiqiang00 ? 哪里有问题可以提出来,不提出来咋给你解决。。
BoringTu
2021-05-08 18:32:38 +08:00
只有一种情况是我说的方案失效的,就是如果是说 electron 是在加载 html 之前就覆盖了内置函数

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/775677

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX