English Русский Español Deutsch 日本語 Português
请保护好自己,开发员!

请保护好自己,开发员!

MetaTrader 4示例 | 8 四月 2016, 16:26
4 112 0
Sergey Kravchuk
Sergey Kravchuk

知识产权的保护依旧是个大问题。 本文对 MQL4 程序保护的基本原则进行阐述。 通过这些原则,你可以确保你所开发的成果不会被窃取,或至少能够让小偷的“工作”复杂化,以让他罢手。



简介

当我开始熟悉 MQL 时,透过 MQL 编程新手的玫瑰色屏幕,我看见了写着“各方面都要愉快”字样的图片: 我学会如何进行交易。 我很清楚应如何编写程序。 随后每一个成功运用程序的人,都从他们挣得的第一桶金里分一小部分给我,作为对我提供的高质量产品的嘉奖。

交易新手利用首笔 20 美元的保证金获得 5 美元利润后,便兴奋地转给了我 2 美元,而有交易老手则曾提取了 2 千美元并拿出 200 美元以表示对我的感谢。 一切都开诚布公: 我所做的工作无法由交易员完成,相比于不使用该方法,交易员可通过使用该方法更频繁/更简单/更持续地获得更多利润。 我们成功合作,获得了可按照权益分派的极佳财务成果。 我甚至为此发明了专用的分配术语- FairWare

尽管我首个工具下载量可观,我也对这些工具接受过多次问答和咨询,我却仅仅收到 3 美元的报酬,而客户很明确地引用了我的 FairWare 条件,试想我有多吃惊吧。 因此,鉴于使用我产品的匿名用户不怎么讲诚信,我决定至少要对任何在真实帐户上使用我的工具设定最低费用。

为此,我必须保护我的知识产权,并启用 Shareware原则。 随着我的工具愈发成熟,我就愈发有意愿保护它们,迄今为止,我已收集了一些行之有效的保护方法,决定与编写 MQL 代码的各位同僚分享。 我们所有人或多或少都使用了我在本文中早前描述过的方法。 关于这个问题的信息已收集在一处,肯定能够缓解你们的“保护烦恼”。

那么,开始吧:从简单到复杂...



保护字符串常量

你首先想要保护的 - 是版权。 不仅让你作为编写出很酷玩意的程序员而感到自豪,而且能确保用户有机会获得开发人员的反馈。 正如墨菲法则所说的,“你找到的每一个最后的错误,其实是倒数第二个,”且你很可能不会在测试期间出现问题,而另一个人则会发现你没遇到的问题。 在这种情况下,你需要让带有电邮或网址的文本字符串在显示于 Expert Advisor 的窗口内时保持不变。 看一个简单的代码:

//+------------------------------------------------------------------+
//|                                                  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 个可能的字符的字符串数组并在每个元素内填充对应的字符。 然后,我们用已编码文本替换初始字符串,该文本由终端窗口内的 Experts 选项卡日志内复制而来,并将其编译,随后我们便得到结果。

因此,内容被加密,我们无法查看我们已编码的字符串。 终于,内容一去不复返 - 仅剩下一组将内容从单独字符组合而来的指令。 剩余未加密的内容 - 是来自 #property 版权和 #property 链接的常量。 遗憾的是,它们无法被编码,因为它们设置为字符串,不允许进行代码组合。

因此,如果我们想要保护每个字符串免受 HEX 编辑器的可能变化影响,都可以通过这种方式进行编码。 你可以通过 Protect-002.mq4 脚本来对其加密。 使用这种组合时,你必须记住,这种操作会比较花时间。 因此,请勿将此类代码模块直接插入 expert 主体内,也不要在每次价格变动时频繁使用它们。 声明所需字符串变量已经足够,使用已编码的组合将其在指标 或 expert 初始化时进行初始化,然后使用这些变量。



防止未经授权使用

我们已保护了我们的版权,现在又有另一个问题了。 你的 Expert Adviser 可能会在你不知情的情况下被他人复制(例如,当你离开 DC 交易大厅的计算机时),并在稍后你不知情的情况下被使用。 如果你打算仅让自己使用 Expert Adviser,或打算出售 Expert Adviser,则这种“泄漏”肯定不是你乐见的。

有许多防止未经授权使用的保护机制:从简单的序列号生成器到使用在线服务及/或电子安全钥匙进行保护。 最后一个方法 - 最可靠但同时也是最耗费劳力的。 但是,MetaTrader 客户端拥有独有特性,这种特性和保护规范对象都允许我们使用更简单但同时也很可靠的方法。

实际上,你需要让你的 Expert Advisor 或指标的工作对象仅限于获得或购买你的 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 将不再运行,用户必须向你索要妥当保护的 Expert 版本。

以下是带有这种保护机制的脚本文本。

//+------------------------------------------------------------------+
//|                                                  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 文件来使其“更新”。



反向编译保护方法

遗憾的是,所有这些方法仅在攻击者没有 expert 源代码访问权限的情况下才有效。 但是,所有建立的事物都可以打破。 互联网上有一个可以反向编译 ex4 文件的实用程序。 这个作者已保护了其软件并正在将其销售出去。

但这款程序也已经被破解,现在任何设法获得这款程序的人都可以反向编译你的 expert 并获得其源代码。 可以对这个反向编译代码进行必要修改(例如,删除分析日期、帐户和服务器的块),重新对其编译并获得你 Expert Advisor 的完全不受保护版本。 

MQL4 编译器开发人员正疲于应对这个问题。 如何应对的细节当然不会公之于众。 但遗憾的是,源代码往往可以恢复。 尽管其文本很难读取:所有识别器而非有意义的名称会机械性地创建名称。 这使回顾和重建算法的过程大为复杂化。 在拥有多个函数的大文件内,这会成为几乎无法解决的问题。 但是,对于小型 expert 而言,它可以重新恢复至接近初始状态。

在此,首先要提到的是编程的技术。 保护系统开发人员的任务(已知反向编译器会以何种形式恢复源代码的情况下),是将保护系统按这种方式编写:让攻击者很难发现并禁用该系统。 这部分内容当然无法详细说明 - 你需要自行发明这种保护方法。

最普遍的推荐做法是,将安全代码遍布整个模组内。 攻击者一定会在分析你代码时感到精疲力尽,从而不会再想去入侵你的系统。 可控变量值必须在不同源代码的位置收集,位置越不受怀疑,攻击者越难以猜到这就是源代码的一部分。

例如,组合结束日期可分成两部分:设置 Expert Advisor 的开始年份,月份、日期和时间会在计算交易信号时添加。 违约分析也可以在一个位置完成,而针对其结果的行动(紧急退场或减少功能)则在另一个位置完成。  

现有的 ex4 文件反向编译器无法恢复变量名称,但可以恢复函数名称。 函数名称和变量名称不同,它们是通过 ex4 文件形式呈现,它们在 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 上进行大量的编码,在其帮助下,我得以快速简单地完成这项工作。 此外,编译工作在完全免费使用的 Visual Studio Express 内完成。

此程序未来用户唯一劣势在于 - 他们需要在他们的系统内安装 .NET FrameWork 3.5 。 但,除了其可观数量外,该程序可能已安装在带有现代化软件的系统内,这些软件经常编写在 .NET 上并随之一同安装。 如果你的系统内没有 .NET 框架,你可以从 此处 下载并自行安装。

MQLEnigma - 是一款控制台应用程序。 该程序有强制参数 - 用于编码的文件名。 此后,将对文本进行以下操作:

  1. 插入所有 #include 文件。 如果你拥有在其他 Expert Advisor 的不同文件内使用的全局变量,则必须将它们集中到一个共同文件内。 这样,更换只会影响这个特定的 Expert Advisor,其他 Expert Advisor 则会继续使用包含了非加密名称的文件。

  2. 从得出的总文本中删除所有注释(不要遇到类似 // int i=0 的东西)。

  3. 将已清除的文本分成两部分:函数主体(它们被删除并单独分析),和所有外部变量和 #define(以及函数声明)。

  4. 从外部文本块中移除所有导入函数的描述。 它们由外部命名,无法被编码。

  5. 在两个文本块(外部和内部)中找到常用类型的描述,如 int, string 等等。 从这些类型中删除变量初始化和数组维度。 

  6. 从 #define 部分删除 #define 关键字和参数设置,从而仅留下已定义的名称。 同时删除已保留的关键字(即你不会不小心将洋红色名称更换为一些无用资料)。

  7. 因此,仅留下了变量名称、内部函数和已声明的常量。 这些名称将收入常用列表内,复制项目将从该列表中移除(如 int i=0; 这样的描述可在部分函数内发生)。 创建用于更换的“无用资料”变量名称并确定找到的识别器长度,从而从最长的那个开始执行更换。 否则,如果出现像 str 和 str2str 这样的两个变量,如果先更换两个 str “部分”的话,则最长的 str2str 的名称会出错。

就是这样:已清除的完整 Expert Advisor 文件文本插入了所有 #includes,按 开放 后缀形式写入单独文件。 随后更换识别器。 匹配识别器名称的表格将以 编码中 后缀形式写入单独文件中,已编码的文件以 已编码后缀形式写入。 后缀形式写入单独文件。 你需要编译此单独文件并分配得出的 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);
}

