yutaponのブログ

javascript界隈の興味あるネタを備忘録的に残しておく場所

KaomojifyJSとかいうUglifyJSの亜種を試してみた

5 Minites of JavaScriptで紹介されていたKaomojifyJSをちょっと触ってみたという記事。

GitHub - Nekuromento/UglifyJS: JavaScript parser / mangler / compressor / beautifier library for NodeJS

はじめに

そもそもuglifyjsはjsのスペースとか改行などを取り除いたり、変数名を短くしてコードを圧縮するツールです。

生成されたコードは人間が読めないようなものになるので、難読化するツールとも言えます。

kaomojifyjsは難読化する際に、変数名などを顔文字化するツールです。
つまりネタツールのようです。

ちょっと触ってみた感じ、単に動かすだけならコマンドライン上で実行するのが
簡単だったので動かす手順を紹介します。

準備

ここからリポジトリをクローンしてきます。
(githubリポジトリ管理はghqが便利!)

クローンしてきたリポジトリに移動して、$ npm installを実行します。

これでターミナル上で動かす準備が整いました。

Kaomojifyしてみる

uglifyjsコマンドのリファレンスは本家のリポジトリに詳細が記載されています。

https://github.com/mishoo/UglifyJS#usage

一番単純な使い方は単にファイルパスを渡すだけです。

# クローンしてきたuglifyjsのディレクトリ内で下記コマンドを実行すると
$ ./bin/uglifyjs FILE_PATH
# ここに難読化された内容が出力される

 

jsファイルへのパスを適当に渡して挙動を確認してみます。

./bin/uglifyjs ./lib/squeeze-more.js
function ast_squeeze_more(ಥل͟ಥ){function ʘ̥ꀾʘ̥(ಥل͟ಥ,ᵕ̈){var OཅO=ꉺꈊꉺ,ʘ̥ꀾʘ̥;return ꉺꈊꉺ=ಥل͟ಥ,ʘ̥ꀾʘ̥=ᵕ̈(),ꉺꈊꉺ=OཅO,ʘ̥ꀾʘ̥}function ᵒ̌ཫᵒ̌(ಥل͟ಥ,ᵕ̈,ꉺꈊꉺ){return[this[0],ಥل͟ಥ,ᵕ̈,ʘ̥ꀾʘ̥(ꉺꈊꉺ.scope,curry(MAP,ꉺꈊꉺ,OཅO))]}var ᵕ̈=pro.ast_walker(),OཅO=ᵕ̈.walk,ꉺꈊꉺ;return ᵕ̈.with_walkers({toplevel:function(ಥل͟ಥ){return[this[0],ʘ̥ꀾʘ̥(this.scope,curry(MAP,ಥل͟ಥ,OཅO))]},"function":ᵒ̌ཫᵒ̌,defun:ᵒ̌ཫᵒ̌,"new":function(ಥل͟ಥ,ᵕ̈){if(ಥل͟ಥ[0]=="name"){if(ಥل͟ಥ[1]=="Array"&&!ꉺꈊꉺ.has("Array"))return ᵕ̈.length!=1?["array",ᵕ̈]:OཅO(["call",["name","Array"],ᵕ̈]);if(ಥل͟ಥ[1]=="Object"&&!ꉺꈊꉺ.has("Object"))return ᵕ̈.length?OཅO(["call",["name","Object"],ᵕ̈]):["object",[]];if((ಥل͟ಥ[1]=="RegExp"||ಥل͟ಥ[1]=="Function"||ಥل͟ಥ[1]=="Error")&&!ꉺꈊꉺ.has(ಥل͟ಥ[1]))return OཅO(["call",["name",ಥل͟ಥ[1]],ᵕ̈])}},call:function(ಥل͟ಥ,ᵕ̈){if(ಥل͟ಥ[0]=="dot"&&ಥل͟ಥ[1][0]=="string"&&ᵕ̈.length==1&&(ᵕ̈[0][1]>0&&ಥل͟ಥ[2]=="substring"||ಥل͟ಥ[2]=="substr"))return["call",["dot",ಥل͟ಥ[1],"slice"],ᵕ̈];if(ಥل͟ಥ[0]=="dot"&&ಥل͟ಥ[2]=="toString"&&ᵕ̈.length==0)return ಥل͟ಥ[1][0]=="string"?ಥل͟ಥ[1]:["binary","+",ಥل͟ಥ[1],["string",""]];if(ಥل͟ಥ[0]=="name"){if(ಥل͟ಥ[1]=="Array"&&ᵕ̈.length!=1&&!ꉺꈊꉺ.has("Array"))return["array",ᵕ̈];if(ಥل͟ಥ[1]=="Object"&&!ᵕ̈.length&&!ꉺꈊꉺ.has("Object"))return["object",[]];if(ಥل͟ಥ[1]=="String"&&!ꉺꈊꉺ.has("String"))return["binary","+",ᵕ̈[0],["string",""]]}}},function(){return OཅO(pro.ast_add_scope(ಥل͟ಥ))})}var jsp=require("./parse-js"),pro=require("./process"),slice=jsp.slice,member=jsp.member,curry=jsp.curry,MAP=pro.MAP,PRECEDENCE=jsp.PRECEDENCE,OPERATORS=jsp.OPERATORS;exports.ast_squeeze_more=ast_squeeze_more;%

実行したときのスクショも。

f:id:sskyu:20150409131931p:plain

難読化すると本来aとかbとかに変換される変数が顔文字化されてることがわかります。
いろんな種類の顔文字が出力されているので、顔文字を探すだけでも楽しいかもしれない。

所感

gulp-uglifyの中で使ってるuglifyjsを置き換えたら使えるようになるかなーと思ったけど、そんなに甘くはなかった。
確かに難読化という点では本家よりも向上しているかもしれないけど、圧縮率という点では文字数が増えている分低下しています。

普通に考えたら本番環境には導入しないと思うけど、Web開発者向けにネタを仕込むなら使ってもいいのではないかと。

応用で、リポジトリをforkして

https://github.com/Nekuromento/UglifyJS/blob/master/lib/process.js#L297

この箇所を変更すればオリジナルのほげほげファイを作れそう。

おわりに

この記事は30分で検証して30分で書いたものです。

限られた時間でまとめるのは難しい。