寫在前面:
.Net千人學習交流QQ群:137 696483 歡迎各位 從事.Net技術開發與研究的 園友加入!
1.本博文只是用來給大家參考,學習的,本人不建議大家去寫外掛破壞游戲,影響他人正常游戲體驗,以下暫稱“助手”。
2.本博文寫的比較菜,因為第一次寫,而且表達方面可能比較難理解。希望大家見諒。
3.本博文側重 描述一下 菜單的功能 和 內存 讀寫以及 一些 其他 注意事項,給大家以參考。
4.助手特性:
可以從服務器端控制 菜單 顯示文字,
控制菜單 功能快捷鍵 ,
控制菜單 功能是否啟用,
控制菜單 功能基址和偏移和寫入值,
控制菜單 功能實現方式(時鐘控制與否)
等..
助手效果:
登陸:
登陸成功效果:
正文:
1. 助手 菜單類 定義:
public partial class MenuFnClass { public delegate void fn(int bassaddress, int[] offsetlist, string value); fn fntemp; ///構造函數,傳入委托方法名 public MenuFnClass( fn fn1) { fntemp = fn1; } public string menuName=string.Empty;//功能名 public bool isMenuOpen=false;//菜單是否正在被使用 public bool isMenuVisiable=false;//菜單是否可用,控制標簽顯示與快捷鍵調用 public int baseAddress=0;//基址 public int[] multiLevel=null;//偏移隊列 public string value=string.Empty;//寫入值 public bool isUsetimer=false;//是否時鐘控制,,如果只需修改一次的功能,則不去除效果. 默認 假 public Label myLabel;//菜單標簽控件 public Keys myKeys;//快捷鍵 public void DoWork() { fntemp(baseAddress, multiLevel,value); } }
2.菜單 功能對象申明:
#region (功能)類定義/初始化 PRivate MenuFactory mnFactory;//從登陸類獲取 基址偏移解密密碼,并初始化菜單工廠類 private List<MenuFnClass> MenuList=new List<MenuFnClass>(); private ArrayList nameList =new ArrayList();//同房玩家昵稱數組 private ArrayList playIdList = new ArrayList();//同房玩家Id數組 private MenuFnClass CS_AntiReport;//防止舉報 private MenuFnClass CS_QuickAmo;//子彈加速 private MenuFnClass CS_SuperGun;//無限散彈 private MenuFnClass CS_SuperKnief;//刀加速 //private MenuFnClass CS_NoJingZi;//去除瞄準鏡 //private MenuFnClass CS_HuanDan;//換彈加速 private MenuFnClass CS_GaiVip;//模擬vip private MenuFnClass CS_GaiRank;//改等級 private MenuFnClass CS_GaiMing;//改游戲昵稱 private MenuFnClass CS_DuckModel;//鴨子模式 private MenuFnClass CS_MaxAmo;//無限子彈 private MenuFnClass CS_FangShan;//去除閃光彈效果 private MenuFnClass CS_HouZuo;//去除后座力 private MenuFnClass CS_ZhunXin; //準心 private MenuFnClass CS_MoNi;//盜名昵稱 private MenuFnClass CS_MoNi2;//模擬角色 //private MenuFnClass CS_KaiJing;//0秒開鏡 //private MenuFnClass CS_QieQiang;//狙擊切槍 //private MenuFnClass CS_AutoFire;//自動開火 private MenuFnClass CS_ShootDist_Add; private MenuFnClass CS_ShootDist_Des;//減少射程 private MenuFnClass CS_RandomMove;//視覺飛天 private MenuFnClass CS_PinbgMuBH;//屏幕不晃 private MenuFnClass CS_WuHouZuo;//無后座力 #endregion
3.
這邊我自己定義了一個 MenuFactory 類,用于 和數據庫交互 取菜單數據。
//請保留原文鏈接:http://www.companysz.com/SparkOng/p/4931550.html
/// <summary> /// 注意 要想實例化本幫助類,必須傳入正確參數。本幫助類解析加密基址字符串 /// </summary> public partial class MenuFactory { private string JieMiMiMa; /// <summary> /// 構造函數,存入基址解密密碼 /// </summary> /// <param name="keydata"></param> public MenuFactory(string keydata) { JieMiMiMa = keydata; } #region 數據庫相關 private string GetConStr() { return "server=.;database=DB_AVA_TEST;integrated security=true;"; } /// <summary> ///從數據庫獲取 【解密密碼keydata】解密數據 ,處理數據 ,直接返回類 供前臺調用 /// </summary> /// <returns></returns> public MenuFnClass GetOneMenu(int? mid, MenuFnClass.fn fn1) { MenuFnClass retMfc= new MenuFnClass(fn1); if (mid == null) { return retMfc; } // return des.DecryptDES(GetDESData(jzid), JieMiMiMa); SqlParameter[] spa = new SqlParameter[] { new SqlParameter("@tid",SqlDbType.Int,4), new SqlParameter("@tusername",SqlDbType.NVarChar,4000), new SqlParameter("@tpassWord",SqlDbType.NVarChar,4000) }; spa[0].Value = mid; spa[1].Value = Login_.login_name; spa[2].Value = Login_.login_pwd; DataSet dsTemp= DbHelperSQL.QueryProcedure("OFS_Get_ById_UserInfoDate", spa);//自定義存儲過程用于從DB取數據 if(dsTemp==null|| dsTemp.Tables[0].Rows.Count==0) { retMfc.isMenuVisiable = false; retMfc.menuName = "tip:function here locked"; } else { //驗證數據有效性? 取出時間參數校驗 DataTable dt=dsTemp.Tables[0]; //bool isok=CheckData(dt.Rows[0]["m"].ToString(),dt.Rows[0]["d"].ToString()); //if(!isok){ return null;} retMfc.baseAddress = Other.HexToInt(des.DESJIE(dt.Rows[0]["BASEADD"].ToString(), JieMiMiMa)); retMfc.isUsetimer=(dt.Rows[0]["ISTIMER"].ToString()=="1")?true:false; retMfc.menuName=dt.Rows[0]["MENUNAME"].ToString(); retMfc.value=dt.Rows[0]["WVALUE"].ToString();//可以不用從數據庫取 retMfc.multiLevel = Other.StringToIntSZ(des.DESJIE(dt.Rows[0]["OFFSETSLIST"].ToString(), JieMiMiMa), ','); //偏移字符串轉換為int[],偏移分隔符',',16進制字符串數組到整型數組 retMfc.isMenuVisiable = (dt.Rows[0]["ISUSED"].ToString() =="1") ? true : false; } return retMfc; } /// <summary> /// 時間校驗,同月,北京日-美國日 <2 /// </summary> /// <param name="strm"></param> /// <param name="strd"></param> /// <returns></returns> private bool CheckData(string strm,string strd) { //int mon = int.Parse(strm); //int day = int.Parse(strd); //if (mon == (DateTime.Now.Month + DateTime.Now.Month) && (DateTime.Now.Day - day) < 2) // { // return true; // } // return false; return true; } /// 根據基址編號id,用戶賬號密碼,從數據庫獲取 已開啟 的基址和偏移 ,返回數據 解密 ,進行數據是否過期驗證 private string GetDESData(int id) { return null; } #endregion }
4. 窗口 Load事件里 去 從數據庫 取菜單 數據 以及 助手 內存地址 等信息,做 初始化 操作。
Load事件里 補下一個 鍵盤hook 注冊代碼
KeyboardHook kh;//聲明為全局 kh = new KeyboardHook(); kh.SetHook(); kh.OnKeyDownEvent += kh_OnKeyDownEvent;
/// <summary> /// 主窗體Load事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Main_frm_vip_Load(object sender, EventArgs e) { try { timr_checkava.Start();//安全 timr_now.Start(); // Login_.Isused = Other.Checkmd5();//如果校驗MD5成功,改變改變量為 true // if (!Login_.Isused) { application.Exit(); return; } this.Text = "請求數據..."; lab_Msg.Text = "[Msg]請求數據..."; Thread tr_fillmenu = new Thread(new ThreadStart(FillMenuList));//開一個線程去 初始化 菜單 集合 tr_fillmenu.Start();// tr_fillmenu時鐘用于 動態從 menuList 菜單集合 里面去 顯示 菜單信息到 窗口。 }
}
//請保留原文鏈接:http://www.companysz.com/SparkOng/p/4931550.html
#region 菜單集合初始化/核心代碼 /// <summary> /// 核心代碼-填充菜單集 /// </summary> /// <returns></returns> private void FillMenuList() { MenuFactory mnFactory;//從登陸類獲取 基址偏移解密密碼,并初始化菜單工廠類 mnFactory = new MenuFactory(des.desjiemi(Login_.datakey));//初始化 從數據庫拿基址的幫助類
PMR = new ProcessMemoryReader(); PMR.ReadProcess = Other.GetAvAProcessId();//獲取游戲進程標識 CS_AntiReport = mnFactory.GetOneMenu(2, AntiReport); //26,參數1:菜單在數據庫的ID 參數2:專屬功能名 此處用到了 委托 CS_AntiReport.myKeys = Keys.NumPad8;//設定該項菜單 快捷鍵 CS_AntiReport.myLabel = lab_AntiReport;// 設定該項菜單 對應的label CS_AntiReport.myLabel.Text = CS_AntiReport.menuName;//設定該項菜單 對應的label的顯示文字 CS_TSRoom.isUsetimer = true; //true持續修改,默認為false;實際從數據庫取值判斷 設定該項功能 是否啟用時鐘 控制還是只執行一次 MenuList.Add(CS_AntiReport); //MenuList定義為 List<MenuFnClass> CS_QuickAmo = mnFactory.GetOneMenu(9, QuickAmo); // 子彈加速 CS_QuickAmo.myKeys = Keys.NumPad1; CS_QuickAmo.myLabel = lab_N1; CS_QuickAmo.myLabel.Text=CS_QuickAmo.menuName; MenuList.Add(CS_QuickAmo); CS_SuperGun = mnFactory.GetOneMenu(11,SuperGun);//N+彈 CS_SuperGun.myKeys = Keys.NumPad2; CS_SuperGun.myLabel = lab_N2; CS_SuperGun.myLabel.Text = CS_SuperGun.menuName; MenuList.Add(CS_SuperGun); CS_SuperKnief = mnFactory.GetOneMenu(13,SuperKnief);//右刀加速 CS_SuperKnief.myKeys = Keys.NumPad3; CS_SuperKnief.myLabel = lab_N8; CS_SuperKnief.myLabel.Text = CS_SuperKnief.menuName; MenuList.Add(CS_SuperKnief); //.....省略一些無關的 或 重復的代碼 Win32.Beep(833, 220);//菜單 初始化完畢, 聲音提示 ,都保存在集合里面}
/// <summary> /// 用于動態加載 菜單到 窗口 的時鐘 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timr_DisplayMenu_Tick(object sender, EventArgs e) { if (!IsInitDataOk) { this.Text = "繪制菜單..."; lab_Msg.Text = "[Msg]繪制菜單..."; lab_Msg.ForeColor = Color.Red; Thread.Sleep(300); JudegVisiable(); //根據 menulist 集合去 隱藏/顯示 功能對應的 label } else { this.Text = "Enjoy Ur Game!!"; lab_Msg.Visible = false; timr_main.Start(); } lab_Msg.Text = "[Msg]接收,解析數據..."; lab_Msg.ForeColor = Color.White; }
/// <summary> /// 初始化菜單項,不可用的設置不可見 或 杠線 /// </summary> private void JudegVisiable() { foreach(MenuFnClass mfc in MenuList) { if (mfc.myLabel == null) return; mfc.myLabel.Visible = true; if(!mfc.isMenuVisiable) { if (Login_.labelUnableStyle == "0") { mfc.myLabel.Font = new Font("宋體", 9, FontStyle.Strikeout); } else { mfc.myLabel.Visible = false; } } } }
#region 界面UI特效集合/UI代碼 /// <summary> /// 按下快捷鍵后的菜單效果以及聲音提示,參數1目標控件,參數2是否打開 /// </summary> private void AddEffect(Label lbl,bool isBeep=true) { lbl.Text = lbl.Text.ToString().Replace('關', '開').Replace("OFF", "ON").Replace("False", "True").Replace("F", "T"); lbl.ForeColor = Color.Red; if (isBeep) Win32.Beep(800, 180); } /// <summary> /// 按下快捷鍵后的菜單效果以及聲音提示,參數1目標控件 /// </summary> private void ClearEffect(Label lbl, bool isBeep = true) { lbl.Text = lbl.Text.ToString().Replace('開', '關').Replace("ON", "OFF").Replace("True", "False").Replace("T", "F"); lbl.ForeColor = Color.Lime; lbl.BackColor = Color.Transparent; if (isBeep) Win32.Beep(1000, 100); } #endregion
異常處理單元:
#region 異常統一處理/異常處理代碼 /// <summary> /// 該頁面統一 處理 提交錯誤信息到貼吧 /// </summary> private void ReportBug(string exceptionMsg) { timr_main.Stop(); uhelp.MyMsg("Sorry!An Exception Throwed!"); FRM_BUGREPORT fbg = new FRM_BUGREPORT(exceptionMsg); fbg.ShowDialog(); this.Hide(); } #endregion
5.助手 功能單元
//請保留原文鏈接:http://www.companysz.com/SparkOng/p/4931550.html
#region 外掛功能實現模塊/核心代碼 //QQ 844125365 /// <summary> /// 一秒子彈數(散彈數)子函數 /// </summary> private void SuperGun(int _baddress,int[] _offsetslist,string _value) { int address = PMR.ReadMultiLevelPointer(_baddress,4,_offsetslist); PMR.WriteByte(address,byte.Parse(_value)); } /// <summary> /// 子彈加速/左刀加速 /// </summary> private void QuickAmo(int _baddress, int[] _offsetslist, string _value) { int address = PMR.ReadMultiLevelPointer(_baddress, 4, _offsetslist); PMR.WriteFloat(address,float.Parse(_value)); //這兒也可以寫字節型 } /// <summary> /// 無限子彈子函數,0x6E9-701-g_AmoNum /// </summary> private void MaxAmo(int _baddress, int[] _offsetslist, string _value) { int address = PMR.ReadMultiLevelPointer(_baddress, 4, _offsetslist); PMR.WriteByte(address, byte.Parse(_value)); } //注: 這些參數都是 從數據里里 取出來的, 在 菜單 初始化 那里 進行了 配置復制 給對應的 菜單 對象。 //..........省略一些 無關 或 重復代碼
//<summary> //防閃 //</summary> private void FangShan(int _baddress, int[] _offsetslist, string _value) { int address = PMR.ReadMultiLevelPointer(_baddress, 4, _offsetslist); int tempBoxCount = PMR.ReadInt(address); if (tempBoxCount == 1) { PMR.WriteInt(address, int.Parse(_value)); } } //<summary> //后座 //</summary> private void HouZuo(int _baddress, int[] _offsetslist, string _value) { int address = PMR.ReadMultiLevelPointer(_baddress, 4, _offsetslist); int tempBoxCount = PMR.ReadByte(address); if (tempBoxCount > 0 && tempBoxCount<=255) { PMR.WriteByte(address, byte.Parse(_value)); } } //<summary> //準心 //</summary> private void ZhunXin(int _baddress, int[] _offsetslist, string _value) { int address = PMR.ReadMultiLevelPointer(_baddress, 4, _offsetslist); int tempBoxCount = PMR.ReadByte(address); if (tempBoxCount > 0 && tempBoxCount <= 255) { PMR.WriteFloat(address, float.Parse(_value)); } }
}
主要的助手 控制時鐘:
#region 主功能控制區/核心代碼 /// <summary> /// 主功能時鐘,動態調用功能 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void timr_main_Tick(object sender, EventArgs e) { ‘ foreach (MenuFnClass fn in MenuList)//該線程時鐘控制 無限子彈/N+彈/無后座 等等功能 { if (fn.isUsetimer && fn.isMenuOpen) { fn.DoWork(); } } }
補充一部分,上面忘記寫出來了:
全局快捷鍵 控制 功能 開關 以及效果顯示:
#region 全局快捷鍵/事件代碼 KeyboardHook kh; /// <summary> /// 鍵盤事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void kh_OnKeyDownEvent(object sender, KeyEventArgs e) {
tempKey = e.KeyData; try { foreach(MenuFnClass mfc in MenuList) { if (mfc.myKeys == Keys.None) return; if (e.KeyData == mfc.myKeys && mfc.isMenuVisiable) //isMenuVisiable控制熱鍵是否有效以及菜單小時與否 { if (mfc.isUsetimer)//用時鐘控制,則dowork()寫在時鐘函數里面 { //以下 給菜單 添加開/關效果 以及 改變 菜單 開/關狀態 if (!mfc.isMenuOpen) { AddEffect(mfc.myLabel); mfc.isMenuOpen = true; } else { ClearEffect(mfc.myLabel); mfc.isMenuOpen = false; } } else//不用時鐘控制,則dowork()執行一次,此處只顯示效果 { mfc.DoWork();//運用委托 觸發該 菜單內含的 功能。 AddEffect(mfc.myLabel); mfc.isMenuOpen = true; } } } } //------------------------------------- 功能控制 End------------------------------------- catch (Exception ex) { ReportBug(ex.ToString()); } } #endregion
尾記:
由于時間比較長了以及篇幅所限,暫時貼這么些關鍵代碼,可能比較亂,自己看源碼吧大家。
源代碼下載:
1.C# 讀寫遠進程 內存幫助類:http://www.companysz.com/SparkOng/p/4881072.html
2. 整個解決方案 源代碼寫的比較欄,有需要的 問我要把(QQ 844125365),就先不發出來獻丑了。主要的 代碼已經貼在上面了。
新聞熱點
疑難解答