開発者諸君、己を守れ!

Sergey Kravchuk | 22 4月, 2016

知的財産の保護はいまだに大きな問題です。本稿では MQL4 プログラム保護の基本原則について説明します。これら原則により、みなさんの開発結果が盗難にあわないよう、すくなくとも盗人の『仕事』をひじょうに複雑にして行わなくなるようにします。

はじめに

MQL を知り始めたころ、MQL プログラマ―のバラ色のメガネを通して、私は『すべての点で快適』な絵:当然のごとくトレード方法を知らされる、を見ました。私はまさしく明確にプログラムを書いています。それを仕事のために手に入れた人はだれも、最初に利益を手にしたのち、高品質なプロダクトに対する感謝としてそのほんの一部を送ってくれます。

最初のデポジット $20 で $5 を儲けた初心者トレーダーは、熱意をもって私に$2 とを送ってくれ、トレードのエースは再び $2,000 を引き出して $200 もの感謝を届けてくれるのです。すべて完全に良心的に見えます。私はトレーダーにはできない仕事をしています。トレーダーはそれを利用して利用しない場合より多く/頻繁に/簡単に/継続的にお金を儲けているのです。共に働いて成功し、すばらしい財政的結果を手にしてきました。これは資金ベースで分割することのできるものです。これに対して私は特別な分配条件を考え出しました。FairWare です。

私の最初のインスツルメントのまともなダウンロード数とそれに関する絶え間ない質問と相談にもかかわらず、$3 しか受け取らなかったときの私の驚きを想像してください。その人は明らかにわたしの FairWare 条件を参照していたのです。私のプロダクツのユーザーの良心はかなり乏しいものでした。そこで私は少なくとも実アカウントで私のツールを使用する場合の最低支払額を設定することにしました。

このためには、私はツールを保護し、シェアウェア の原則に切り替えたのです。私のツールがより充実するにつれ、ますますそれを保護したいという思いは厳格になりました。これまで、MQL コーディング仲間とシェアすることに決めたいくつかの実証済みの方法を集めました。本稿で先に述べたとおり、われわれは全員、多少この道を歩んできています。そして、一か所に集められたこの問題に関する情報はこれら『保護の苦しみ』を確実に和らげるのです。

というわけで、始めましょう。まずは簡単なところから複雑なものへ。。。



文字列定数の保護

まずみなさんが保護したい最初の事柄は著作権です。自分がその優れたもの書いたイケてるプログラマーであると自信を持ち自慢するだけでなく、ユーザーが作成者からのフィードバックを受ける機会を得るために、です。「マーフィーの法則」にもあるように、『最後に見つけるバグは実際は最後から2番目のバグである』のです。そして検証中偶然見つけ、別のだれかがみなさんのチェックをすり抜けたものを見つける可能性があるのです。このような場合、それが Expert Advisor のウィンドウに表示されるとき、自分の変更のない E メールやウェブサイトのアドレスを含むテキスト文字列を作成する必要があります。簡単なコードを考察します。

//+------------------------------------------------------------------+
//|                                                  Protect-001.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start()
{
  Comment("Copyright © 2009, Sergey Kravchuk");
  return(0);
}

すべて明解でオープンです。スクリプトはコメントを表示します。ex4 ファイルの中を見ると、テキストがすべて開いているのがわかります。

HEX エディタにより、すべて表示されるテキストを簡単に置換でき、変更済みスクリプトは著作権を失います。

ここで考えましょう。テキスト文字列とは?これは相互の連結された文字の連続です。誰がそのような文字列を『一文字ずつ』書くのを妨げるのでしょうか?ただし、その前にエンコードされた文字列のコレクタを準備します。以下がそのソースコードです。

//+------------------------------------------------------------------+
//|                                                  Protect-002.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

#property show_inputs

extern string prefix = "char";
extern string text   = "input your text for encoding";
string rez           = ""; // here we will assemble the result

