そうでないコード

こんにちは、habravchane!



約1年前、Habrは「JavaScriptのN行の%string%」という件名の投稿で一掃されました。 どのようにすべてが終了したのかさえ覚えていませんが、すべては30行のExcelで始まりました。 次に、この主題に関する他の多くの興味深いバリエーションが登場しました。JSゼロラインを演奏することもありましたが、それはまったく別の話です...



どんなにコンパクトなものを考え出そうとしても、何も生まれませんでした。 その後、問題を別の角度から見ることにしました。 この瞬間、私の頭に疑問が浮かびました。コードが「崩壊」して、コードがまったく存在しないようにすることは可能ですか? そして、デビッド・ブレインが私を呼んだ。



私はいくつかの魔法を追加しようとしましたが、これは私が得たものです。



画像



「消える」コード



タスクは、コードを記述することです...どのように。 また、彼は何かをすることができなければなりません。 明らかに、操作にはこれらの操作を解釈できる特定の関数が必要であるため、残念ながらコードを非表示にすることはできませんが、最後の行を数行に分割するのは簡単です。



多くの人々は、コンピューターの活版印刷に印刷できない文字があることを知っているか、聞いたことがある。 実質的に見えない。 さらに、これは何らかのバグやチップではありませんが、非常に正常な動作です-目に見えません。 現在、一般に受け入れられ標準化されているテキストエンコーディングの1つはUTF-8であり 、ほとんどすべての最新のサイトで使用されています。 目に見えないキャラクターがたくさんいることも貴重です! たとえば、そのうちの1つはゼロ幅スペース(U + 200B)です。 ここにあります: ""。 ほら いや? しかし、彼はそうです。



デビッド・ブレイン・メソッド



手に触れたい人のために、1年前の例へのリンクを提供します無料のオンラインデモをご覧ください 。 後で、Habrのサンドボックスでのメモの数か月後、偶然にも、このアイデアが表示されている投稿 (方法3)に出会いましたが、ひねりはありませんでした。



私のバージョンでは、エンコードは最も原始的な方法で行われました。 マイナス-ファイルサイズが大幅に増加し、さらに-エンコードに必要なのは2文字のみです。 次のようになりました。

var code = '1101101111110111111111111111110101101101111101111';
      
      





かなりの時間が経った後、私は自分が取り組んでいるプロジェクトの一環としてこのトピックに戻りました。 さらに進んで、各文字が1と0ではなく4文字でエンコードされるという事実から始まりました。

 "f".charCodeAt(0).toString(16); // "66" //    "f" - 0x0066 String.fromCharCode("0x0066"); // "f"
      
      





その結果、16文字のセットを使用して、余分なコードの超過を減らすことができます。

 var Symbols = ["","","","","","","","","","","","","","","",""]; //    "f": var bar = invisibleJS("f"); // bar = "";
      
      





この例のコードが占めるボリュームの増加は4x (1文字をエンコードするために4文字)に減少しましたが、理論的には、ロシア語やラテン語以外の文字が必要ない場合は2xを達成できます。



スタジオでの例



次のようなコードにします。

 alert("Hello world!");
      
      





コードを難読化ツールにフィードした後(コードの引用と解析は行いませんが、興味深いことは何もありません)、出力は次のようになります。

 var helloworld = "⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏⁡⁡‍‭⁡⁡‍‍⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌⁡⁡‍‍⁡⁡‍‮";
      
      





セミコロンは引用符内にあることに注意してください。ただし、実際にはそうではありません( Sublimeなど、ほとんどすべてのテキストエディターで確認できます)。 一方で、これは難読化に+5を追加し、誤解を招きやすく、軽い頭痛で脅迫します。一方、「正しい」エディターはテキストの方向(左から右、右から左)に影響する文字を使用しません。



これは、デコード関数が結果としてどのように見えるかです:

 var revealJS = function(s){return s.match(/(.{4})/g).map(function(b){return b.split('').map(function(i){return Array.apply(null,{length:10}).map(Number.call,Number).concat('abcdef'.split(''))['⁡‌‍‎‏‪‫‬‭‮'.split('').indexOf(i)]})}).map(function(c){return String.fromCharCode(0+"x"+c.join(''))}).join('')}
      
      





コードがより良く、より小さく、よりエレガントになることは確かですが、このタスクはこの投稿の価値はありません。 行の終わりで、コードは再び右から左に移動することに注意してください。 一般に、このニュアンスは、わずかに異なる不可視の文字を拾うことで除去できます。



これで、非表示のコードを「マニフェスト」できます。

 var helloworld = "⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏⁡⁡‍‭⁡⁡‍‍⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌⁡⁡‍‍⁡⁡‍‮"; revealJS(helloworld); // "alert("Hello world!")" eval(revealJS(helloworld)); // !
      
      





ここから直接コンソールにコピーするか、こちらをご覧ください



例として引用されている「開発者」コードは、「消失」機能で使用される特定の文字に合わせて調整されています。これらの文字を場所で変更したり、他の文字を使用することで、「コードテーブル」オプションの数は無限に増加します。



これには1つの大きなマイナス点がありますeval()



を使用して実行されたコードをのぞき見できます。 さらに、コンソールはこのコードが開始されるファイル/行を示します:





この誤解を修正できます。 コーディングに4文字すべてを使用する場合(上記で説明したように)、難読化の中に難読化の可能性があります。 Xzibitは興奮しました

 //  ... alert("Hello world!"); // ... window["alert"]("Hello world!"); // ... window[revealJS("⁡⁡‫‌⁡⁡‫⁡⁡‫‪⁡⁡‬‍⁡⁡‬‏")](revealJS("⁡⁡‏‭⁡⁡‫‪⁡⁡‫⁡⁡‫⁡⁡‫⁡⁡‍⁡⁡⁡‬‬⁡⁡‫⁡⁡‬‍⁡⁡‫⁡⁡‫‏⁡⁡‍‌")) // ...   : "⁡⁡‬‬⁡⁡‫‮⁡⁡‫⁡⁡‫‏⁡⁡‫⁡⁡‬‬⁡⁡‪⁡⁡‫‌⁡⁡‬‎⁡⁡‫⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‪⁡⁡‍‭⁡⁡‫‌⁡⁡‬‎⁡⁡‫⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‍‮"
      
      





こちらで見れます 。 ちなみに、誰もコードを少なくとも3回、少なくとも4回難読化することはありません。



結果のコードは次のようになります。





すでに優れていますが、何か他のことができます。 記事の冒頭で、コードを隠していないかのように隠すタスクの概要を説明しました。 これで、コンソールを開くだけで、すぐに問題を確認できます。 このニュアンスを取り除くことは非常に簡単でした: eval()



代わりにeval()



使用します:

 var script = document.createElement("script"); script.innerHTML = revealJS("⁡⁡‬‬⁡⁡‫‮⁡⁡‫⁡⁡‫‏⁡⁡‫⁡⁡‬‬⁡⁡‪⁡⁡‬‍⁡⁡‫‪⁡⁡‬‫⁡⁡‫‪⁡⁡‫‌⁡⁡‫⁡⁡‏⁡⁡‪‎⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‪⁡⁡‍‭⁡⁡‬‍⁡⁡‫‪⁡⁡‬‫⁡⁡‫‪⁡⁡‫‌⁡⁡‫⁡⁡‏⁡⁡‪‎⁡⁡‍‭⁡⁡‍‍‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‍‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡‫‍⁡‫‌‍⁡‫‌‍⁡‍‍⁡⁡‍⁡‫‌‍⁡‫‌‍⁡⁡‍⁡⁡⁡⁡‍‍⁡⁡‍‮⁡⁡‍‮"); document.getElementsByTagName('body')[0].appendChild(script); //      ,      document.getElementsByTagName('body')[0].removeChild(script);
      
      





残念ながら、 jsFiddleでこのコードを実行すると、コードが表示されたままになります。 これは、JavaScriptウィンドウのコードもeval()



