[分享][笔记]现学现用之windbg的高级玩法外篇二:干掉QQProtect.sys
发点感慨,牛就是牛,我等只能望其相背。
知道大家懒(其实是我比较懒
),查了半天windbg的帮助手册,解释一下此文中一些不明觉厉的地方。
首先是传送门,本文需要结合ddlx牛的这篇文章看:
http://bbs.pediy.com/showthread.php?t=179566
对了,one more thing,fcitx码字不容易,错别字请见谅。
原文:
0: kd> r @$t0=@@(#FIELD_OFFSET(nt!_EPROCESS, ThreadListHead))
解释:
指令解释:将t0寄存器设置为ThreadListHead在EPROCESS中的偏移
参考windbg帮助Debuggers>Debugger Reference>Syntax Rules>Numerical Expression Syntax>C++ Numbers and Operators节
1.#FIELD_OFFSET
#FIELD_OFFSET(Type, Field) 返回Field域成员相对于Type的偏移
2.@@()
主要是针对数值的,windbg对待numeric数据有几种不同的方式,默认是c++模式,当然还有masm模式。
@@()的作用为,以当前模式之外的另外一种模式对待当前置。说人话就是如果当前是c++模式,那么所有数值都是按照c++模式的解析方式解析的,如果我希望以masm模式解析,就需要将数值用@@(xxxx)括起来。
3.@$t0
参考windbg帮助Debuggers>Debugger Reference>Syntax Rules>Numerical Expression Syntax>Pseudo-Register Syntax
其实可以省略@符号,但是速度会降低。@$告诉windbg,t0为一个寄存器。好像有10个用户可自定义的寄存器@$t0 --- @$t9
原文:
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"解释:
1.!list,windbg对linked list这一数据结构专门的支持命令。用于遍历链表中的每一个节点
2.@$extret寄存器,存储链表每一个节点的入口地址,如果 -x参数中不出现这个寄存器,则默认添加到-x指令的结尾。
上面的命令意义为:遍历System进程的线程结构,将线程的起始地址范围在0xeee0c000与0xeee36680之间则打印
ETHREAD结构地址($t3),递归打印ETHREAD Cid域内容,打印$t4地址处的符号信息($t4为线程函数地址)。
原文:
0: kd> r @$t0=eee33900; r @$t1=86699130; r@$t2=eee33800;?? ((nt!_KAPC*)@$t0)->Type=18;?? ((nt!_KAPC*)@$t0)->Size=sizeof(nt!_KAPC);?? ((nt!_KAPC*)@$t0)->Thread=@$t1;?? ((nt!_KAPC*)@$t0)->KernelRoutine=@$t2;?? ((nt!_KAPC*)@$t0)->Inserted=1;r @$t3=@@(&(((nt!_ETHREAD*)@$t1)->Tcb.ApcState.ApcListHead[0]));r @$t4=@@(&(((nt!_KAPC*)@$t0)->ApcListEntry));r @$t5=@@(((nt!_LIST_ENTRY*)@$t3)->Flink);?? ((nt!_LIST_ENTRY*)@$t4)->Flink=@$t5;?? ((nt!_LIST_ENTRY*)@$t4)->Blink=@$t3;?? ((nt!_LIST_ENTRY*)@$t5)->Blink=@$t4;?? ((nt!_LIST_ENTRY*)@$t3)->Flink=@$t4;?? ((nt!_ETHREAD*)@$t1)->Tcb.ApcState.KernelApcPending=1;
解释:
首先,我可不可以吐嘈一下这条命令真长。。。。。
格式化一下吧:r @$t0=eee33900; r @$t1=86699130; r @$t2=eee33800; ?? ((nt!_KAPC*)@$t0)->Type=18;//原文中在eee33900出写入了第一个线程的APC,所以这里是填充所需的数据结构 ?? ((nt!_KAPC*)@$t0)->Size=sizeof(nt!_KAPC); ?? ((nt!_KAPC*)@$t0)->Thread=@$t1;//ETHREAD ?? ((nt!_KAPC*)@$t0)->KernelRoutine=@$t2;//start address ?? ((nt!_KAPC*)@$t0)->Inserted=1; r @$t3=@@(&(((nt!_ETHREAD*)@$t1)->Tcb.ApcState.ApcListHead[0])); r @$t4=@@(&(((nt!_KAPC*)@$t0)->ApcListEntry)); r @$t5=@@(((nt!_LIST_ENTRY*)@$t3)->Flink); ?? ((nt!_LIST_ENTRY*)@$t4)->Flink=@$t5; ?? ((nt!_LIST_ENTRY*)@$t4)->Blink=@$t3; ?? ((nt!_LIST_ENTRY*)@$t5)->Blink=@$t4; ?? ((nt!_LIST_ENTRY*)@$t3)->Flink=@$t4; ?? ((nt!_ETHREAD*)@$t1)->Tcb.ApcState.KernelApcPending=1;
-0-,直接写内存果然V587....
原文:
0: kd> dps 80505450 l11c
解释:
其实,没啥好说的,dds的“马甲”,用于列出对应地址符号信息的,起始地址80505450,长度l11c。
话外音:让我想起了某位结合dps与治疗的强力猎人T.......
原文:
0: kd> bp nt!NtWaitForSingleObject ".if(@@(((nt!_KTHREAD*)@$thread)->Win32Thread)!=0){;}.else{gc;}"解释:
其实只有一个地方需要解释,$thread为预定义变量,参考windbg帮助Debuggers>Debugger Reference>Syntax Rules>Numerical Expression Syntax>Pseudo-Register Syntax
剩下的元命令和扩展命令请查阅windbg帮助手册吧,对应一下命令解释应该比较容易弄明白。
文中恢复QQProtect保护的地方,那些加加减减为内核中数据结构的操作。怎奈我等菜鸟对这些数据结构极为不熟悉,留给其他牛人去说明吧。
文中如果有错误的地方,请指出来。。。反正我也不会改,不要再憋坏了