int start()
{
  // enter the original text to see what this string is
  rez = "/* " + text + " */ ";
  
  for (int i = 0; i < StringLen(text); i++)
  rez = rez + prefix + "[" + StringGetChar(text, i) + "]+";
  
  // cut the last '+' character and print string to the log
  Print(StringSubstr(rez, 0, StringLen(rez)-1)); 
}

作業アルゴリズムは明らかであることを願っています。何がコードになっているのかわかるようにコメントを入れ、個々の文字から組み立てられている文字列コードを取得するために一文字ずつ連結するのです。結果としての文字列はログに表示されます。そこからコピーし、元のソースコードに挿入します。

それがどのように作用するか理解するため、エンコードされた文字列でソースを見てみます。

//+------------------------------------------------------------------+
//|                                                  Protect-003.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start()
{  
  string char[256]; int i;

  for (i = 0; i < 256; i++) char[i] = CharToStr(i);

  Comment
  (
    /* Copyright © 2009, Sergey Kravchuk*/ 
    char[67]  + char[111] + char[112] + char[121] + char[114] + char[105] + char[103] +
    char[104] + char[116] + char[32]  + char[169] + char[32]  + char[50]  + char[48]  +
    char[48]  + char[57]  + char[44]  + char[32]  + char[83]  + char[101] + char[114] +
    char[103] + char[101] + char[121] + char[32]  + char[75]  + char[114] + char[97]  +
    char[118] + char[99]  + char[104] + char[117] + char[107]
  );
  return(0);
}

ごらんのように、まず、メインの ASCII テーブルの可能な256文字すべての文字列配列を宣言し、各エレメントを対応する文字で埋めます。それから、元の文字列を「ターミナル」ウィンドウの「エキスパート」タブからコピーされたエンコード済みテキストと置き換え、それをコンパイルしました。以下がその結果です。

結果として、内容は暗号化され、エンコードされた文字列はもう見ることができません。その後、それは失われてしまいます。代わりに、コマンドセットがあります。それは個別の文字から組み合わせるものです。残りの暗号化されていない文字列は #property 著作権と #property リンクからの定数です。残念ながら、それらはエンコードできません。というのも、それらは文字列としてのセットで、組み立てコードは許可されていないためです。

HEX エディタで可能であろう変更から保護したい文字列はすべてこの方法でエンコードできます。それはProtect-002.mq4 スクリプトによって暗号化することが可能です。そのようなアセンブリを使用する場合、操作にいくらか時間がかかることを念頭に置かなければなりません。よって、ティック毎にそれを何百回と使用しないためにも、そのようなコードブロックを直接エキスパート本文には入れません。必要な文字列変数を宣言し、それをインディケータやエキスパートの初期化でエンコードされたアセンブリによって一度初期化するだけで十分です。それからその変数を使用します。



不正使用に対する保護

著作権を保護したわけですが、別の問題があります。みなさんの Expert Adviser は知らないところで(たとえば、DC の取引フロアのコンピュータから離れているとき)誰かの手でコピーされ、そののち知らない間に使用される可能性があります。自分専用の使用、または販売を考えている場合、この『リーク』はもちろんみなさんの利益になりません。

不正使用に対する保護のメカニズムは数多くあります。単純なシリアルナンバー作成機能からオンライン サービスおよび/または電子セキュリティキーを使用した保護まで。最後の方法はもっとも信頼性のあるものですが、同時にもっとも労力のかかるものでもあります。MetaTrader クライアントターミナルには独自の特別な特性があり、それにより保護仕様のオブジェクトと共によりシンプルでありながら信頼性のある方法を使用することができるものです。

実際、自分のExpert Advisor やインディケータを提供したり販売するトレーダーのためにのみ動作するようにする必要があります。所有者を確実に特定するには、各ユーザーに対して完全にユニークな事柄が一つあります。それは作業アカウントナンバーです。そしてトレードサーバー名と併せて、それは Expert Advisor 所有者の完全にユニークな『電子パスワード』となるのです。

以下はこの保護スキームを実装するコードのシンプルな例です。

//+------------------------------------------------------------------+
//|                                                  Protect-004.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start()
{
  string char[256]; int i;

  for (i = 0; i < 256; i++) char[i] = CharToStr(i);
  // Account number, on which expert is allowed to work
  int    AllowedAccountNo = StrToInteger(/* 49153 */ char[52]+char[57]+char[49]+char[53]+char[51]);
  string AllowedServer = /* UWC-Demo.com */ char[85]+char[87]+char[67]+char[45]+char[68]+
  char[101]+char[109]+char[111]+char[46]+char[99]+char[111]+char[109];

  if (AccountNumber() != AllowedAccountNo || AccountServer() != AllowedServer)
  {
    Print("You don't have permission to use this script!");
    return(1);
  }
  
  Print("You can use this script!");
}

ここで、アカウント番号とトレーダーサーバー名を暗号化された文字列として非表示にする以前の方法を使い、ex4 が別アカウントやサーバーで動作するよう『修正される』ことのないことを相対的に確認することができます。

そのような保護を行うこと(許可された購入者ごとにを毎回 Expert Advisor を再構築することや、エンコードされた文字列メカニズムを使うなんらかのユニバーサルな保護スキームを考え出すこと)は本稿の範囲を超えています。それにそのようなユニバーサルな保護ロジックについてオープンに話すことは安全ではありません。そうでなければ、それは開発者に対してだけでなく、クラッカーにも利用可能となります。われわれのプログラムをブレイクする人たちの仕事を容易にすることはありません。 



時間による保護

Expert Advisor を保護するもう一つ別の方法はその動作を時間で制限することです。任意のアカウントまたはサーバーで特定日付までのみ動作するようにすることが可能です。デモ期間が切れたら、Expert Advisor はもう動作せず、ユーバーは適切に保護されたバージョンのエキスパートを依頼する必要があります。

以下はこの保護メカニズムを持つスクリプトのテキストです。

//+------------------------------------------------------------------+
//|                                                  Protect-005.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start()
{
  string char[256]; int i;

  for (i = 0; i < 256; i++) char[i] = CharToStr(i);

  // Date, until which the expert is allowed to work
  int LastAllowedDate = StrToTime(
  /* 2009.09.11 23:59:00 */
  char[50]+char[48]+char[48]+char[57]+char[46]+char[48]+char[57]+char[46]+char[49]+
  char[49]+char[32]+char[50]+char[51]+char[58]+char[53]+char[57]+char[58]+char[48]+char[48]

  );

  if (TimeCurrent() >= LastAllowedDate)
  {
    Print("Demo period has expired " + TimeToStr(LastAllowedDate,TIME_DATE|TIME_SECONDS));
    return(1);
  }
  
  Print("You can work until "+ TimeToStr(LastAllowedDate,TIME_DATE|TIME_SECONDS));
}

それは、でも期間終了日を含み文字列の暗号化も使用しているため、ex4 ファイルを編集して『更新する』のは不可能です。



逆コンパイルからの保護

残念ながら、これら方法は、攻撃する人がエキスパートのソースコードにアクセスできない場合にしか正常に作用しません。作られたものはかならず壊される可能性があるものです。インターネット上で利用できるユーティリティがあり、それにより ex4 ファイルを逆コンパイルすることができるのです。その作成者はこのソフトウェアを保護し販売しています。

このユーティリティもクラックされたことがあり、今はそれを入手する人はだれでもエキスパートを逆コンパイルし、そのソースコードを入手することが可能です。この逆コンパイルされたコードに不要な変更を加え(たとえば、日付、アカウント、サーバーを解析するブロックを削除する)、それを再コンパイルし、みなさんの Expert Advisor の完全未保護バージョンを入手することが可能なのです。 

MQL4 コンパイラ作成者はこの問題と闘っています。この闘いはもちろん、決して発表されることはありません。ただ、残念ながら、ソースコードは頻繁に復元されます。ですが、そのテキストを読むのは困難です。意味のある名前の代わりにすべての識別子は機械的に作成された名前となっています。むろん、これはアルゴリズムを再考し再構築する過程をかなり複雑にします。多くの関数を伴う大きなファイルでは、それはほぼ解決不可能な問題となります。ただしエキスポートが小さい場合には、ほぼ元の条件に復元することが可能です。

そして、まずはププログラミング技術ありきです。保護システム作成者の仕事は(同時に逆コンパイラがどの形式でソースコードを復元するか知ったうえで)、攻撃者にとって、保護を見つけ出し無効化することがもっとも困難であるようにプログラムを書くことです。この部分は確かに詳述しません。ご自身でそのような保護方法を考え出す必要があります。

もっとも一般的にお薦めするのは、モジュール全体にセキュリティコードをちりばめることです。攻撃者はそのようなコードを解析するのに疲れるに違いありません。それでハッキングを台無しにすることを望まなくなるものです。制御変数の値はソースコードの異なる位置で収集される必要があります。そして、その箇所の疑惑が高いほど、これがセキュリティコードの一部であると考えるのが困難になります。

たとえば、終了日を組み立てるのは2つの部分に分けることができます。Expert Advisor の冒頭で年を設定し、月日と時刻はトレードシグナル計算中に追加するのです。違反の分析も一か所で行い、その結果におけるアクション(非常エグジットや機能低下)は別の場所にします。  

ex4 ファイルの逆コンパイラを出ることで変数名を復元することはできませんが、関数名を復元することは可能です。変数名とは異なり、それらはファイルに存在し、そこから逆コンパイラによって選択されるのです。よって、IsDemoMode() という関数を使用する場合、それによって保護をどこでオフにするか直接の指示を与えるのです。

以下の『誤り』のように日付でデモ期間を確認するようスクリプトをやや書き直す場合、

//+------------------------------------------------------------------+
//|                                                  Protect-006.mq4 |
//|                                Copyright © 2009, Sergey Kravchuk |
//|                                         http://forextools.com.ua |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start()
{
  string char[256]; int i;

  for (i = 0; i < 256; i++) char[i] = CharToStr(i);

  // Date, until which the expert is allowed to work
  int LastAllowedDate = StrToTime(
  /* 2009.09.11 23:59:00 */
  char[50]+char[48]+char[48]+char[57]+char[46]+char[48]+char[57]+char[46]+char[49]+
  char[49]+char[32]+char[50]+char[51]+char[58]+char[53]+char[57]+char[58]+char[48]+char[48]

  );

  if (IsDemoMode(LastAllowedDate))
  {
    Print("Demo period has expired " + TimeToStr(LastAllowedDate,TIME_DATE|TIME_SECONDS));
    return(1);
  }
  
  Print("You can work until "+ TimeToStr(LastAllowedDate,TIME_DATE|TIME_SECONDS));
}

bool IsDemoMode(int LastAllowedDate)
{
  if (TimeCurrent() >= LastAllowedDate) return(true); else return(false); 
}

逆コンパイラは以下の結果を出します。

#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start() {
   string lsa_0[256];
   for (int l_index_4 = 0; l_index_4 < 256; l_index_4++) lsa_0[l_index_4] = CharToStr(l_index_4);
   int l_str2time_8 = StrToTime(lsa_0[50] + lsa_0[48] + lsa_0[48] + lsa_0[57] + lsa_0[46] + 
      lsa_0[48] + lsa_0[57] + lsa_0[46] + lsa_0[49] + lsa_0[49] + lsa_0[32] + lsa_0[50] +
      lsa_0[51] + lsa_0[58] + lsa_0[53] + lsa_0[57] + lsa_0[58] + lsa_0[48] + lsa_0[48]);
   if (IsDemoMode(l_str2time_8)) {
      Print("Demo period has expired " + TimeToStr(l_str2time_8, TIME_DATE|TIME_SECONDS));
      return (1);
   }
   Print("You can work until " + TimeToStr(l_str2time_8, TIME_DATE|TIME_SECONDS));
   return (0);
}

bool IsDemoMode(int ai_0) {
   if (TimeCurrent() >= ai_0) return (TRUE);
   return (FALSE);
}

ごらんのように、日にちを持つ文字列はエンコードされ、一見、何がどのようにチェックされたかわかりません。このソースコードでは、IsDemoMode 関数のどこで何が編集されるかは明確であるため、この保護は無効です。



MQLEnigma -MQ4 ソースコードのエディタ

既存の逆コンパイラに対する闘いには、使用済み関数名の置換方法を身につける必要があります。これは MQL4 によっては実質的には不可能です(まあ、通常の名前をあきらかなゴミとコンテンツ交換すれば別ですが)。そこで私は VB.NET によってエンコーダプログラムを書く必要がありました。 

なぜ VB.NET なのでしょうか?過去数年、VBA や VB.NET で数多くのコーディングを行ってきただけで、そのためその助けを借りてこのタスクを速く簡単にやり遂げることができたのです。また、コンパイルはビジュアルスタジオ エクスプレスで行いました。それは完全無料です。

このプログラムを今後使用するにあたり、唯一の欠点は、システムに.NET FrameWork 3.5 をインストールする必要があることです。その相応な金額にもかかわらず、それはすでにシステムに最新のソフトウェアとともにインストールされている可能性があります。それは .NET に書かれていることが多く、それと共にインストールされます。お手持ちのシステムに .NET フレームワークがない場合は、ご自分でここからダウンロードし、インストール可能です。

MQLEnigma -コンソール アプリケーションです。必須パラメータがあります。それはエンコード対象ファイル名です。その後、以下の操作がテキストで行われます。

  1. 全 #include ファイルを挿入します。別の Expert Advisor の異なるファイルで使用されるグローバル変数がある場合は、1件の共通ファイルに集めなければなりません。置換はこの特別な Expert Advisor のみに影響し、その他は暗号化されていない名前を持つインクルードファイルを使用し続けます。

  2. 結果のトータルテキストからコメントをすべて切り捨てます(// int i=0;のようなものに出くわさないよう)。

  3. きれいにしたファイルを二分割します。関数本体(これらは個別に切り離し分析されます)、外部変数すべてと #define です(関数宣言と共に)。

  4. 外部テキストのブロックからインポートされる関数の記述はsべて削除します。その名前は外部から与えられエンコードできないのです。

  5. テキストの両ブロック(内部、外部)で int、string などのような共通タイプの記述を見つけます。これらタイプから変数初期化と配列次元を削除します。 

  6. #define セクションから #define キーワードとパラメータ設定を削除し、定義済み名のみを残します。また、予約キーワードも削除します(赤紫色の名前を誤ってゴミと置換することのないよう)。

  7. 結果、変数名、内部関数名、宣言済み定義名のみが残ります。これらの名前は、共通リストに集められます。そこから重複が取り除かれます(int i=0; のような記述は複数関数に出ます)。作成されたものは、置換用変数の『ゴミ』名で、定義されたものは最長のものからの置換を行うための見つけ出された識別子の長さです。それ以外は、str と str2str のような2つの変数の場合、長い方の str2str は誤った名前を持ち、その2つの str 『部分』がまず置き換えられます。

以上です。#includes がすべて挿入された Expert Advisor ファイルのきれいになったフルテキストは接尾辞Open を伴って個別のファイルに書き込まれます。その後、識別子が置換されます。一致する識別子名の表は接尾辞 Encodings を伴って別のファイルに書き込まれ、エンコードされたファイルは接尾辞 Encoded を伴って書き込まれます。コンパイルし結果の ex4 を配布の必要があるのはまさにこのファイルです。

新しい名前は好きなようにアセンブルすることが可能ですが、意味のないユニークなものでなければなりません。私は単純な方法を使いました。最大整数を取り、左から有効であるがコード 160(改行なしスペース)を持つ『非表示』文字に追加し、ゴミを増やすため、メインの数字の左右にランダムな数を追加しました。次の名前を作成する際は、前のメインの数字から1を引きました(名前のユニークさを確実にするため)。そしてそのあとゴミと非表示スペースが追加されます。

次のようにテキスト定数内の変数名を置換しないために、

Print(" LotSize = " + DoubleToStr(LotSize,2));

以下の技を使いました。変数を置き換える前に、各文字の後、定数内にコード3を持つ文字を挿入しました。それはキーボードで簡単にタイプでき、そのためテキストにはありません。"LotSize =" の結果、定数は "#L#o#t#S#i#z#e# #=# #"(ここで # はコード3を持つ文字を意味します) に変換しました。そのとき、文字列定数で LotSize を置換するサブストリングを検索する必要がある場合、私は単純にそれを見つけず、それは気づかないままとなります。変数がすべて置換されたら、単純に文字をコード3で区切り、元の文字列定数は復元されます。

前の例のテキストを置換したとき、変数はこのリストに従って見つけました(最初の数字-ソースコード内でインディケータ発見があった数)。

21      char             2114319876214748364748749 
6       i                1596751872214748364643597 
1       IsDemoMode       158651616521474836452710 
5       LastAllowedDate  3650920921474836448123

そうして以下のファイルを取得しました。

#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"
int start()
{
  string  2114319876214748364748749 [256]; int  1596751872214748364643597 ;
  for ( 1596751872214748364643597  = 0;  1596751872214748364643597  < 256;  1596751872214748364643597 ++)
  2114319876214748364748749 [ 1596751872214748364643597 ] = CharToStr( 1596751872214748364643597 );
  int  3650920921474836448123  = StrToTime(
  2114319876214748364748749 [50]+ 2114319876214748364748749 [48]+ 2114319876214748364748749 [48]+
  2114319876214748364748749 [57]+ 2114319876214748364748749 [46]+ 2114319876214748364748749 [48]+
  2114319876214748364748749 [57]+ 2114319876214748364748749 [46]+ 2114319876214748364748749 [49]+
  2114319876214748364748749 [49]+ 2114319876214748364748749 [32]+ 2114319876214748364748749 [50]+
  2114319876214748364748749 [51]+ 2114319876214748364748749 [58]+ 2114319876214748364748749 [53]+
  2114319876214748364748749 [57]+ 2114319876214748364748749 [58]+ 2114319876214748364748749 [48]+
  2114319876214748364748749 [48]
  );
  if ( 158651616521474836452710 ( 3650920921474836448123 ))
  {
    Print("Demo period has expired " + TimeToStr( 3650920921474836448123 ,TIME_DATE|TIME_SECONDS));
    return(1);
  }
  Print("You can work until "+ TimeToStr( 3650920921474836448123 ,TIME_DATE|TIME_SECONDS));
}
bool  158651616521474836452710 (int  3650920921474836448123 )
{
  if (TimeCurrent() >=  3650920921474836448123 ) return(true); else return(false);
}

そのようなソーステキストのエンコードには一つすばらしい特徴があります。Expert Advisor のソースコードを持っていますが、それを実行したくないとします。それでもここで、このエンコードされたテキストを提供できます。実際、ソースコードを提供しましたが、そのアルゴリズムの秘密は公開されていません。

その逆コンパイル後、以下のコードを取得します。

#property copyright "Copyright © 2009, Sergey Kravchuk"
#property link      "http://forextools.com.ua"

int start() {
   string lsa_0[256];
   for (int l_index_4 = 0; l_index_4 < 256; l_index_4++) lsa_0[l_index_4] = CharToStr(l_index_4);
   int l_str2time_8 = StrToTime(lsa_0[50] + lsa_0[48] + lsa_0[48] + lsa_0[57] + lsa_0[46] + 
      lsa_0[48] + lsa_0[57] + lsa_0[46] + lsa_0[49] + lsa_0[49] + lsa_0[32] + lsa_0[50] +
      lsa_0[51] + lsa_0[58] + lsa_0[53] + lsa_0[57] + lsa_0[58] + lsa_0[48] + lsa_0[48]);
   if (f0_1276(l_str2time_8)) {
      Print("Demo period has expired " + TimeToStr(l_str2time_8, TIME_DATE|TIME_SECONDS));
      return (1);
   }
   Print("You can work until " + TimeToStr(l_str2time_8, TIME_DATE|TIME_SECONDS));
   return (0);
}

bool f0_1276(int ai_0) {
   if (TimeCurrent() >= ai_0) return (TRUE);
   return (FALSE);
}

そこには意味のある名前はありません(予約済みの 'start' と標準関数名以外)。また、このシンプルな例をソートしても、数多くの変数を持つより複雑なテキストは完全に不十分です。ハッキングコストはひじょうに高いので、書いた人からExpert Advisor を購入する方が安価で簡単です。同時に公式のサポートも受けられます。



おわりに

正直、MQLEnigma は「エクストリームプログラミング」の最悪の慣例で作成されました。入力ソーステキストは構文的に『正しい』と私は思いました。たとえば、一致していない関数の括弧、変数名(int;)のないタイプ宣言、等はありません。アルゴリズムは『オン・ザ・フライ』で作成されました。私は最大プロジェクトを取り、不必要なものはすべて徐々に切り落とし、同時に結果のテキストを見ました。最終的に、変数名だけが残る必要があります。数多くの例外や潜在的エラー処理を入れなかったのはそのためです。

また、来たる MQL5 には逆コンパイルに対する保護機能があります。よってこの作業は MQL4 プログラムに対してのみ意味のあるものです。同様の理由で、VB.NET を選びました。このツール(より正確にはVBA)を使うことで、日々の仕事を行っています。そのため、私にとってはそれを利用することはより簡単で速く快適だったのです。

MQLEnigma 作業をプログラミングするこの不正確な方法にもかかわらず、私はまだ誤った処理をし、そのコンパイルがエラーにつながるようなソースコードに出くわしていません。ただしこれは、この方法が絶対的に正しいことを意味するものではありません。そのため、ソースコード全体を提供しているのです。正常に動作しないMQLEnigma を取得したなら、その原因をつきとめ、必要に応じてご自分で修正することができます(そうなったときは、本稿でお話した変更についてご一報をお忘れなくお願いします)。

本稿は保護のもっとも簡単な方法のみ考察していますが、それでもその方法はみなさんの開発を効果的に保護するものです。本稿の冒頭で述べたことに戻りますと、私が一番最初のライセンスFairWareの結論で書いたことと同じことが言えます。ご自分では考え出したり書いたりすることの決してなかったプログラムを書くことで私はみなさんの訳に立ってきました。これからはみなさんが可能な方法で私を助けてくださる番です。 :-)

MQLEnigma のソースコードにはいくつかデバッグ中に取得するテキストでは明らかでなかった論理エラーがある可能性があります。みなさんが見つけられた場合には、本稿添付のファイルを変更し、更新できるようご一報をお願いします。ハッキングの可能性なく公開可能な別の保護方法をご存じなら、コメントを残してください。私や MQL4 コミュニティの他のメンバーはみなさんの貢献に感謝します。

それでは最終結論です。ソースコード保護の話題はひじょうにやりがいのあるものです。秘密をすべて共有することはよい考えではありません。なぜならそれによって、潜在的な攻撃者に弱点を見せることになりからです。私が本稿を公表しようと思ったのは、ひとえにデコーダに対して新しい事柄がなにもないからです。それでも、これらは一番よく知られる保護の方法であり、ひじょうに効果的に作用し、特に MQL のプログラミング初心者にとっては有用でなものなのです。