toString

2025-04-19

驚くべきことだが、以下の等式はすべてtrueを返す。どうも__proto__チェインで遡ったオブジェクトのtoStringを共有しているようだ。

const p=document.write; writeLog1("[1] "+(p.toString===p.toString.toString)); writeLog1("[2] "+(p.toString.toString===p.toString.toString.toString)); writeLog1("[3] "+(p.toString.toString.toString===p.toString.toString.toString.toString)); writeLog1("[4] "+(p.toString===(()=>{}).toString));
Verified on Chrome, FireFox, Edge, Opeara, Safari v13.1.3, Android-Chrome, Android-FireFox, Android-Edge, Android-Opeara for [1] to [4]
特に注目したいのは、最初の等式である。

document.write.toString===document.write.toString.toString
document.write.toString と document.write.toString.toString に Fakeの関数を用意するとすれば以下のようになる。
document.write.toString=()=>{ return `function write() { [native code] }`; }; document.write.toString.toString=()=>{ return `function toString() { [native code] }`; };
Fakeの関数はどうしても2つの違った関数を用意する必要があり、等式は成り立たなくなる。 従って、等式が成り立たたないのならば、Fakeであるとわかる。 ちなみに、[4]も重要である。[4]ではfunction.toStringと比較している。 function.toStringは、functionのサイズの変化で改ざんを検出するのに使われる。 Hackerは、この検出の回避のために、function.toStringを override するわけだが、 HObfus側では、[4]をチェックするので、Hackerは、以下の3つを一つの関数にまとめなければならず さらに難しくなる。
p.toString p.toString.toString (()=>{}).toString