前阵子把QQ密码搞出来了,现在想复习下发现又生疏了,看来要写个文章利用看雪论坛帮自己保存下,特别是WinDbg的命令忘的太快了,恩要记下来了。
注:本文没有用到驱动来实现,也没有用到假界面这个方法,只是借助于WinDbg分析,代码是Ring3的,QQ版本是2011,版本号是1.65.2221.488即最新的版本beta 3.3
QQ密码框是靠不停的安装卸载钩子来实现密码保护的,这地球人都知道,主要的2个钩子是WH_DEBUG和WH_KEYBOARD_LL,但你断SetWindowsHookExA或者SetWindowsHookExW都是断不下来的,只能在QQ启动时断下来几个无关紧要的键盘钩子,那么WH_DEBUG和WH_KEYBOARD_LL这2个钩子从哪里来的,下面一步步分析:
1、毫无疑问QQ已经将代码进行了转移,但作为一个无壳无驱动的聊天程序,肯定还是要经过内核中的函数的,SetWindowsHookEx以及SetWindowsHook的内核函数都是Win32k!NtUserSetWindowsHookEx,它是在ShadowSSDT表中的。
2、开虚拟机,WinDbg连上,先将QQ打开停在登陆界面,这时候QQ内部就会不停的加载和卸载钩子,这是因为有定时器的缘故,后面再说。然后在WinDbg中Ctrl+Break,输入下面的命令
kd> !process 0 0 qq.exe
PROCESS 81a98260  SessionId: 0  Cid: 0640    Peb: 7ffdf000  ParentCid: 0540
    DirBase: 084001a0  ObjectTable: e12cb3b0  HandleCount: 280.
    Image: QQ.exe
找到qq的EPROCESS 为81a98260  
3、下断点:
     bu /p 81a98260  Win32k!NtUserSetWindowsHookEx
     则断在QQ的进程空间中,这就是加上/p的好处,详解参见帮助文档
4、输入命令 kb
kd> kb
ChildEBP RetAddr  Args to Child              
f8202d44 8053e638 00400000 0012f9a8 00000000 win32k!NtUserSetWindowsHookEx
f8202d44 7c92e4f4 00400000 0012f9a8 00000000 nt!KiFastCallEntry+0xf8
0012f980 1000a20c 100072e1 00400000 0012f9a8 ntdll!KiFastSystemCallRet
看见了吧 被我们纠出来了,分析堆栈结构
win32k!NtUserSetWindowsHookEx会返回到nt!KiFastCallEntry中而nt!KiFastCallEntry会调用sysexit返回到Ring3,返回Ring3的地址是7c92e4f4 
这是ntdll!KiFastSystemCallRet函数,只有一个指令是ret,这个函数又会返回到1000a20c 中,1000a20c 地址是QQ的TsSafeEdit.dat模块中
5、将断点清除,系统继续运行,用OD附加,来到1000a20c 处,往上看就会看到你想要的,如图:
    
    1125就是Win32k!NtUserSetWindowsHookEx在ShadowSSDT中的序列号,因为在ShadowSSDT中所以算函数表中的偏移要减0x1000,
    具体的原因请参见http://bbs.pediy.com/showthread.php?t=89407
6、1000A200就是QQ秘密调用生成WH_DEBUG和WH_KEYBOARD_LL钩子的地方,而且一直地址不变,始终是模块TsSafeEdit.dat的地址+A200,但这个地址一开始是没有代码的,QQ会用memcpy函数将代码复制过来执行,
    所以我们要Hook住memcpy,判断目标地址是不是TsSafeEdit.dat的地址+A200,然后再到这个1000A200进行猥琐,当然我这个是笨方法。。。
7、好了,怎么得到QQ密码的思路就出来了,
     (1)Hook住memcpy,判断目标地址是不是TsSafeEdit.dat的地址+A200,然后再那个地址写入mov eax,1 ret 18h,即成功的返回
      (2)加载我们自己的钩子来得到密码。。。。。。。。。不罗嗦了,都在代码里,以下QQ账号和密码的截图:
       
8、实际上QQ不停的加载和卸载钩子是SetTimer的缘故,只要Hook住SetTimer就可以了,Hook中判断句柄的窗口类型是不是Edit就可以了,但这种方法,WH_DEBUG和WH_KEYBOARD_LL的钩子还是存在的,得到的数据虽然不完全是按键数据,但又规律可循
9、附件中的工程编译出来的是DLL,用OD在程序载入点的时候加载DLL就可以了,写着玩的所以代码不规范。。。。,还有BUG,但基本思路就这样,另外如果想做成木马的话,
     还需要过360对QQ目录下的文件保护,保证在QQ启动的时候加载DLL,至于怎么过我就不透露了,另外如果用户是记住密码的,可以在将用户的db文件删除,这样用户
必须输入密码了,只想到这种,代码中获取QQ号是Hook住了明文处,恩 ,就这样了
HookQQ.rar