Help us understand the problem. What is going on with this article?

MATLABいたずらテクニック

はじめに

うちの研究室では,研究にMATLABが必須となっています。
そして,一時期他の人のMATLABにいたずらプログラムを仕掛けることが流行っていました。
同じ悲劇を繰り返さないため1に,その時に得た知識をメモしておきます。

注意

もし試してみようと思った人は以下に気を付けてください。

  • 使い方を誤るとシミュレーションデータが消えるなど,シャレにならない結果になります。
  • かならず自分の環境でデバッグしてから仕掛けましょう。
  • コードを仕掛けるときは,時と場合と相手を選んで利用してください。

そして,コードを利用したことによる損害に,私は一切責任を取らないことを付け加えておきます。

MATLAB起動時にスクリプトを自動実行する

MATLABでは起動時に検索パス内にある start.m という名前のファイルが自動的に実行されます。(公式ドキュメント)
そこで,このstartup.mにいたずらコードを仕込むことで,相手がMATLABを起動した瞬間にいたずらプログラムを実行できます。

この方法なら起動直後なのでシミュレーション結果を壊してしまう恐れもありません。
また,コードを仕込むタイミングと実際に実行されるタイミングがずれるため,仕掛人がばれにくいという利点があります。

無限ループを作る

MATLABでもwhile true ~~ endとかで無限ループが作れます。
これとmsgbox関数uiwait関数を組み合わせれば,無限アラートなどは簡単に作れます。

infinite_loop.m
% 実行した場合は,Ctrl-Cで終了可能
str = {'  ∧_∧  ババババ', '( ・ω・)=つ≡つ', '(っ ≡つ=つ', '`/  )',...
       '(ノΠU', '何回閉じても無駄ですよ~ww', 'm9(^Д^)プギャー!!'};
while true
h = msgbox(str, 'アラート', 'warn');
uiwait(h);
end

抜けられない無限ループを作る

先ほど無限ループの作り方を紹介しました。
しかし,単純な無限ループでは"Ctrl-C"で終了可能です。
これを回避し勝手に終了できなくするために,onCleanup関数を利用します。

onCleanup関数はある変数が消えるとき(スコープを抜けるとき)に,任意の関数を実行させる関数です。
そして,Ctrl-Cで関数を終了させた場合には,その関数のスコープを抜けるためローカル変数は消えてしまいます。
そこで,ローカル変数をトリガーに再帰的に関数呼び出しをさせることで抜けられないループを作れます。

例えば,「(クイズに正解するまでは)何回閉じても無駄なアラート2」は以下のコードで実現可能です。
(もちろん,Ctrl-Cでも止めることはできません)

infinite_loop_advanced.m
looping();          % ループする関数呼び出し

function looping()
persistent c;       % ループ回数
persistent flagFin; % 終了するべきか
MAX_ITERATION = 10; % 最大ループ回数(500以下)
if isempty(c)
    % 永続変数の初期化
    c = 0;
    flagFin = false;
end
% ループを終了すべきかを判断
if c < MAX_ITERATION && ~flagFin
    tempObj = onCleanup(@() looping());     % 消えるとき再帰呼び出し
    joke();                                 % ジョークプログラム呼び出し
    flagFin = isFinished();                 % 終了条件を判定
    c = c + 1;
else
    clear flagFin c     % 永続変数の消去
end
end

function flag = isFinished()
% 終了条件を判定する(今回はクイズ)
in = input('Q. 1年は何か月ですか?: ');
if in == 12
    flag = true;
else
    flag = false;
end
end

function joke()
% ジョークプログラム本体

str = {'  ∧_∧  ババババ', '( ・ω・)=つ≡つ', '(っ ≡つ=つ', '`/  )',...
    '(ノΠU', '何回閉じても無駄ですよ~ww', 'm9(^Д^)プギャー!!'};
h = msgbox(str, 'アラート', 'warn');
uiwait(h);
disp('aa');
end

コードを読めないようにpファイル化する

いろいろスクリプトで工夫したとしても,ソースコードを読むことができれば対処は可能です。
ですが,MATLABにはソースコードを保護する(隠す)方法があります。
それが,pcode関数とpファイルです。

例えば,先ほどのlooping関数を別個の関数ファイルに保存しstart.mから呼び出す形とすると,ソースコードを難読化することができます。

おわりに

以上が,これまでに当研究室で確認されたいたずらテクニックです。
仕掛ける相手に気を付けつつ,楽しんでもらえたらなーと思います。

MATLABは研究に使うため真面目なイメージがあるかもしれませんが,いたずらも含めてゲーム作成などいろいろ遊ぶこともできます。
「好きこそものの上手なれ」ですし,楽しいと学ぶ意欲も高まるものだと思います。
ですので個人的には,遊びながらMATLABに慣れていくのもありなのかなーと思います。
「こんなこともできるんだ!」「面白そう!」と思ってもらって,MATLABに興味を持つきっかけになればうれしいです。

なお,もし本記事に問題などありましたらコメントなどですぐにお知らせください。

参考文献

  1. 闇の魔術に対する防衛術 Advent Calendar 2019 (Qiita)
  2. 闇の魔術に対する防衛術 Advent Calendar 2018 (Qiita)
  3. アラートループ事件 (Wikipedia)
  4. MATLAB でゲームを作る (Qiita)
  5. MATLABでマインスイーパ (Qiita)
  6. Simlinkでテトリス (MATLAB 公式ドキュメント)

  1. 仕掛け方を知っていれば対処も可能ですが,知らないと解除になかなか苦労します・・・。 

  2. 一応安全のため,MAX_ITERATIONで回数制限はかけています。また,MATLAB本体が再帰呼び出しの回数に制限をかけているため,厳密には無限にはループしません。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした