Fork me on GitHub
QQ自动登录

再谈QQ自动登录(上)

 3年前曾经用C++写过一个QQ自动登录器,作为一个程序员新手的入门之作,其技术含量那是相当的低。最近回过头看了一遍以前的代码,心潮澎湃,于是按捺不住用流行的C#重新写了一遍,用意在于对比软件开发的趋势。
 c++版思路:
(1)启动QQ主程序
WinExec(strLoc,SW_HIDE); // strLoc为QQ程序地址
(2)找到登录窗口
pWnd = FindWindow(_T("#32770"), _T("QQ用户登录"));  
(3) 找到QQ号码输入窗口并输入号码 (利用剪切板复制粘贴QQ号码) 

 1CComboBox *pCob = (CComboBox *)pWnd->GetDlgItem(138);
 2 if (pCob)
 3 {
 4    //CString source;
 5    if(OpenClipboard())
 6    
 7      HGLOBAL clipbuffer;
 8      char *buffer;
 9      EmptyClipboard();
10      clipbuffer=GlobalAlloc(GMEM_DDESHARE,m_strCode.GetLength()+1);
11      buffer=(char *)GlobalLock(clipbuffer);
12      strcpy(buffer,LPCSTR(m_strCode));
13      GlobalUnlock(clipbuffer);
14      SetClipboardData(CF_TEXT,clipbuffer);
15      CloseClipboard();
16     }

17    pCob->SetCurSel(0);
18    pCob->DeleteString(0);
19    pCob->SendMessage(WM_PASTE, 00);
20}

(4)输入QQ密码(因为密码输入框不支持粘贴,模拟键盘输入密码)

 1        pCob = (CComboBox *)pWnd->GetDlgItem(0x3e95);
 2        if (pCob)
 3        {
 4            if (pCob->GetCurSel()==CB_ERR)
 5            {
 6            pCob->SetCurSel(0);
 7            }

 8        }

 9        
10        CWnd *pCwnd = pWnd->GetNextWindow(GW_CHILD);
11        pCwnd = pCwnd->GetNextWindow(GW_HWNDNEXT);
12        while (pCwnd != NULL)
13        {
14            if (pCwnd)//找到
15            {
16                CEdit *pPwd = (CEdit *)pCwnd->GetDlgItem(16038);
17                if (pPwd)
18                {
19                    char buf[20];
20                    memset(buf, 0sizeof(buf));
21                    int iRet = m_strPassword.GetLength();
22                    pPwd->SetSel(0-1);
23                    pPwd->Clear();
24
25                    i = 0;
26                    while (i < iRet)
27                    {
28                        pPwd->SendMessage(WM_CHAR, (WPARAM)m_strPassword.GetAt(i), 0);
29                        i++;
30                    }

31                    break;
32                }

33            }

34            pCwnd = pCwnd->GetNextWindow(GW_HWNDNEXT);
35        }

(5)模拟按下登录按钮

 1        CButton *pbtn = (CButton *)pWnd->GetDlgItem(324);
 2        if (pbtn)
 3        {
 4            if (QQInfo.type!=pbtn->GetCheck())
 5            {
 6            pbtn->PostMessage(WM_LBUTTONDOWN, 00);
 7            pbtn->PostMessage(WM_LBUTTONUP, 00);
 8            }

 9        }

10
11        CButton *pbtnLogin = (CButton *)pWnd->GetDlgItem(16032);
12        if (pbtnLogin)
13        {
14            pbtnLogin->PostMessage(WM_LBUTTONDOWN, 00);
15            pbtnLogin->PostMessage(WM_LBUTTONUP, 00);
16        }

以上代码大量用到了消息处理,用程序完全模拟了我们登录QQ的过程

再谈QQ自动登陆器:提供C#源码下载(下)

 上次提到的QQ自动登陆器C++版本,其技术太过低级,但是所用方法在其他的应用中作用强大,尤其是外挂程序。其实就QQ登录来说有其接口的,用C#代码描述就一条语句:
