D 的个人博客

全职做开源,自由职业者

  menu

破解QQ键盘保护的方法

调试环境:WinXP SP2 QQ2006 Beta2
调试工具:OnlyDBG

测试步骤:
1.进入QQ目录下,改名或者删除npkcrypt.sys文件。运行QQ,出现QQ键盘保护启动失败,先关了QQ。
2.运行OnlyDBG,打开LoginCtrl.dll。右键,然后查找,然后点当前模块中的名称(标签)。
3.找到npkcntc.#1导入函数,只要选择第一个就行了。然后按回车键,点弹出窗口里的,再回车。代码如下:


CODE:[Copy to clipboard]60A3F9A8   .  8BCE          mov     ecx, esi
60A3F9AA   .  E8 49050000   call    60A3FEF8  //检测npkcrypt.sys文件是否存在
60A3F9AF   .  85C0          test    eax, eax
60A3F9B1      74 0C         je     short 60A3F9BF  //关健点,改为jne,意思是npkcrypt.sys文件不存在的时跳转
60A3F9B3   . |FF15 E466A460 call    [<&npkcntc.#1>]               
60A3F9B9   . |8986 90010000 mov     [esi+190], eax
60A3F9BF   > \39BE 90010000 cmp     [esi+190], edi      
60A3F9C5   .  0F8E 88000000 jle     60A3FA53            
60A3F9CB   . |68 9E0B0000   push    0B9E                  //0B9E资源为显示鍵盘加密成功的字符。
60A3F9D0   . |8D8E 94010000 lea     ecx, [esi+194]
60A3F9D6   . |E8 5D1A0000   call    <jmp.&MFC42.#4160>
60A3F9DB   . |E8 BE1A0000   call    <jmp.&MFC42.#1168>
60A3F9E0   . |8B40 0C       mov     eax, [eax+C]
60A3F9E3   . |57            push    edi                          
60A3F9E4   . |6A 0C         push    0C                              
60A3F9E6   . |6A 0C         push    0C                              
60A3F9E8   . |6A 01         push    1                              
60A3F9EA   . |68 C13E0000   push    3EC1                        //注意这里的3EC1,加密正确显示的资源名,非常重要
60A3F9EF   . |50            push    eax                           
60A3F9F0   . |FF15 7C66A460 call    [<&USER32.LoadImageA>]         
60A3F9F6   . |8D7E 64       lea     edi, [esi+64]                   //健盘加密技术启运成功显示的图像
60A3F9F9   . |6A 00         push    0                                
60A3F9FB   . |8BCF          mov     ecx, edi                        
60A3F9FD   . |8986 88010000 mov     [esi+188], eax                 
60A3FA03   . |E8 11FAFFFF   call    60A3F419                     
60A3FA08   . |FF15 F066A460 call    [<&npkcntc.#9>]                 
60A3FA0E   . |85C0          test    eax, eax
60A3FA10   . |75 08         jnz     short 60A3FA1A
60A3FA12   . |6A 01         push    1
60A3FA14   . |FF15 E066A460 call    [<&npkcntc.#4>]                 
60A3FA1A   > |85FF          test    edi, edi
60A3FA1C   . |75 04         jnz     short 60A3FA22
60A3FA1E   . |33C0          xor     eax, eax
60A3FA20   . |EB 03         jmp     short 60A3FA25
60A3FA22   > |8B47 20       mov     eax, [edi+20]
60A3FA25   > |68 46080000   push    846
60A3FA2A   . |50            push    eax
60A3FA2B   . |FFB6 90010000 push    dword ptr [esi+190]
60A3FA31   . |FF15 EC66A460 call    [<&npkcntc.#5>]               
60A3FA37   . |85FF          test    edi, edi
60A3FA39   . |75 04         jnz     short 60A3FA3F
60A3FA3B   . |33C0          xor     eax, eax
60A3FA3D   . |EB 03         jmp     short 60A3FA42
60A3FA3F   > |8B47 20       mov     eax, [edi+20]
60A3FA42   > |6A 02         push    2
60A3FA44   . |50            push    eax
60A3FA45   . |FFB6 90010000 push    dword ptr [esi+190]
60A3FA4B   . |FF15 E866A460 call    [<&npkcntc.#10>]               
60A3FA51   . |EB 43         jmp     short 60A3FA96
60A3FA53   > \FF15 9460A460 call    [<&KERNEL32.GetLastError>]  //npkcrypt.sys文件不存在,跳到这里   
60A3FA59   .  E8 401A0000   call    <jmp.&MFC42.#1168>
60A3FA5E   .  8B40 0C       mov     eax, [eax+C]
60A3FA61   .  57            push    edi                             
60A3FA62   .  6A 0C         push    0C                              
60A3FA64   .  6A 0C         push    0C                              
60A3FA66   .  6A 01         push    1                              
60A3FA68   .  68 C23E0000   push    3EC2               // 改  注意这里是3ec2,错误的资源名,改成正确的资源名为3ec1
60A3FA6D   .  50            push    eax                             
60A3FA6E   .  FF15 7C66A460 call    [<&USER32.LoadImageA>]         
60A3FA74   .  8D7E 64       lea     edi, [esi+64]
60A3FA77   .  6A 01         push    1                              
60A3FA79   .  8BCF          mov     ecx, edi                     
60A3FA7B   .  8986 88010000 mov     [esi+188], eax                 
60A3FA81   .  E8 93F9FFFF   call    60A3F419                       
60A3FA86   .  68 9F0B0000   push    0B9F        //改 这里是0B9F,显示健盘加密失败的字符资源,前面为0b9e,改成0b9e
60A3FA8B   .  8D8E 94010000 lea     ecx, [esi+194]
60A3FA91   .  E8 A2190000   call    <jmp.&MFC42.#4160>
60A3FA96   >  E8 031A0000   call    <jmp.&MFC42.#1168>
60A3FA9B   .  8B40 0C       mov     eax, [eax+C]
60A3FA9E   .  6A 00         push    0                              
60A3FAA0   .  6A 10         push    10                             
60A3FAA2   .  6A 10         push    10                             
60A3FAA4   .  6A 01         push    1                                
60A3FAA6   .  68 C33E0000   push    3EC3                           
60A3FAAB   .  50            push    eax                           
60A3FAAC   .  FF15 7C66A460 call    [<&USER32.LoadImageA>]     
格式不好弄,大家凑合着看吧

有了上面的偏移量以及数据后,现在我们来用程序实现,这里给出C修改LoginCtrl.dll的源码:


CODE:[Copy to clipboard]#include <stdio.h>
#include <stdlib.h>

int main()
{
        char modification[1];
        FILE *f = fopen("E:\\QQ\\LoginCtrl.dll", "rb+"); //打开QQ目录下的LoginCtrl.dll文件
        fseek(f, 63921, SEEK_SET);                               //定位文件指针到63921(\xf9b1)
        modification[0] = 115;                                       
        fwrite(modification, sizeof(char), 1, f);              //修改为115(\x75)
         
                    //下面的道理相同,具体的offset请参看上面调试时候的数据
        fseek(f, 64105, SEEK_SET);
        modification[0] = 193;
        fwrite(modification, sizeof(char), 1, f);
        
        fseek(f, 64135, SEEK_SET);
        modification[0] = 158;
        fwrite(modification, sizeof(char), 1, f);

        fclose(f);
        return 0;
}
好了,用C,短短的几行代码就搞定了^^
好累,睡觉去咯。。。。
呼呼~~~~