または同じものでラップしているという事実に何らかの関係があるという疑いがあります。 「奇跡」のないローカルプロジェクトでのテスト中、すべてが正常に機能し、実行される機能自体が現れません。

画像



適用分野



1 楽しみのために。

2 。 コード難読化ツール。

。 他の方法と組み合わせて使用​​して、コードを縮小/難読化します。 たとえば、 Google Closure CompilerまたはUglifyJSなど

4 。 オープンエリアでの秘密のコミュニケーションの可能性。

5 。 「スリープ」スクリプト、記事内の「ブックマーク」、フォーラム上のメッセージ、メッセージボード、コンテキスト広告。ただし、一般的にどこに書くものを与えても、これがユーザーのブラウザーに入ります。



最後の2つのポイントでは、すべてがそれほど単純ではありませんが、言及するしかありませんでした。 少し考えを明らかにします。 ざっと見てみると、たとえば、 GmailYandex.Mailはそのような文字を削除しないことがわかりました。 一部は‍ ‪ ‎



変換され‍ ‪ ‎



‍ ‪ ‎



、しかしパーツは見えないままです。 メールクライアントでも状況は似ていると思います( Thunderbirdをチェックしました)-何も見えません。 これは、隠されたメッセージを文字で送信できることを意味します。これは、「目視検査」中に何らかの形でそれ自体を与えることはなく、解読できない隠し文字を発見しても、解読アルゴリズムを持っている人だけが解読できます(一般的に、あなたの頭にそれを保存し、ブラウザコンソールで直接コードを書くことができます):

 ,  ⁡⁡‍⁡⁡‍⁡⁡‏‏‌⁡‏‎‪⁡‏‎‎⁡‏‎⁡‏‎‏⁡‏‎⁡‏‏⁡⁡‍⁡⁡‏‎‍⁡⁡‍⁡⁡‏‎⁡‏‏⁡‏‏‍⁡‏‏⁡⁡‍⁡⁡‍⁡⁡‏‎⁡‏‏⁡⁡‏‎‭⁡‏‏‪⁡‏‎⁡‏‎‏⁡‏‎‭⁡⁡‍⁡⁡‏‎⁡‏‎‏⁡‏‎‭⁡‏‎?
      
      





しかし実際には(文字「a」と疑問符の間にある部分にrevealJS()



を適用する必要があります):

   /*,   ,  */?
      
      





画像



したがって、オープンエリアでの秘密のコミュニケーションの可能性があります。 この場合、誰も何も疑わないでしょう。 (意図的に検索しない限り、これは別の会話です)。 一般的に、主な利点の1つ(そしておそらく唯一の利点)は、コンテンツが「視覚的制御」を通過することです(ただし、ここですべてがスムーズになるわけではありません。 それは目に見えない人とビデオ監視システムのようなものです。 おそらく、インターネット全体がこのようなメッセージで長い間詰め込まれているのでしょうか? :)



隠されたスクリプトについては、すべてが明白です:「開発者」と「ランチャー」を含む悪意のあるjsコードが何らかの方法でブラウザに侵入した場合(たとえば、多くの人が外部からライブラリをロードし、同じjQueryを取得しますハッキングされた 、またはAdBlockなどの一般的なプラグイン)、一定の確率でページに隠されたコードが起動されます。 つまり、この場合、スキームは次のとおりです。それぞれが独自の方法で向けられた多くの異なる「ベクター」と、非常に小さな単一の「アクティベーター」です。



ご清聴ありがとうございました。



追伸 少し「nishtyachok」:行の先頭のスクリプトで、文字U + 202E (右から左へのオーバーライド)を引用符で囲むと、楽しいものになります。 コードの機能は保持されます:



 "‮";var revealJS = function(s){return s.match(/(.{4})/g).map(function(b){return b.split('').map(function(i){return Array.apply(null,{length:10}).map(Number.call,Number).concat('abcdef'.split(''))['⁡‌‍‎‏‪‫‬‭‮'.split('').indexOf(i)]})}).map(function(c){return String.fromCharCode(0+"x"+c.join(''))}).join('')}
      
      






All Articles