1Process.Start(qqPath, "/START QQUIN:" + strAcntNum + " PWDHASH:" + strAcntPsw + " /STAT:" + (blAcntSts ? "40" : "41"));
2
其中 qqPath为QQ程序路径,strAcntNum为QQ号码,strAcntPsw为QQ的Hash值,布尔类型blAcntSts为登录状态,即是否隐身。
    简单吧,看来QQ自动登陆器是没有技术含量了,今天就设计过程中的其他技术作一介绍:
(1)注册表中添加QQ程序路径和登陆器程序打开密码
 1        public static string SetQQRegistryValue(string key, object value)
 2        {
 3            RegistryKey pregkey = Registry.CurrentUser.OpenSubKey(Constants.STR_QQ_REG_PATH, true);
 4            if (pregkey == null)
 5            {
 6                pregkey = Registry.CurrentUser.CreateSubKey(Constants.STR_QQ_REG_PATH, RegistryKeyPermissionCheck.ReadWriteSubTree);
 7                pregkey.SetValue(key, string.Empty);
 8                pregkey.Close();
 9                return string.Empty;
10            }

11            else
12            {
13                pregkey.SetValue(key, value);
14                pregkey.Close();
15                return value.ToString();
16            }

17
18        }

19
20        public static string GetQQRegistryValue(string key)
21        {
22            RegistryKey pregkey = Registry.CurrentUser.OpenSubKey(Constants.STR_QQ_REG_PATH, true);
23            if (pregkey == null)
24            {
25                pregkey = Registry.CurrentUser.CreateSubKey(Constants.STR_QQ_REG_PATH, RegistryKeyPermissionCheck.ReadWriteSubTree);
26            }

27            object value = pregkey.GetValue(key);
28            pregkey.Close();
29            if (value == null)
30            {
31                return string.Empty;
32            }

33            else
34            {
35                return value.ToString();
36            }

37        }

38

(2)序列化QQ帐号信息到文件
 1public static List<QQAccount> Get(string path)
 2        {
 3            if (qqInfoList == null)
 4            {
 5                FileStream fs = null;
 6                try
 7                {
 8                    XmlSerializer xs = new XmlSerializer(typeof(List<QQAccount>));
 9                    fs = new FileStream(path, FileMode.Open, FileAccess.Read);
10                    qqInfoList = (List<QQAccount>)xs.Deserialize(fs);
11                    fs.Close();
12                    return qqInfoList;
13                }

14                catch
15                {
16                    if (fs != null)
17                        fs.Close();
18                    return null;
19                }

20
21            }

22            else
23            {
24                return qqInfoList;
25            }

26        }

27
28public static void Set(string path, List<QQAccount> qqList)
29        {
30            if (qqList == null)
31                throw new Exception("Parameter is null!");
32
33            FileStream fs = null;
34            try
35            {
36                XmlSerializer xs = new XmlSerializer(typeof(List<QQAccount>));
37                fs = new FileStream(path, FileMode.Create, FileAccess.Write);
38                xs.Serialize(fs, qqList);
39                fs.Close();
40            }

41            catch
42            {
43                if (fs != null)
44                    fs.Close();
45                throw new Exception("Xml serialization failed!");
46            }

47        }
(3)Hash处理登录密码
 1        public static string HashBase64(string str)
 2        {
 3            byte[] result = new byte[str.Length];
 4            try
 5            {
 6                MD5 md = new MD5CryptoServiceProvider();
 7                result = md.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));
 8                return Convert.ToBase64String(result);
 9            }

10            catch
11            {
12                return "";
13            }

14        }

15
如下提供源码下载,作的粗糙,原谅!如有更好的建议请留言!

源码下载

 

posted on 2010-06-30 11:43  HackerVirus  阅读(616)  评论(0编辑  收藏  举报