using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Web; using System.Web.Caching; using System.Windows.Forms; using CsharpHttpHelper; using Newtonsoft.Json; using PCRobot.Entitys; using PCRobot.Pack; using PCRobot.PCWechat.Enterprise; using PCRobot.Utils; using static PCRobot.PCWechat.Routine.Wechat_Xiaoxie_Type; namespace PCRobot.PCWechat.Routine { public partial class Wechat_Xiaoxie : WechatRoutineBase { public Wechat_Xiaoxie(WechatUser User) : base(User) { } public delegate void OnEvent(string Name, string Message); public static OnEvent ClickEvent; #region 静态函数 public static void Install() { if (IsInstall) return; #region 自动登录新建设备信息,注册表开关 try { if (Version == "3.4.0.38") { string Winrarpath = @"Software\Tencent\WeChat"; string key = "FakeDeviceId"; //yes为开,no为关 RegistryHelper.SetRegistryKey("HKEY_CURRENT_USER", Winrarpath, key, "no"); RegistryHelper.GetRegistryValue(Winrarpath, key); } } catch (Exception ex) { LogHelper.GetSingleObj().Error("自动登录新建设备信息", $"注册表操作异常:{ex.Message} - {ex.StackTrace}"); } #endregion ClickEvent?.Invoke("开始登录", "正在检测已登录微信,请稍等...."); try { //Thread.Sleep(5000); //DllPath = HttpExtend.MapFile($"WeChatHelper_{Version}.dll", "Bin"); m_AcceptCallbackFunc = WxAcceptCallback; m_RecvCallbackFunc = WxRecvCallback; m_CloseCallbackFunc = WxCloseCallback; UseUtf8(); // 初始化Callback InitWeChatSocket(m_AcceptCallbackFunc, m_RecvCallbackFunc, m_CloseCallbackFunc); DllPath = HttpExtend.MapFile($"WeChatHelper_{Version}.dll", "Bin"); KillPc(true); } catch (Exception) { } finally { IsInstall = true; ClickEvent?.Invoke("登录完成", ""); } } private static string DllPath; /// /// 微信WeChatWin.dll基址 /// //private static IntPtr BaseAddress; public delegate void AcceptCallbackFunc(uint dwClientId); public delegate void RecvCallbackFunc(uint dwClientId, IntPtr intPtr, uint dwSize); public delegate void CloseCallbackFunc(uint dwClientId); private static AcceptCallbackFunc m_AcceptCallbackFunc; private static RecvCallbackFunc m_RecvCallbackFunc; private static CloseCallbackFunc m_CloseCallbackFunc; // 引入DLL导出函数 [DllImport("Bin\\WeChatServer.dll")] public static extern bool InitWeChatSocket(AcceptCallbackFunc acceptCallback, RecvCallbackFunc recvCallback, CloseCallbackFunc closeCallback); [DllImport("Bin\\WeChatServer.dll")] public static extern uint InjectWeChat(byte[] strDllPath); //[DllImport("Bin\\WeChatServer.dll")] //public static extern bool SetLoginWxid(byte[] szWxid); //BOOL __stdcall UseUtf8(); [DllImport("Bin\\WeChatServer.dll")] public static extern bool UseUtf8(); [DllImport("Bin\\WeChatServer.dll")] public static extern bool GetUserWeChatVersion(StringBuilder v); [DllImport("Bin\\WeChatServer.dll")] public static extern uint InjectWeChat2(byte[] dllPath, byte[] wechatPath); [DllImport("Bin\\WeChatServer.dll")] public static extern uint InjectWeChatMultiOpen(byte[] dllPath, byte[] wechatPath); [DllImport("Bin\\WeChatServer.dll", EntryPoint = "SendWeChatData")] public static extern bool _SendWeChatData(uint dwClienId, byte[] strJsonData); public bool SendWeChatData(uint dwClienId, string strJsonData) { try { if (WechatClient.IsDebug) LogHelper.GetSingleObj().Debug("调试发送", $"{dwClienId} -> {strJsonData}"); if (User != null && !string.IsNullOrEmpty(User.Wxid)) { var json = HttpExtend.JsonToDictionary(strJsonData); var type = json["type"].ToString(); MsgType msgType; if (!Enum.TryParse(type, out msgType)) return false; switch (msgType) { //截取发送消息 - 为是否是辅助输入提供判断 case MsgType.MT_SEND_TEXTMSG: case MsgType.MT_SEND_CHATROOM_ATMSG: case MsgType.MT_SEND_CARDMSG: case MsgType.MT_SEND_XMLMSG: case MsgType.MT_SEND_IMGMSG: case MsgType.MT_SEND_FILEMSG: case MsgType.MT_SEND_VIDEOMSG: case MsgType.MT_SEND_GIFMSG: { json = json["data"] as Dictionary; string to_wxid = json["to_wxid"].ToString(); string message = string.Empty; if (json.ContainsKey("content")) message = json["content"].ToString(); else if (json.ContainsKey("card_wxid")) message = json["card_wxid"].ToString(); else if (json.ContainsKey("xml")) message = json["xml"].ToString(); else if (json.ContainsKey("file")) message = json["file"].ToString(); if (!string.IsNullOrEmpty(message)) Common.SetCache(User.Wxid, to_wxid, message); } break; } } return _SendWeChatData(dwClienId, Encoding.UTF8.GetBytes(strJsonData)); } catch (Exception ex) { LogHelper.GetSingleObj().Error(new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, $"{ex.Message} - {ex.StackTrace}"); } return false; } //[DllImport("Bin\\WeChatServer.dll")] [DllImport("Bin\\WeChatServer.dll")] public static extern bool DestroyWeChat(); [DllImport("Bin\\WeChatServer.dll")] public static extern uint InjectWeChatPid(int dwPid, byte[] dllPath); /// /// 卸载安装 /// public static void UnInstall() { try { DestroyWeChat(); LogHelper.GetSingleObj().Info(new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, "卸载成功"); } catch (Exception ex) { LogHelper.GetSingleObj().Error(new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message); } } #region 微信版本基础变量 //private const string Version = "2.9.5.41"; //private const int PcOffSet = 0x1769E00;//2.9.5.41 //private const string PcMd5 = "194F44DF80553326711A4F576FE7166E";//2.9.5.41 //private const string Version = "3.3.0.93"; //private const int PcOffSet = 0x1DAEB90;//3.3.0.93 //private const string PcMd5 = "5EE8A5B9D4EE63BE1813632D8A7B2E77";//3.3.0.93 private const string Version = "3.4.0.38"; private const int PcOffSet = 0x1DEE968;//3.4.0.38 private const string PcMd5 = "AB0916C9949178A786192B188892AE2C";//3.4.0.38 #endregion /// /// 杀死注入 pc /// /// private static void KillPc(bool isInject = false) { Process[] MyProcesses = Process.GetProcesses(); var path1 = HttpExtend.MapPath("PCWechat"); var path2 = HttpExtend.MapPath("PCWechat\\" + Version); //var path3 = HttpExtend.MapPath("PCWechat\\" + "3.3.0.93");//退出上个版本的微信 foreach (Process MyProcess in MyProcesses) { try { var name = MyProcess.ProcessName.ToUpper(); if (name == "WECHAT" && MyProcess.MainModule.FileName.StartsWith(path1)) { try { #region 退掉这个版本的微信 //if (MyProcess.MainModule.FileName.StartsWith(path3)) //{ // try // { // LogHelper.GetSingleObj().Info("主动Q", "版本不对杀死进程:" + MyProcess.Id); // MyProcess.Kill(); // } // catch (Exception) // { } //} #endregion //判断微信版本 if (MyProcess.MainModule.FileName.StartsWith(path2)) { var id = MyProcess.Id; if (isInject) { var result = Task.Factory.StartNew(delegate { try { var WechatWinFile = HttpExtend.MapFile("WeChatWin.dll", $"PCWechat\\" + Version); var md5 = Common.GetMD5Hash(WechatWinFile); if (!File.Exists(WechatWinFile) || md5 != PcMd5.ToUpper()) { return false; } else { LogHelper.GetSingleObj().Info("系统", $"开始注入进程:{id}..."); uint uin = InjectWeChatPid(id, Encoding.UTF8.GetBytes(DllPath)); LogHelper.GetSingleObj().Info("系统", $"注入成功:{id},句柄ID:{uin}"); return true; } } catch (Exception) { } return false; }).Wait(30000); if (!result) { try { LogHelper.GetSingleObj().Info("系统c", "杀死进程:" + MyProcess.Id); MyProcess.Kill(); } catch (Exception) { } } } else { try { LogHelper.GetSingleObj().Info("主动d", "杀死进程:" + MyProcess.Id); MyProcess.Kill(); } catch (Exception) { } } Thread.Sleep(10); } } catch (Exception) { } } } catch (Exception ex) { LogHelper.GetSingleObj().Error(new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message); } } } public static uint StartWechat(string wxid, bool isError = false) { var path = string.Empty; var WechatWinFile = HttpExtend.MapFile("WeChatWin.dll", $"PCWechat\\" + Version); var md5 = Common.GetMD5Hash(WechatWinFile); if (!File.Exists(WechatWinFile) || md5.ToUpper() != PcMd5.ToUpper()) { if (isError) throw new Exception("易转发客户端微信版本不支持,请登录易转发端手动处理"); var rst = MessageBox.Show("您的微信版本暂时不支持,立即重新安装吗?", "版本不兼容", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (rst == DialogResult.Yes) { var f = new WechatUpdate(Version); f.ShowDialog(); if (!f.IsOk) return 0; } else return 0; } path = HttpExtend.MapFile("WeChat.exe", $"PCWechat\\" + Version); //WechatLoginHelper.BeginLogin(wxid); //var ss = SetLoginWxid(Encoding.UTF8.GetBytes("")); //返回dwClientId var pid = InjectWeChat2(Encoding.UTF8.GetBytes(DllPath), Encoding.UTF8.GetBytes(path)); //WechatLoginHelper.ClickLogin((int)pid); return pid; //return InjectWeChatMultiOpen(Encoding.UTF8.GetBytes(DllPath), Encoding.UTF8.GetBytes(path)); } /// /// 远程登录微信 /// public static List RemoteLoginCodes = new List(); /// /// 是否在获取二维码 /// private static string RemoteCache = "get_login_code_cache"; /// /// pc微信登录二维码 /// /// public static void LoginQrcode(string wxid, string ServerMsgID) { try { RemoteLoginCode result = null; try { StartWechat(wxid, true); } catch (Exception ex) { result = new RemoteLoginCode() { pid = -1, rType = RobotType.客户端微信, b64Md5 = ex.Message }; } if (result == null) { result = Task.Factory.StartNew(delegate () { var awaitTime = DateTime.Now.AddSeconds(10); do { Thread.Sleep(200); //Cache cache = HttpRuntime.Cache; //object item = cache[RemoteCache]; //if (item != null) //{ // cache.Remove(RemoteCache); // var r = item as RemoteLoginCode; // return r; //} if (CacheHelper.Exist(RemoteCache)) { CacheHelper.Remove(RemoteCache); var r = CacheHelper.Get(RemoteCache); return r; } } while (awaitTime >= DateTime.Now); return null; }).Result; } var socketClient = EasySoc.GetSocket(); var msg = new CommonResult(); msg.RobotUsername = string.Empty; msg.RobotUsernick = string.Empty; msg.RobotType = RobotType.客户端微信; msg.MsgId = ServerMsgID; msg.Cmd = PCRobotCMD.rcvLoginCode; msg.Data = result == null ? string.Empty : JsonConvert.SerializeObject(result); socketClient.Send(msg); } catch (Exception ex) { LogHelper.GetSingleObj().Error(new StackTrace().GetFrame(0).GetMethod().Name, ex.Message); } } /// /// 等待登录结果 /// public static Dictionary WaitLoginResult = new Dictionary(); /// /// 本地解密dat图片 /// /// /// /// public static string DecodeImage(string FileName, byte XorKey, string DecodeImagePath) { var data = File.ReadAllBytes(FileName); for (int i = 0; i < data.Length; i++) data[i] = Convert.ToByte(data[i] ^ XorKey); //var path = FileName.Replace(Path.GetFileName(FileName), Path.GetFileNameWithoutExtension(FileName) + ".jpg"); File.WriteAllBytes(DecodeImagePath, data); return DecodeImagePath; } /// /// 获取微信的uin的值 /// /// /// public static string GetUin(int pid) { try { Process[] processes = Process.GetProcesses(); foreach (Process process in processes) { if (process.Id == pid) { foreach (ProcessModule processModule in process.Modules) { if (processModule.ModuleName == "WeChatWin.dll") { //微信基址 var WeChatWinBaseAddress = processModule.BaseAddress; //Console.WriteLine("微信基址:\t" + "0x" + ((int)(processModule.BaseAddress)).ToString("X8") + Environment.NewLine); var WxNameAddress = WeChatWinBaseAddress + PcOffSet; var uinStr = Common.GetString(process.Handle, WxNameAddress, 4); //Console.WriteLine($"uinStr = {uinStr}"); return uinStr; } } break; } } } catch (Exception) { } return string.Empty; } #endregion } }