首页 > QQ技巧 > 正文

使用windbg干掉QQ2013正式版 sp2 QQProtect.sys

时间:2013-10-10 10:41 作者:QQ地带 我要评论

今天与大家一起见证怎么废了QQProtect.sys。
 
环境:
QQ版本:2013正式版 sp2(8178)
调试工具:windbg 6.12
操作系统:xp sp3 32bit
其他工具:lordpe
 
一直很纳闷,你一个QQ干嘛还要上个保护驱动那?这种行为让楼主很不爽。已知QQProtect会启动内核线程、注册内核通知回调例程、SSDT hook, SSDTShadow hook, inline hook。
打算用 QQProtect来练练手,正好好久没玩内核了,快生疏了。
本篇共分为4部分:
1. kill 内核线程
2. 恢复SSDT hook,inline hook
3. 摘除内核通知回调例程
4. 恢复SSDTShadow hook
 
当然以上的操作都是使用windbg做的。一起来调戏QQProtect吧。
 
使用APC KILL内核线程
 
QQ的保护驱动创建了一些内核线程。楼主找到QQ的内核线程
获取system进程的EPROCESS地址
代码:
0: kd> !process 0 0 system
PROCESS 867b5830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 06ca0020  ObjectTable: e1002e40  HandleCount: 401.
    Image: System
在获取QQProtect驱动的起始地址和结束地址
代码:
0: kd> lm m qq*
start    end        module name
eee0c000 eee36680   QQProtect   (deferred)    
遍历进程的线程链,找到起始地址在QQProtect模块空间的线程
获取需要的字段在结构中的偏移
代码:
0: kd> r @$t0=@@(#FIELD_OFFSET(nt!_EPROCESS, ThreadListHead))
0: kd> r @$t1= @@(#FIELD_OFFSET(nt!_ETHREAD, ThreadListEntry))
0: kd> r @$t2=@@(#FIELD_OFFSET(nt!_ETHREAD, StartAddress))
遍历线程链,找到QQ的内核线程
代码:
0: kd> !list "-t nt!_LIST_ENTRY.FLink -e -x \"r @$t3=@$extret-@$t1; r @$t4= @$t3+@$t2; r @$t5=poi(@$t4);.if(@@((unsigned long)@$t5>(unsigned long)0xeee0c000 && (unsigned long)@$t5<(unsigned long)0xeee36680)){r @$t3;dt -b nt!_ETHREAD Cid. @$t3; dds @$t4 l1;}; \" 867b5830+@$t0"
 
r @$t3=@$extret-@$t1; r @$t4= @$t3+@$t2; r @$t5=poi(@$t4);.if(@@((unsigned long)@$t5>(unsigned long)0xeee0c000 && (unsigned long)@$t5<(unsigned long)0xeee36680)){r @$t3;dt -b nt!_ETHREAD Cid. @$t3; dds @$t4 l1;};  
$t3=86699130 //ETHREAD地址
   +0x1ec Cid  : 
      +0x000 UniqueProcess : 0x00000004 //进程ID
      +0x004 UniqueThread : 0x00000160  //线程ID
86699354  eee11a0c QQProtect+0x5a0c //线程的起始地址
 
r @$t3=@$extret-@$t1; r @$t4= @$t3+@$t2; r @$t5=poi(@$t4);.if(@@((unsigned long)@$t5>(unsigned long)0xeee0c000 && (unsigned long)@$t5<(unsigned long)0xeee36680)){r @$t3;dt -b nt!_ETHREAD Cid. @$t3; dds @$t4 l1;};  
$t3=862de020
   +0x1ec Cid  : 
      +0x000 UniqueProcess : 0x00000004 
      +0x004 UniqueThread : 0x00000164 
862de244  eee22626 QQProtect+0x16626
通过上面的查找,找到了两个QQProtect的内核线程。找到了线程,接下来该怎么办呢?我们知道用户态线程直接强杀就OK了,但是内核线程强杀是不行的。通常使用APC。使用APC机制结束掉线程。
找到方法,那下一步就是实施了。由于不能调用系统API构建APC,只能手动构建和插入APC了。
 
 
第一步先找一块用来构建APC的内存。就在QQProtect中找一处吧。
先看一下QQProtect模块的区段信息
代码:
0: kd> !dh -s eee0c000
 
SECTION HEADER #1
   .text name
   1B516 virtual size
     480 virtual address
   1B580 size of raw data
     480 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
68000020 flags
         Code
         Not Paged
         (no align specified)
         Execute Read
 
SECTION HEADER #2
  .rdata name
    3A8C virtual size
   1BA00 virtual address
    3B00 size of raw data
   1BA00 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
48000040 flags
         Initialized Data
         Not Paged
         (no align specified)
         Read Only
 
 
Debug Directories(1)
    Type       Size     Address  Pointer
    cv           8f       1e868    1e868    Format: RSDS, guid, 1, f:\qqprotectdrvbuild\qqbuilder_qd3.5.1_drv2.9\basic_qqprotectdrv_vob\qqprotectdrv\objfre_wxp_x86\i386\QQProtectSYS.pdb
 
SECTION HEADER #3
   .data name
    82AC virtual size
   1F500 virtual address
    8300 size of raw data
   1F500 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C8000040 flags
         Initialized Data
         Not Paged //不分页内存
         (no align specified)
         Read Write
 
SECTION HEADER #4
   INIT name
     CC6 virtual size
   27800 virtual address
     D00 size of raw data
   27800 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
E2000020 flags
         Code
         Discardable //可废弃的,初始化完成后,内核可以回收这块内存。
                                     //但是由于内核的页粒度为0x1000,INIT段的开始处一部分内存与.data段在同一块内存页中,那此段的前0x200个字节就是理想的APC数据块载体了
         (no align specified)
         Execute Read Write
 

标签: QQ2013
顶一下
(1)
50%
踩一下
(1)
50%

Google提供的广告