4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaScriptを全角文字で記述して、究極の難読化をする方法

Last updated at Posted at 2017-05-12

#JavaScriptを全角文字で書いて更に難読化させる

JavaScriptの一部の文字列、もしくは、命令全体を全角文字で書くことによって、更に難読化させることができます。
セキュリティー上、少しでも見られたくないURLや文字列、命令文を記述したりするのに有効です。

ソースコード上では、ただ全角コードで記述してあるため、可読性が良く、かつ、難読化させる時は、全角文字を強制的に \uxxxxのような文字列にするために、更に難読化させる効果があります。

現代のブラウザは、JavaScriptはUTF-16で実行されていますが、ツールによって変換を行ないます。
ソースはUTF-8で記述するようにしてください。

##必要なツール

utf16.pl
#!/usr/bin/perl
# Usage perl utf16.pl inputfile outputfile

use utf8;
use Encode;

$in=$ARGV[0];
$out=$ARGV[1];

$buf="";
open(R,"<:utf8",$in)||die "$in not found\n";
#binmode(R,":utf8");
open(W, ">$out")||die "$out can't write\n";
foreach(<R>) {
	for($i=0; $i<length($_); $i++) {
		$c=substr($_, $i, 1);
		if(utf8::is_utf8($c) && (ord($c) > 0x7f)) {
			utf8::encode($c);
			Encode::from_to($c, "utf8", "utf16");
			$c=~s/(.)/unpack('H2',$1)/eg;
			$c=~s/(feff)/\\u/g;

			$buf.=$c;

			$c=substr($_, $i+1, 1);

		} else {
			$buf.=$c;
		}
	}
#	print W "\n";
}
$buf=~s/\\u([0-9A-Fa-f][0-9A-Fa-f])(\n)/"\\u$1" . unpack("H2",$2)/ge;

print W $buf;
close(W);
close(R);

##難読化方法
Makefile等で

Makefile
perl utf16.pl script.js script.min.js.tmp1
yuicompressor --type js script.min.js.tmp1 > script.min.js.tmp2
perl jsPacker.pl -e62 -q -f -i script.min.js.tmp2 > script.min.js
rm -f script.min.js.tmp1 script.min.js.tmp2

##実例として、まず、行ないたいソースです。

###ソース

step1_src.js
var GLOBAL = (this || 0).self || global;

(function (G, D, W){
	W.onload = function() {
		alert("test");
	}
})(GLOBAL, document, window);

###難読化します

step1_compiled.js
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36);};;if(!''.replace(/^/,String)){while(c--)d[c.toString(a)]=k[c]||c.toString(a);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('e 1=(d||0).9||8;(2(b,c,a){a.7=2(){6("5")}})(1,4,3);',15,15,'|GLOBAL|function|window|document|test|alert|onload|global|self||||this|var'.split('|'),0,{}))

alert、test共に文字列がソースに存在します。

##次に、「test」の文字だけ、更に難読化します

###ソース

step2_src.js
var GLOBAL = (this || 0).self || global;

(function (G, D, W){
	W.onload = function() {
		alert(zenhan("test"));
	};
	var zenhan=function(str) {
		var h = '';
		str.split('').forEach(function (s) {
			h += String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
		});
		return h;
	};

})(GLOBAL, document, window);

###難読化します

step2_compiled.js
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36);};;if(!''.replace(/^/,String)){while(c--)d[c.toString(a)]=k[c]||c.toString(a);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('2 3=(r||0).q||p;(1(b,c,a){a.o=1(){n(d("\\4\\m\\l\\4"))};2 d=1(f){2 e="";f.k("").j(1(g){e+=i.h(g.9(0)-8)});7 e}})(3,6,5);',28,28,'|function|var|GLOBAL|uff54|window|document|return|65248|charCodeAt||||||||fromCharCode|String|forEach|split|uff53|uff45|alert|onload|global|self|this'.split('|'),0,{}))

testの文字列がわかりづらくなりました。

##alert("test")自体をすべて難読化する
evalを使うことで、すべて全角文字でJavaScriptを書くことができます。

step3_src.js
var GLOBAL = (this || 0).self || global;

(function (G, D, W){
	W.onload = function() {
		eval(zenhan("alert(’test’);"));
	};
	var zenhan=function(str) {
		var h = '';
		str.split('').forEach(function (s) {
			h += String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
		});
		return h;
	};

})(GLOBAL, document, window);
step3_compiled.js
eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36);};;if(!''.replace(/^/,String)){while(c--)d[c.toString(a)]=k[c]||c.toString(a);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('2 4=(y||0).x||w;(1(v,u,9){9.t=1(){r(6("\\q\\p\\8\\o\\3\\n\\7\\3\\8\\m\\3\\7\\l\\k"))};2 6=1(5){2 h="";5.j("").i(1(s){h+=g.f(s.e(0)-d)});c h}})(4,b,a);',35,35,'|function|var|uff54|GLOBAL|str|zenhan|u2019|uff45|W|window|document|return|65248|charCodeAt|fromCharCode|String||forEach|split|uff1b|uff09|uff53|uff08|uff52|uff4c|uff41|eval||onload|D|G|global|self|this'.split('|'),0,{}))

alert、testともにわかりづらくなりました。

##function zenhanの注意

  • 強制的にコードを引き算するため、半角文字が含んでいるとうまく動作しません。
  • 全角文字に存在して、半角文字に存在する文字列を含めることはできません。例:「あいうえお」

##最後に

  • あくまで難読化であって、何らかの方法で復号することはできます。(筆者は既に確認済です)
  • 難読化を行うことによって、パフォーマンスが落ちたり、動作しなくなったりする可能性があります。よくデバッグを行ないながら行いましょう。
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?