Cocos2d-x 勉強第13回「Luaスクリプトの難読化」

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー
SEGAさん、DIVAの筐体ください(ズザー

まずはこれを見ていただきたい

raw

前回の記事(Cocos2d-x 勉強第12回「Luaを試してみる」)で、 cocos2d-xにおけるlua bindingのサンプルを追った訳ですが、

luaスクリプトは「リソースファイル」という扱いで、plainなテキストでアプリに同封されますので、 悪意のあるユーザーは改変が簡単にできてしまうでしょう。
難読化、できれば暗号化できるのが望ましいです。

確認してみたところ、まさしくまんま、そのまんまの姿で同封されております。
これではいじりたい放題にいじれと言っているようなもの。

不正を許せない日本男児としては、なんとかして対策を取り入れたいところです。

luajitで難読化

そこでluajitさんです。luajitさんは、luaスクリプトの最適化、bytecode化などをしてくれるそうです。 キャー!カッコイイ!

早速、下記のコマンドでbytecodeに変換してみることにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ luajit -b hello.lua hello.luajit

# 一応中身を確認しておく
$ head hello.luajit
J7447C==G
         format
               string
print�4%>4%4>%$>447>=4%>Gtraceback
debug
tostringLUA ERROR: -----------------------------------------
cclog�+7T�G+7>+7+7T�+7T�+7>G�setPositionX
isPaused�e'i'_477>7%>47''>477>47'      >47>47 >):
7
 +  7
                    +
7

+
 7

うん、関数名とかはそのままみたいだけど、これをそのままいじくれるやつなんてそうは居まい…。

また、luaの読み込み部分もhello.luajitの方を読むように修正します。

1
2
//std::string path = FileUtils::getInstance()->fullPathForFilename("hello.lua");
std::string path = FileUtils::getInstance()->fullPathForFilename("hello.luajit");

これで試しにビルドしてみると…、動く!動くぞ! 難読化に関してはこれで問題ないでしょう。

難読化の問題点

一見、スクリプト操作への対策として難読化でも必要十分な条件を満たしているように思えますが、難読化は基本的にdecode可能な内容になっているはずです。
ひとたびdecodeされてしまえば、アプリの内容をさらけ出してしまうでしょう。

そもそも、読み込まれるファイル名さえ把握されてしまえば、そのファイル名で任意のコードを置いてしまえばいいので、 スクリプトでのネイティブアプリ開発はこのあたりのセキュリティ対策は念には念を入れて行わなければ、とんでもない事態を招いてしまいかねません。

あ、あと、毎度々々luajitコマンド叩くのも面倒なので、このあたりを自動化する必要性があると思うんですよね。。
パスを書き換えるのも面倒なので、ビルド時にluajitを噛むように改修できると一番よいと思うのですが、それってどうやるんですかね…?
今度調べてみるか…。

できれば暗号化をしたい

スクリプト言語を用いる場合、ファイル自信を暗号化してしまうのがやはり望ましいです。
ただ、アプリ自身がそれをデコードする仕組みがないと実行すらできない、という宿命を背負っているために デコードのための鍵を同封せざるを得ず、このあたりのスマートな解決方法に関して参考文献をまだ見つけられておりません。。

だれか何かよい資料があれば教えていただけるとありがたいです。

参考文献など

感謝です!

ソースコード

https://github.com/8823-scholar/cocos2d-x-study/commit/d08dcc44515ec3f5f8c0dd5a83db69eb82cc583b