它的名称都毫无意义(除了保留的“开始”和标准函数名称外),尽管你可以挑选出这种简单的示例,但带许多变量的更复杂文本差得太远。 入侵成本太高了,而从开发者处购买 Expert Advisor 则更便宜和简单,且还能获得官方支持。



总结

老实说, MQLEnigma 是在极限编程最差劲的传统下开发出来的。 我假设输入的源文本在句法而言是“正确”的。 举例来说,函数和不含变量名称 (int;) 的类型声明等的括号必须正确匹配。算法已“飞速”开发 - 我边看着得出的文本,边进行了最大的项目并逐步删除所有不必要的东西, - 毕竟,仅保留变量名称是必须保留的。 这就是为什么我没有包含无数例外情况和可能出现错误的处理。

此外,即将到来的 MQL5 将拥有对反向编译的防护措施,因此这项工作仅对 MQL4 程序有意义。 基于同样原因,我选择了 VB.NET - 通过使用这个(更确切的说是 VBA)工具处理我每日的工作,因此对我来说驾驭这个工具会更加简单、快速和顺手。

尽管这个编程方式不尽准确,但 MQLEnigma 奏效了,我还未曾遇见被错误处理并且由编译导致错误的源代码。 但这并不意味着,这种方式就绝对正确。 这就是为何我要给出完整的源代码。 如果你的 MQLEnigma 不正确运作,则你要能够找出原因,并在必要时自行纠正错误(如果发生这种情况,请别忘记告诉我对本文讨论内容做出修改)。

本文仅讨论最简单的保护方法,但这些方法却可以有效保护你的开发产品。 回到我在本文开头写下的内容,我要说的与我在首次授权 FairWare时写下的内容一样: 开发者帮助过你编写你未曾自行开发或编写过的程序。 现在 - 轮到你来尽己所能,帮助开发者了 :-) 。

MQLEnigma 的源代码 可能包含部分在调试期间未出现在我文本中的逻辑错误。 如果你找到这些错误,请告诉我以便我进行修改并更新本文随附文件。 如果你了解其他可以公开发表而不会被黑客利用的保护方法,请留下你的评论。 我和我们 MQL4 社区内的其他成员都会对你的贡献深表感激。

最后的结论是:源代码保护这一主题非常有挑战性。 分享所有秘密不是个好主意,因为这么做的话你会向潜在攻击者展示你的弱点。 我决定发表这片文章,仅因为这对于解码者而言已屡见不鲜。 但是,这是最早为人所熟知的保护方法,非常有效,同时很管用,尤其对于 MQL 编程新手而言。

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1572

附加的文件 |
files_en.zip (29.18 KB)
金融证券的叠加和干扰 金融证券的叠加和干扰
随着影响货币对行为受到更多因素影响,评估其行为和对未来进行预测将愈发困难。 因此,如果我们成功提取货币对的组成部分,随时间改变的国家货币值,通过和带有此货币以及影响其行为的多个因素的货币对相比较,我们便可以相当程度上界定国家货币移动的自由度。 因此我们可以提高对其行为评估和未来预测的精准度。 如何办到?
Meta 交易者持仓报告 - 在 MetaTrader 4 中进行美国商品期货交易委员会报告分析的新领域 Meta 交易者持仓报告 - 在 MetaTrader 4 中进行美国商品期货交易委员会报告分析的新领域
本文关于在 MetaTrader 中使用美国商品期货交易委员会(CFTC)的报告数据。 文章详细描述了所讨论的 META 交易者持仓报告(COT)项目,展示了如何加载和处理必要的信息。 项目中包含的 Expert Advisor 将帮助我们分析文章中给出概念的有效性。 最后,我们将得出一些结论并提供有用的建议。
交易者的工具箱: 设计指标 交易者的工具箱: 设计指标
本文主要介绍设计指标的主要任务,解决方案和自动化。
FANN2MQL 神经网络教学 FANN2MQL 神经网络教学
本文将利用一个简单的例子为你演示如何通过 FANN2MQL 来使用神经网络:教给神经网络一个简单的模式,然后测试它是否能够识别从未见过的模式。