技术背景:由于公司打卡功能深入了解,决定破解网络打卡,签到等功能。【模仿用户操作】
拓展:由此扩展出,可以登录诸多网站模仿用户行为爬去数据 筛选 提炼 选中结果
废话不多说,开启技术教程:
技术环境:通过VS创建winform窗体、主要自制浏览器实现访用户操作(主要控件: WebBrowser)
=============================
代码摘要:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Win32; using mshtml; namespace CardToH3C { //webB1:https://blog.csdn.net/zhichao2001/article/details/50388225 [ComVisible(true)] public partial class Form1 : Form { public Form1() { InitializeComponent(); } public string getTypeIDorName= ConfigurationManager.AppSettings["getTypeIDorName"]; string userName =ConfigurationManager.AppSettings["userName"]; string password = ConfigurationManager.AppSettings["password"]; /// <summary> /// 登陆 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { Login(); } public void Login() { this.Invoke(new MethodInvoker(() => { //点击登陆 HtmlElement btnAdd = (getTypeIDorName == "ID" ? webBrowser1.Document.GetElementById(ConfigurationManager.AppSettings["LoginID"]) : webBrowser1.Document.GetElementsByTagName(ConfigurationManager.AppSettings["LoginID"])[int.Parse(ConfigurationManager.AppSettings["LoginTagName"])]); if (btnAdd != null) { (getTypeIDorName == "ID" ? webBrowser1.Document.GetElementById(ConfigurationManager.AppSettings["userNameID"]) : webBrowser1.Document.GetElementsByTagName(ConfigurationManager.AppSettings["userNameID"])[int.Parse(ConfigurationManager.AppSettings["userNameTagName"])]).SetAttribute("value", userName); (getTypeIDorName == "ID" ? webBrowser1.Document.GetElementById(ConfigurationManager.AppSettings["passwordID"]) : webBrowser1.Document.GetElementsByTagName(ConfigurationManager.AppSettings["passwordID"])[int.Parse(ConfigurationManager.AppSettings["passwordTagName"])]).SetAttribute("value", password); btnAdd.InvokeMember("Click"); } else { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":未找到登陆按钮" + "\r\n") + textBox5.Text; } })); } /// <summary> /// 上班打卡 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { upclick(); } public void upclick() { this.Invoke(new MethodInvoker(() => { HtmlElement btnAdd = (getTypeIDorName == "ID" ? webBrowser1.Document.GetElementById(ConfigurationManager.AppSettings["upID"]) : webBrowser1.Document.GetElementsByTagName(ConfigurationManager.AppSettings["upID"])[ConfigurationManager.AppSettings["upTagName"]]); if (btnAdd != null) btnAdd.InvokeMember("Click"); else textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":未找到上班打卡按钮" + "\r\n") + textBox5.Text; })); } /// <summary> /// 下班打卡 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { downclick(); } public void downclick() { this.Invoke(new MethodInvoker(() => { HtmlElement btnAdd = (getTypeIDorName == "ID" ? webBrowser1.Document.GetElementById(ConfigurationManager.AppSettings["downID"]) : webBrowser1.Document.GetElementsByTagName(ConfigurationManager.AppSettings["downID"])[ConfigurationManager.AppSettings["downTagName"]]); if (btnAdd != null) btnAdd.InvokeMember("Click"); else textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":未找到下班打卡按钮" + "\r\n") + textBox5.Text; })); } #region 运行清理缓存 [DllImport("shell32.dll")] static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, ShowCommands nShowCmd); private void Form1_Load(object sender, EventArgs e) { SetAutoStar(); //AutoRunAfterStart(); chongzhi(); //自动登录 this.Invoke(new MethodInvoker(() => { zidongdaka(); })); //CancleAutoRun(); } public void chongzhi() { ///https://blog.csdn.net/threadroc/article/details/35991377 ShellExecute(IntPtr.Zero, "open", "rundll32.exe", "InetCpl.cpl,ClearMyTracksByProcess 255", "", ShowCommands.SW_HIDE); //## 这边把脚本错误的压制设置为true. webBrowser1.Url = new Uri(ConfigurationManager.AppSettings["LgionUrl"]); webBrowser1.ScriptErrorsSuppressed = true; webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated); } public enum ShowCommands : int { SW_HIDE = 0, SW_SHOWNORMAL = 1, SW_NORMAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, SW_SHOWDEFAULT = 10, SW_FORCEMINIMIZE = 11, SW_MAX = 11 } public void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e) { IHTMLWindow2 win = (IHTMLWindow2)webBrowser1.Document.Window.DomWindow; string s = @"function confirm() {"; s += @"return true;"; s += @"}"; s += @"function alert(str)"; s += @"{"; s += @"window.external.alertMessage(str);"; s += @"}"; win.execScript(s, "javascript"); webBrowser1.ObjectForScripting = this; } public void alertMessage(string s) { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "接收到alert消息:" + s + "\r\n") + textBox5.Text; //MessageBox.Show("接收到alert消息:" + s); //换成你自己想要执行的动作 } #endregion #region 开机启动 /// <summary> /// 写进注册表,以便开机启动 /// </summary> private void SetAutoStar() { try { string filepath = Assembly.GetExecutingAssembly().Location; string runName = Path.GetFileNameWithoutExtension(filepath); RegistryKey hkml = Registry.LocalMachine; RegistryKey runKey = hkml.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); runKey.SetValue(runName, filepath); runKey.Close(); textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":成功加入到注册表" + "\r\n") + textBox5.Text; } catch (Exception ex) { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":加入到注册表失败"+ ex.Message + "\r\n") + textBox5.Text; } } /// <summary> /// 取消开机启动,删除注册表中的值 /// </summary> public void CancleAutoRun() { try { string filepath = Assembly.GetExecutingAssembly().Location; string runName = Path.GetFileNameWithoutExtension(filepath); RegistryKey hkml = Registry.LocalMachine; RegistryKey runKeys = hkml.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true); runKeys.DeleteValue(runName); textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":成功取消注册表" + "\r\n") + textBox5.Text; } catch (Exception ex) { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":取消注册表失败" + ex.Message + "\r\n") + textBox5.Text; } } #endregion bool dkched = false; DateTime updt1 = DateTime.Now; DateTime updt2 = DateTime.Now; DateTime downdt1 = DateTime.Now; DateTime downdt2 = DateTime.Now; /// <summary> /// 自动打卡 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { zidongdaka(); } public void zidongdaka() { this.Invoke(new MethodInvoker(() => { if (dkched == false) { bool chaced = true; #region 检测数据真确性 string dt = textBox1.Text; string dt2 = textBox2.Text; string dt3 = textBox3.Text; string dt4 = textBox4.Text; if (DateTime.TryParse(dt, out updt1) == false || DateTime.TryParse(dt2, out updt2) == false || DateTime.TryParse(dt3, out downdt1) == false || DateTime.TryParse(dt4, out downdt2) == false) { MessageBox.Show("设置时间错误,例如:8:00"); chaced = false; } #endregion if (chaced) { button4.Text = "正在监控中..."; dkched = true; Thread td = new Thread(dk); td.Start(); } } else { MessageBox.Show("打卡监控中"); } })); } public bool updk = false; int fenzchaUP = 0; public bool downdk = false; int fenzchaDown = 0; bool chuci = true; //定时执行 01:00重置 public void dk() { while (true) { if (chuci) { Thread.Sleep(5000); chuci = false; Login(); } Thread.Sleep(60000); if (DateTime.Now.Minute == 0 && DateTime.Now.Hour == 1) { this.Invoke(new MethodInvoker(() => { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":初始化今天的打卡\r\n") + textBox5.Text; })); downdk = updk = false; //随机打卡时间 TimeSpan ts = updt2 - updt1; Double fzc = ts.TotalMinutes; Random rd = new Random(); fenzchaUP = rd.Next(1, Convert.ToInt32(fzc)); //随机打卡时间 TimeSpan ts2 = downdt2 - downdt1; Double fzc2 = ts2.TotalMinutes; Random rd2 = new Random(); fenzchaDown = rd2.Next(1, Convert.ToInt32(fzc2)); } //上班打卡 if (updk == false) { if (updt1.AddMinutes(fenzchaUP).Hour == DateTime.Now.Hour&& updt1.AddMinutes(fenzchaUP).Minute == DateTime.Now.Minute) { Login(); Random rd = new Random(); Thread.Sleep(rd.Next(3000, 5000)); upclick(); updk = true; this.Invoke(new MethodInvoker(() => { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":上班打卡成功\r\n") + textBox5.Text; })); } } //下班打卡 if (downdk==false) { if (downdt1.AddMinutes(fenzchaDown).Hour == DateTime.Now.Hour && downdt1.AddMinutes(fenzchaDown).Minute == DateTime.Now.Minute) { Login(); Random rd = new Random(); Thread.Sleep(rd.Next(3000, 5000)); downclick(); downdk = true; this.Invoke(new MethodInvoker(() => { textBox5.Text = (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":下班打卡成功\r\n") + textBox5.Text; })); } } } } /// <summary> /// 重置 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button5_Click(object sender, EventArgs e) { chongzhi(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { } /// <summary> /// 取消注册表 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button6_Click(object sender, EventArgs e) { CancleAutoRun(); } } }源码:
http://note.youdao.com/noteshare?id=946bad691c66fba81d0af49df57fc6dc&sub=9F95A0D86DA54A809B5E6FE6ABB1A980:
感谢技术提供者(WebBrowser):
https://blog.csdn.net/zhichao2001/article/details/50388225 https://blog.csdn.net/threadroc/article/details/35991377