用QQ远程控制计算机(山寨版)

      有时候我总苦于在两台计算机之间奔波,而中国的IP又是如此的金贵以至于你压根别想远程连接到你的PersonalComputer上。一两年前还可以用花生壳动态链到花生壳的客户端上,可是由于“有关部门”的一纸声明,域名不再是可以随便注册的了。中国互联网的冬天于是悄然来临。

      不扯这么多了,我们完全可以通过QQ远程控制自己的计算机,不过其中最大的问题还是那徽标类似于Linux却连API都不公开的公司了。无奈只有发扬我朝科技工作者伟大的山寨精神,寻求一点解决方案了。

      我的方案如下:

      你需要再注册一个账号,然后稍作处理,比如去掉各种状态切换,image 当然最重要的是image,这样你在给受控账号发消息的时候就会直接弹出一个窗口了。然后在你的主账号把受控账号加为好友,接下来就到了发挥我们伟大的山寨精神的时候了。

      你会发现每次弹出的窗口的位置是一样的,这样就方便了很多(当然如果不一样完全可以找到窗口的句柄再用客户区坐标操作,可以用Spy++模拟一下)。我们可以写一个程序,在后台一直启动一个守护进程,轮询地查找有没有QQ消息的弹出窗口,如果是从主账号发过来的,就模拟鼠标去点那些诸如“远程协助”“请求受控”之类的按钮,这样就华丽丽的完成了我们的工作,oh yeah.

      接下来我们用主账户向受控账户发一条消息,用Spy++看弹出窗口的属性,结果如下:

image

可以看到窗口的名称是你的主账号名,窗口的类是TXGuiFoundation,我们可以通过

HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName );

来查找窗口句柄,以确定是不是有窗口弹出,然后用

BOOL SetCursorPos( int x, int y ); 

VOID mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, DWORD dwExtraInfo );

模拟鼠标单击事件,具体代码如下

————————————————————————————————我是代码的分割线——————————————————————————————

    

#include <windows.h>
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
void Press(int x,int y);//点击一个按钮

#define QQName "布拉德比特"
#define QQClass "TXGuiFoundation"
#define Application 818,248
#define Assistance  832,291
#define Accept        918,608
#define DaemonTimer     1        //平时轮询的timer
#define WaitTimer    2        //申请受控的timer
#define WorkingTimer 3        //轮询受控是否完成的timer
#define Elapse        1000    //轮询的时间间隔
#define WaitTimeOut    5000    //等待主控同意的时间间隔
#define SleepDelay  500        //点击应用->协助的时延间隔
#define WaitDelay    5000    //点击同意->申请受控的时间间隔



int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("Daemon");
    HWND         hwnd;
    MSG          msg;
    WNDCLASSEX   wndclassex = {0};
    wndclassex.cbSize        = sizeof(WNDCLASSEX);
    wndclassex.style         = CS_HREDRAW | CS_VREDRAW;
    wndclassex.lpfnWndProc   = WndProc;
    wndclassex.cbClsExtra    = 0;
    wndclassex.cbWndExtra    = 0;
    wndclassex.hInstance     = hInstance;
    wndclassex.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclassex.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
    wndclassex.lpszMenuName  = NULL;
    wndclassex.lpszClassName = szAppName;
    wndclassex.hIconSm       = wndclassex.hIcon;

    if (!RegisterClassEx (&wndclassex))
    {
        MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, 
        szAppName, 
        TEXT ("WindowTitle"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        NULL, 
        NULL, 
        hInstance,
        NULL); 
    
    SetTimer(hwnd,DaemonTimer,Elapse,(TIMERPROC)WndProc);
    
    while (GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HWND handle=0;
    switch (message)
    {
    case WM_CREATE:
        return (0);
        
    case WM_TIMER:
        switch (wParam)
        {
        case DaemonTimer:
            handle=::FindWindow(QQClass,QQName);
            if(handle)//找到
            {
                Sleep(1000);//防止窗口弹得太慢....
                Press(Application);//按应用
                Sleep(SleepDelay);
                Press(Assistance);//按远程协助
                KillTimer(hwnd,DaemonTimer);//停止轮询,等待点受控
                SetTimer(hwnd,WaitTimer,WaitTimeOut,(TIMERPROC)WndProc);//等待主控机操作
            }
            return (0);
        case WaitTimer:
            KillTimer(hwnd,WaitTimer);//停止等待
            Press(Accept);//点接受
            Sleep(WaitDelay);
            Press(Accept);//点同意受控
            SetTimer(hwnd,WorkingTimer,DaemonTimer,(TIMERPROC)WndProc);
            return (0);
        case WorkingTimer:
            handle=::FindWindow(QQClass,QQName);
            if(!handle)//找不到了
            {
                KillTimer(hwnd,WorkingTimer);
                SetTimer(hwnd,DaemonTimer,Elapse,(TIMERPROC)WndProc);//正常轮询
            }
            return (0);
        }

    case WM_DESTROY:
        PostQuitMessage (0);
        return (0);
    }
    return DefWindowProc (hwnd, message, wParam, lParam);
}


void Press(int x,int y)
{
    SetCursorPos(x,y);//模拟鼠标移动
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);//模拟鼠标左键down
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//模拟鼠标左键up
}

这三个分别是三个按钮(应用,远程协助,和同意/申请受控)的位置(屏幕坐标)

Application 818,248
Assistance  832,291
Accept        918,608

我们可以写个程序去获取屏幕坐标,核心代码也只有这么一点

void CGetCursorDlg::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CString str;
    POINT point;
    GetCursorPos(&point);
    str.Format("x:%d y:%d",point.x,point.y);
    GetDlgItem(IDC_STATIC)->SetWindowText(str);

    CDialog::OnTimer(nIDEvent);
}

当然不要忘了把窗口置为最前

::SetWindowPos(GetSafeHwnd(),   HWND_TOPMOST,   0,   0,   0,   0,   (SWP_NOSIZE   |   SWP_NOMOVE)   );

程序文件也可以在http://g.zhubajie.com/urllink.php?id=9989557cd1u21u3n72xhh85下载

       这样我们的受控机登陆着受控QQ的账号,守护进程在后台运行,如果弹出“布拉德比特”的消息窗口,程序就会去点击应用\远程协助,之后等待5秒钟让你在主控机器上点击"接受",之后程序会依次点击“申请受控”和“同意”,这样就完成了一个完整的远程协助申请过程。记得退出的时候一定要通过关闭QQ窗口来退出,以使守护进程复位。

      OK,远程管理你的计算机吧~~

posted @ 2010-10-02 16:27  HarryChenThu  阅读(1047)  评论(1编辑  收藏  举报