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