请教一下MT4的EA如何加密?
请教一下MT4的EA如何加密?如何加使用期限?
现在MT4的编译器已经很强了,反编译难度极高,不需要使用其他手段加密。
bool CheckDeadline() { datetime deadline=D'2017.12.31'; //截止日期 datetime st=TimeCurrent(); //服务器时间 if(st>deadline) { Alert("已经过期....联系QQ:xxxx xxxx"); return(true); //过期了 } return(false);//还没有过期 }
请教一下MT4的EA如何加密?如何加使用期限?
目前最新EX4可以直接用反编译工具转换出来 ,下面提供一个简单的办法如果防止EX4被反编译工具还原成MQ4,把这段 混淆 代码复制到你的MQ4里面 ,然后 在你的初始化函数OnInit() 里面加入INTX();这个代码就可以了。原理很简单,目前存在的反编译工具 功能不是很全面,只要你的代码里面 类 结构体,他就没办法还原,反编译工具失效!
#include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\ListView.mqh> #include <Controls\ComboBox.mqh> #include <Controls\SpinEdit.mqh> #include <Controls\RadioGroup.mqh> #include <Controls\CheckGroup.mqh> //+------------------------------------------------------------------+ //| defines | //+------------------------------------------------------------------+ //--- indents and gaps #define INDENT_LEFT (11) // indent from left (with allowance for border width) #define INDENT_TOP (11) // indent from top (with allowance for border width) #define INDENT_RIGHT (11) // indent from right (with allowance for border width) #define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width) #define CONTROLS_GAP_X (-10010) // gap by X coordinate #define CONTROLS_GAP_Y (10) // gap by Y coordinate //--- for buttons #define BUTTON_WIDTH (100) // size by X coordinate #define BUTTON_HEIGHT (20) // size by Y coordinate //--- for the indication area #define EDIT_HEIGHT (20) // size by Y coordinate //+------------------------------------------------------------------+ //| Class CPanelDialog | //| Usage: main dialog of the SimplePanel application | //+------------------------------------------------------------------+ class CPanelDialog : public CAppDialog { private: CEdit m_edit; // the display field object CButton m_button1; // the button object CButton m_button2; // the button object CButton m_button3; // the fixed button object CListView m_list_view; // the list object CRadioGroup m_radio_group; // the radio buttons group object CCheckGroup m_check_group; // the check box group object public: CPanelDialog(void); ~CPanelDialog(void); //--- create virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2); //--- chart event handler virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); protected: //--- create dependent controls bool CreateEdit(void); bool CreateButton1(void); bool CreateButton2(void); bool CreateButton3(void); bool CreateRadioGroup(void); bool CreateCheckGroup(void); bool CreateListView(void); //--- internal event handlers virtual bool OnResize(void); //--- handlers of the dependent controls events void OnClickButton1(void); void OnClickButton2(void); void OnClickButton3(void); void OnChangeRadioGroup(void); void OnChangeCheckGroup(void); void OnChangeListView(void); bool OnDefault(const int id,const long &lparam,const double &dparam,const string &sparam); }; //+------------------------------------------------------------------+ //| Event Handling | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CPanelDialog) ON_EVENT(ON_CLICK,m_button1,OnClickButton1) ON_EVENT(ON_CLICK,m_button2,OnClickButton2) ON_EVENT(ON_CLICK,m_button3,OnClickButton3) ON_EVENT(ON_CHANGE,m_radio_group,OnChangeRadioGroup) ON_EVENT(ON_CHANGE,m_check_group,OnChangeCheckGroup) ON_EVENT(ON_CHANGE,m_list_view,OnChangeListView) ON_OTHER_EVENTS(OnDefault) EVENT_MAP_END(CAppDialog) //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CPanelDialog::CPanelDialog(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CPanelDialog::~CPanelDialog(void) { } //+------------------------------------------------------------------+ //| Create | //+------------------------------------------------------------------+ bool CPanelDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2) { // if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) // return(false); //--- create dependent controls if(!CreateEdit()) return(false); if(!CreateButton1()) return(false); if(!CreateButton2()) return(false); if(!CreateButton3()) return(false); if(!CreateRadioGroup()) return(false); if(!CreateCheckGroup()) return(false); if(!CreateListView()) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the display field | //+------------------------------------------------------------------+ bool CPanelDialog::CreateEdit(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP; int x2=ClientAreaWidth()-(INDENT_RIGHT+BUTTON_WIDTH+CONTROLS_GAP_X); int y2=y1+EDIT_HEIGHT; //--- create if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,x1,y1,x2,y2)) return(false); if(!m_edit.ReadOnly(true)) return(false); if(!Add(m_edit)) return(false); m_edit.Alignment(WND_ALIGN_WIDTH,INDENT_LEFT,0,INDENT_RIGHT+BUTTON_WIDTH+CONTROLS_GAP_X,0); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button1" button | //+------------------------------------------------------------------+ bool CPanelDialog::CreateButton1(void) { //--- coordinates int x1=ClientAreaWidth()-(INDENT_RIGHT+BUTTON_WIDTH); int y1=INDENT_TOP; int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button1.Create(m_chart_id,m_name+"Button1",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button1.Text("Button1")) return(false); if(!Add(m_button1)) return(false); m_button1.Alignment(WND_ALIGN_RIGHT,0,0,INDENT_RIGHT,0); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button2" button | //+------------------------------------------------------------------+ bool CPanelDialog::CreateButton2(void) { //--- coordinates int x1=ClientAreaWidth()-(INDENT_RIGHT+BUTTON_WIDTH); int y1=INDENT_TOP+BUTTON_HEIGHT+CONTROLS_GAP_Y; int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button2.Create(m_chart_id,m_name+"Button2",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button2.Text("Button2")) return(false); if(!Add(m_button2)) return(false); m_button2.Alignment(WND_ALIGN_RIGHT,0,0,INDENT_RIGHT,0); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button3" fixed button | //+------------------------------------------------------------------+ bool CPanelDialog::CreateButton3(void) { //--- coordinates int x1=ClientAreaWidth()-(INDENT_RIGHT+BUTTON_WIDTH); int y1=ClientAreaHeight()-(INDENT_BOTTOM+BUTTON_HEIGHT); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button3.Create(m_chart_id,m_name+"Button3",m_subwin,x1,y1,x2,y2)) return(false); if(!m_button3.Text("Locked")) return(false); if(!Add(m_button3)) return(false); m_button3.Locking(true); m_button3.Alignment(WND_ALIGN_RIGHT|WND_ALIGN_BOTTOM,0,0,INDENT_RIGHT,INDENT_BOTTOM); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "RadioGroup" element | //+------------------------------------------------------------------+ bool CPanelDialog::CreateRadioGroup(void) { int sx=(ClientAreaWidth()-(INDENT_LEFT+INDENT_RIGHT+BUTTON_WIDTH))/3-CONTROLS_GAP_X; //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP+EDIT_HEIGHT+CONTROLS_GAP_Y; int x2=x1+sx; int y2=ClientAreaHeight()-INDENT_BOTTOM; //--- create if(!m_radio_group.Create(m_chart_id,m_name+"RadioGroup",m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_radio_group)) return(false); m_radio_group.Alignment(WND_ALIGN_HEIGHT,0,y1,0,INDENT_BOTTOM); //--- fill out with strings for(int i=0;i<4;i++) if(!m_radio_group.AddItem("Item "+IntegerToString(i),1<<i)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "CheckGroup" element | //+------------------------------------------------------------------+ bool CPanelDialog::CreateCheckGroup(void) { int sx=(ClientAreaWidth()-(INDENT_LEFT+INDENT_RIGHT+BUTTON_WIDTH))/3-CONTROLS_GAP_X; //--- coordinates int x1=INDENT_LEFT+sx+CONTROLS_GAP_X; int y1=INDENT_TOP+EDIT_HEIGHT+CONTROLS_GAP_Y; int x2=x1+sx; int y2=ClientAreaHeight()-INDENT_BOTTOM; //--- create if(!m_check_group.Create(m_chart_id,m_name+"CheckGroup",m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_check_group)) return(false); m_check_group.Alignment(WND_ALIGN_HEIGHT,0,y1,0,INDENT_BOTTOM); //--- fill out with strings for(int i=0;i<4;i++) if(!m_check_group.AddItem("Item "+IntegerToString(i),1<<i)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "ListView" element | //+------------------------------------------------------------------+ bool CPanelDialog::CreateListView(void) { int sx=(ClientAreaWidth()-(INDENT_LEFT+INDENT_RIGHT+BUTTON_WIDTH))/3-CONTROLS_GAP_X; //--- coordinates int x1=ClientAreaWidth()-(sx+INDENT_RIGHT+BUTTON_WIDTH+CONTROLS_GAP_X); int y1=INDENT_TOP+EDIT_HEIGHT+CONTROLS_GAP_Y; int x2=x1+sx; int y2=ClientAreaHeight()-INDENT_BOTTOM; //--- create if(!m_list_view.Create(m_chart_id,m_name+"ListView",m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_list_view)) return(false); m_list_view.Alignment(WND_ALIGN_HEIGHT,0,y1,0,INDENT_BOTTOM); //--- fill out with strings for(int i=0;i<16;i++) if(!m_list_view.ItemAdd("Item "+IntegerToString(i))) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Handler of resizing | //+------------------------------------------------------------------+ bool CPanelDialog::OnResize(void) { //--- call method of parent class if(!CAppDialog::OnResize()) return(false); //--- coordinates int x=ClientAreaLeft()+INDENT_LEFT; int y=m_radio_group.Top(); int sx=(ClientAreaWidth()-(INDENT_LEFT+INDENT_RIGHT+BUTTON_WIDTH))/3-CONTROLS_GAP_X; //--- move and resize the "RadioGroup" element m_radio_group.Move(x,y); m_radio_group.Width(sx); //--- move and resize the "CheckGroup" element x=ClientAreaLeft()+INDENT_LEFT+sx+CONTROLS_GAP_X; m_check_group.Move(x,y); m_check_group.Width(sx); //--- move and resize the "ListView" element x=ClientAreaLeft()+ClientAreaWidth()-(sx+INDENT_RIGHT+BUTTON_WIDTH+CONTROLS_GAP_X); m_list_view.Move(x,y); m_list_view.Width(sx); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnClickButton1(void) { m_edit.Text(__FUNCTION__); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnClickButton2(void) { m_edit.Text(__FUNCTION__); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnClickButton3(void) { if(m_button3.Pressed()) m_edit.Text(__FUNCTION__+"On"); else m_edit.Text(__FUNCTION__+"Off"); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnChangeListView(void) { m_edit.Text(__FUNCTION__+" \""+m_list_view.Select()+"\""); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnChangeRadioGroup(void) { m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_radio_group.Value())); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CPanelDialog::OnChangeCheckGroup(void) { m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_check_group.Value())); } //+------------------------------------------------------------------+ //| Rest events handler | //+------------------------------------------------------------------+ bool CPanelDialog::OnDefault(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- restore buttons' states after mouse move'n'click if(id==CHARTEVENT_CLICK) m_radio_group.RedrawButtonStates(); //--- let's handle event by parent return(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { ExtDialog.ChartEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ CPanelDialog ExtDialog; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void intX() { (ExtDialog.Create(0,"Simple Panel",0,50,50,390,200)); (ExtDialog.Run()); } //+------------------------------------------------------------------+
如果你的代码是普通的代码,没有类 结构体,那么你的代码可以直接被还原,就像 老版本EX4被 EX4-TO-MQ4 DECOMPILER 还原一样。
当然你的加入这段代码,也只能防止你的EX4不被工具还原成MQ4。纯EX4一样没办法防止被破解
破解可以直接修改EX4去掉EX4限制,这个目前没办法解决!唯一的办法把你的EA做成MQL5市场上的EA或者采用 DLL加密 ,目前已知MQ5的EA没办法破解,但是可以通过人工分析,OLLYDBG 调试重建出来代码,只是这个工作量惊人,比较费时费力,所以成本比较高!DLL加密 把核心代码写入DLL, 然后DLL加强壳(SHIELDEN和VMPROTECT、ZPROTECT),通过服务器验证,基本上就比较安全了。
你的代码里面加入了下面这段 混淆代码,破解者去人工OLLYDBG分析重建MQ4 基本上是不可能了!
推荐做成mql5市场EA,如果不方便做成市场EA,就把你EA加入混淆代码,至少你的策略源码MQ4 不会被人还原出来!!
目前最新EX4可以直接用反编译工具转换出来 ,下面提供一个简单的办法如果防止EX4被反编译工具还原成MQ4,把这段 混淆 代码复制到你的MQ4里面 ,然后 在你的初始化函数OnInit() 里面加入INTX();这个代码就可以了。原理很简单,目前存在的反编译工具 功能不是很全面,只要你的代码里面 类 结构体,他就没办法还原,反编译工具失效!
如果你的代码是普通的代码,没有类 结构体,那么你的代码可以直接被还原,就像 老版本EX4被 EX4-TO-MQ4 DECOMPILER 还原一样。
当然你的加入这段代码,也只能防止你的EX4不被工具还原成MQ4。纯EX4一样没办法防止被破解
破解可以直接修改EX4去掉EX4限制,这个目前没办法解决!唯一的办法把你的EA做成MQL5市场上的EA或者采用 DLL加密 ,目前已知MQ5的EA没办法破解,但是可以通过人工分析,OLLYDBG 调试重建出来代码,只是这个工作量惊人,比较费时费力,所以成本比较高!DLL加密 把核心代码写入DLL, 然后DLL加强壳(SHIELDEN和VMPROTECT、ZPROTECT),通过服务器验证,基本上就比较安全了。
你的代码里面加入了下面这段 混淆代码,破解者去人工OLLYDBG分析重建MQ4 基本上是不可能了!
推荐做成mql5市场EA,如果不方便做成市场EA,就把你EA加入混淆代码,至少你的策略源码MQ4 不会被人还原出来!!
谢谢,你给的方法很有价值
建立 客户端/服务端 (C/S),把策略写进服务器端,通过用户和密码验证,验证模块和与服务器端都写进服务器端里,这样即使EA的代码都开放,别人也难以破解,因为客户端什么都没有。我的外汇智能交易系统就是这样的,前端只是一个展现工具(参见www.chan138.com)。
请问有教程吗