1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/f32test/plugins/version_1/virus/t_vshook.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,685 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// f32test\virus\t_vshook.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "t_vshook.h"
1.22 +#include <f32pluginutils.h>
1.23 +
1.24 +
1.25 +_LIT(KVirusScannerName, "This is a test virus scanner");
1.26 +
1.27 +
1.28 +/**
1.29 +Leaving New function for the plugin
1.30 +@internalComponent
1.31 +*/
1.32 +CTestVirusHook* CTestVirusHook::NewL()
1.33 + {
1.34 + return new(ELeave) CTestVirusHook;
1.35 + }
1.36 +
1.37 +
1.38 +/**
1.39 +Constructor for the plugin
1.40 +@internalComponent
1.41 +*/
1.42 +CTestVirusHook::CTestVirusHook()
1.43 + {
1.44 +// RDebug::Print(_L("EMaxClientOperations %d, size of CFsPlugin %d, iSignatureOffset %d"), EMaxClientOperations, sizeof(CFsPlugin), _FOFF(CTestVirusHook, iSignature));
1.45 + ASSERT(iSignature == 0);
1.46 + iSignature = 0x1234;
1.47 + }
1.48 +
1.49 +
1.50 +/**
1.51 +The destructor for the test virus scanner hook. This would
1.52 +not be a part of a normal virus scanner implementation as
1.53 +normal virus scanners cannot be unloaded - it must be
1.54 +provided in the test virus scanner server so that it can
1.55 +be tested with the F32 test suite.
1.56 +@internalComponent
1.57 +*/
1.58 +CTestVirusHook::~CTestVirusHook()
1.59 + {
1.60 + iFs.Close();
1.61 +
1.62 + for (TInt i = 0; i < iSignaturesLoaded; i++)
1.63 + {
1.64 + if (iKnownSignatures[i])
1.65 + {
1.66 + delete iKnownSignatures[i];
1.67 + }
1.68 + }
1.69 + ASSERT(iSignature == 0x1234);
1.70 + }
1.71 +
1.72 +/**
1.73 +Initialise the virus scanner.
1.74 +Reads the virus definition file and then waits for
1.75 +notification that files containing a virus have been
1.76 +detected.
1.77 +@internalComponent
1.78 +*/
1.79 +void CTestVirusHook::InitialiseL()
1.80 + {
1.81 + User::LeaveIfError(RegisterIntercept(EFsFileOpen, EPreIntercept));
1.82 + User::LeaveIfError(RegisterIntercept(EFsFileSubClose, EPostIntercept));
1.83 + User::LeaveIfError(RegisterIntercept(EFsFileRename, EPreIntercept));
1.84 + User::LeaveIfError(RegisterIntercept(EFsRename, EPreIntercept));
1.85 + User::LeaveIfError(RegisterIntercept(EFsDelete, EPreIntercept));
1.86 + User::LeaveIfError(RegisterIntercept(EFsReplace, EPreIntercept));
1.87 + User::LeaveIfError(RegisterIntercept(EFsReadFileSection, EPreIntercept));
1.88 +
1.89 + ReadVirusDefinitionFile();
1.90 + }
1.91 +
1.92 +/**
1.93 +Read the virus definition file C:\virusdef.txt and parse
1.94 +its contents. Any virus definitions found in that file
1.95 +are added to the KnownSignatures array so they can be
1.96 +used by the virus scanning hook.
1.97 +
1.98 +@internalComponent
1.99 +
1.100 +@return KErrNone if the file was read and parsed
1.101 +successfuly.
1.102 +*/
1.103 +TInt CTestVirusHook::ReadVirusDefinitionFile()
1.104 + {
1.105 + TInt r = iFs.Connect();
1.106 + if (r != KErrNone)
1.107 + return r;
1.108 +
1.109 + r = iFs.SetNotifyChange(EFalse); // Disable change notifications
1.110 + if (r != KErrNone)
1.111 + return r;
1.112 +
1.113 + //Open the virus definition file
1.114 + RFile vsDefFile;
1.115 + r = vsDefFile.Open(iFs, _L("C:\\virusdef.txt"), EFileShareAny);
1.116 + if (r != KErrNone)
1.117 + return r;
1.118 +
1.119 + TInt fileSize=0;
1.120 + r = vsDefFile.Size(fileSize);
1.121 + if (r != KErrNone)
1.122 + {
1.123 + vsDefFile.Close();
1.124 + return r;
1.125 + }
1.126 +
1.127 + HBufC8* defBuf=NULL;
1.128 +
1.129 + TRAP(r,defBuf = HBufC8::NewL(fileSize));
1.130 + if (r != KErrNone)
1.131 + {
1.132 + vsDefFile.Close();
1.133 + return r;
1.134 + }
1.135 +
1.136 + TPtr8 ptr(defBuf->Des());
1.137 + r = vsDefFile.Read(ptr);
1.138 + if (r != KErrNone)
1.139 + {
1.140 + delete defBuf;
1.141 + vsDefFile.Close();
1.142 + return r;
1.143 + }
1.144 +
1.145 + //Now parse the definition file, putting the definitions into the hook's
1.146 + //array of known virus signatures.
1.147 + TInt bytesParsed = 0;
1.148 + TInt stringBeginPos = 0;
1.149 + TInt stringEndPos = 0;
1.150 + TInt stringLength = 0;
1.151 + HBufC8* signatureBuf = NULL;
1.152 + while (bytesParsed < fileSize)
1.153 + {
1.154 + ptr.Set(defBuf->Des());
1.155 + ptr.Set(&ptr[bytesParsed], fileSize-bytesParsed, fileSize-bytesParsed);
1.156 + stringBeginPos = ptr.MatchF(_L8("startdef:*:enddef*"));
1.157 +
1.158 + if (stringBeginPos < 0)
1.159 + {
1.160 + break;
1.161 + }
1.162 +
1.163 + stringBeginPos += 9; //stardef:
1.164 + stringBeginPos += bytesParsed;
1.165 + ptr.Set(defBuf->Des());
1.166 + ptr.Set(&ptr[stringBeginPos], fileSize-stringBeginPos, fileSize-stringBeginPos);
1.167 + stringEndPos = ptr.MatchF(_L8("*:enddef*"));
1.168 +
1.169 + if (stringEndPos < 0)
1.170 + {
1.171 + break;
1.172 + }
1.173 +
1.174 + stringEndPos += 9; //stardef:
1.175 + stringEndPos += bytesParsed;
1.176 + stringLength = stringEndPos - stringBeginPos;
1.177 +
1.178 + ptr.Set(defBuf->Des());
1.179 + TRAP(r,signatureBuf = HBufC8::NewL(stringLength));
1.180 +
1.181 + TPtrC8 actualSig(ptr.Mid(stringBeginPos, stringLength));
1.182 +
1.183 + TPtr8 ptr2(signatureBuf->Des());
1.184 + ptr2.Append(actualSig);
1.185 + iKnownSignatures[iSignaturesLoaded] = signatureBuf;
1.186 + iSignaturesLoaded++;
1.187 +
1.188 + bytesParsed += 9; //startdef:
1.189 + bytesParsed += stringLength;
1.190 + bytesParsed += 9; //:enddef\n
1.191 + }
1.192 +
1.193 + //Cleanup
1.194 + delete defBuf;
1.195 + vsDefFile.Close();
1.196 +
1.197 + return r;
1.198 + }
1.199 +
1.200 +/**
1.201 +@internalComponent
1.202 +*/
1.203 +TInt CTestVirusHook::DoRequestL(TFsPluginRequest& aRequest)
1.204 + {
1.205 + TInt err = KErrNotSupported;
1.206 +
1.207 + TInt function = aRequest.Function();
1.208 +
1.209 + iDrvNumber = aRequest.DriveNumber();
1.210 +
1.211 + switch(function)
1.212 + {
1.213 + case EFsFileOpen:
1.214 + err = VsFileOpen(aRequest);
1.215 + break;
1.216 +
1.217 + case EFsFileSubClose:
1.218 + VsFileClose(aRequest);
1.219 + break;
1.220 +
1.221 + case EFsFileRename:
1.222 + case EFsRename:
1.223 + case EFsReplace:
1.224 + err = VsFileRename(aRequest);
1.225 + break;
1.226 +
1.227 + case EFsDelete:
1.228 + err = VsFileDelete(aRequest);
1.229 + break;
1.230 +
1.231 + case EFsReadFileSection:
1.232 + err = VsReadFileSection(aRequest);
1.233 + break;
1.234 +
1.235 + default:
1.236 + break;
1.237 + }
1.238 +
1.239 + return err;
1.240 + }
1.241 +
1.242 +
1.243 +/**
1.244 +@internalComponent
1.245 +*/
1.246 +TInt CTestVirusHook::VsFileOpen(TFsPluginRequest& aRequest)
1.247 + {
1.248 + TFileName fileName;
1.249 + TInt err = ValidateRequest(aRequest, fileName);
1.250 + if (err == KErrNone)
1.251 + {
1.252 + err = ScanFile(fileName);
1.253 + if (err != KErrNone)
1.254 + {
1.255 + // Clean the infected file
1.256 + CleanFile(fileName, EFileOpen);
1.257 + }
1.258 + }
1.259 +
1.260 + return err;
1.261 + }
1.262 +
1.263 +/**
1.264 +@internalComponent
1.265 +*/
1.266 +void CTestVirusHook::VsFileClose(TFsPluginRequest& aRequest)
1.267 + {
1.268 + TFileName fileName;
1.269 + TInt err = GetName(&aRequest, fileName);
1.270 + if(err == KErrNone)
1.271 + {
1.272 + err = ScanFile(fileName);
1.273 + if (err != KErrNone)
1.274 + {
1.275 + // Clean the infected file
1.276 + CleanFile(fileName, EFileClose);
1.277 + }
1.278 + }
1.279 + }
1.280 +
1.281 +/**
1.282 +@internalComponent
1.283 +*/
1.284 +TInt CTestVirusHook::VsFileRename(TFsPluginRequest& aRequest)
1.285 + {
1.286 +
1.287 + TInt err = VsDirRename(aRequest);
1.288 + if(err != KErrAccessDenied)
1.289 + {
1.290 + TFileName fileName;
1.291 + err = ValidateRequest(aRequest, fileName);
1.292 + if (err == KErrNone)
1.293 + {
1.294 + err = ScanFile(fileName);
1.295 + if (err != KErrNone)
1.296 + {
1.297 + // Clean the infected file
1.298 + CleanFile(fileName, EFileRename);
1.299 + }
1.300 + }
1.301 + }
1.302 +
1.303 + return err;
1.304 + }
1.305 +
1.306 +/**
1.307 +@internalComponent
1.308 +*/
1.309 +TInt CTestVirusHook::VsDirRename(TFsPluginRequest& aRequest)
1.310 + {
1.311 +
1.312 + TFileName fileName;
1.313 + TInt err = GetName(&aRequest, fileName);
1.314 + if(err != KErrNone)
1.315 + return(err);
1.316 +
1.317 + err = fileName.Find(_L("\\system\\lib\\"));
1.318 + if (err != KErrNotFound)
1.319 + {
1.320 + //Don't allow sys\bin to be ever renamed
1.321 + return KErrAccessDenied;
1.322 + }
1.323 + err = fileName.Find(_L("\\sys\\bin\\"));
1.324 + if (err != KErrNotFound)
1.325 + {
1.326 + //Don't allow sys\bin to be ever renamed
1.327 + return KErrAccessDenied;
1.328 + }
1.329 +
1.330 + return err;
1.331 + }
1.332 +
1.333 +/**
1.334 +@internalComponent
1.335 +*/
1.336 +TInt CTestVirusHook::VsFileDelete(TFsPluginRequest& aRequest)
1.337 + {
1.338 +
1.339 + TFileName fileName;
1.340 + TInt err = ValidateRequest(aRequest, fileName);
1.341 + return err;
1.342 + }
1.343 +
1.344 +/**
1.345 +@internalComponent
1.346 +*/
1.347 +TInt CTestVirusHook::VsReadFileSection(TFsPluginRequest& aRequest)
1.348 + {
1.349 +
1.350 + // The t_virus test uses a filename clean.txt, a read length of 8 and a read position of 0.
1.351 + TFileName fileName;
1.352 + TInt len;
1.353 + TInt pos;
1.354 +
1.355 + // test getting name on read file section intercept
1.356 + TInt err = GetName(&aRequest, fileName);
1.357 + if(err != KErrNone)
1.358 + {
1.359 + return(err);
1.360 + }
1.361 + TParse parse;
1.362 + parse.Set(fileName,NULL,NULL);
1.363 + TPtrC name = parse.Name();
1.364 + if(name.CompareF(_L("clean"))!=0)
1.365 + {
1.366 + return(KErrGeneral);
1.367 + }
1.368 + TPtrC ext = parse.Ext();
1.369 + if(ext.CompareF(_L(".txt"))!=0)
1.370 + {
1.371 + return(KErrGeneral);
1.372 + }
1.373 +
1.374 + // test getting read length and required file position on read file section intercept
1.375 + err = GetFileAccessInfo(&aRequest, len, pos);
1.376 + if(err != KErrNone)
1.377 + {
1.378 + return(err);
1.379 + }
1.380 + if ((len != 8) || (pos != 0))
1.381 + {
1.382 + return(KErrGeneral);
1.383 + }
1.384 +
1.385 + return KErrNone;
1.386 + }
1.387 +
1.388 +
1.389 +/**
1.390 +@internalComponent
1.391 +*/
1.392 +TInt CTestVirusHook::VirusScannerName(TDes& aName)
1.393 + {
1.394 + aName = KVirusScannerName;
1.395 + return KErrNone;
1.396 + }
1.397 +
1.398 +/**
1.399 +Reads the contents of the file passed in and checks
1.400 +whether it contains any of the specified virus
1.401 +signatures
1.402 +
1.403 +@return A value depending on whether a known virus is
1.404 +found within the file.
1.405 +
1.406 +@param aFile A CFileCB object which can be used to read the file.
1.407 +@internalComponent
1.408 +*/
1.409 +TInt CTestVirusHook::ScanFile(const TDesC& aName)
1.410 + {
1.411 +
1.412 + TInt r = KErrNone;
1.413 + TInt pos = 0;
1.414 + TInt size = 0;
1.415 +
1.416 + // Rename the file
1.417 + TPtrC tmpFile = _L("VS_RENAMED.VSH");
1.418 + TParse parse;
1.419 + parse.Set(aName, NULL, NULL);
1.420 + parse.Set(parse.DriveAndPath(), &tmpFile, NULL);
1.421 +
1.422 + r = iFs.Rename(aName, parse.FullName());
1.423 + if(r != KErrNone)
1.424 + return r;
1.425 +
1.426 + RFile file;
1.427 + r = file.Open(iFs, parse.FullName(), EFileRead);
1.428 + if(r == KErrNone)
1.429 + {
1.430 + r = file.Size(size);
1.431 + }
1.432 +
1.433 + //If the file size is 0, then the file
1.434 + //has just been created - so it can't contain
1.435 + //a virus.
1.436 + if(r != KErrNone || size == 0)
1.437 + {
1.438 + file.Close();
1.439 +
1.440 + // Rename the file back
1.441 + TInt err = iFs.Rename(parse.FullName(), aName);
1.442 + if(err != KErrNone)
1.443 + return err;
1.444 +
1.445 + return r;
1.446 + }
1.447 +
1.448 + do
1.449 + {
1.450 + r = file.Read(pos, iScanBuf);
1.451 +
1.452 + if (r != KErrNone)
1.453 + {
1.454 + break;
1.455 + }
1.456 +
1.457 + r = ScanBuffer();
1.458 + pos += iScanBuf.Length();
1.459 + } while ((r == KErrNotFound) && (iScanBuf.Length() == iScanBuf.MaxLength()));
1.460 +
1.461 + file.Close();
1.462 +
1.463 + // Rename the file back
1.464 + TInt err = iFs.Rename(parse.FullName(), aName);
1.465 + if(err != KErrNone)
1.466 + return err;
1.467 +
1.468 + if (r > 0)
1.469 + {
1.470 + //We've found an infection
1.471 + return KErrAccessDenied;
1.472 + }
1.473 + else
1.474 + {
1.475 + return KErrNone;
1.476 + }
1.477 + }
1.478 +
1.479 +/**
1.480 +Scans the internal buffer which has been loaded with fresh
1.481 +file contents, to see if it contains any known virus
1.482 +signatures.
1.483 +
1.484 +@return A value depending on whether a known virus signature
1.485 +is found within the buffer.
1.486 +
1.487 +@internalComponent
1.488 +*/
1.489 +TInt CTestVirusHook::ScanBuffer()
1.490 + {
1.491 + //Look through the internal buffer for all known virus signatures.
1.492 +
1.493 + TInt r;
1.494 + for (TInt i = 0; i < iSignaturesLoaded; i++)
1.495 + {
1.496 + r = iScanBuf.Find(iKnownSignatures[i]->Des());
1.497 +
1.498 + if (r != KErrNotFound)
1.499 + {
1.500 + return r;
1.501 + }
1.502 + }
1.503 + return KErrNone;
1.504 + }
1.505 +
1.506 +/**
1.507 +Validate that nobody is trying to touch the virus scanner files.
1.508 +
1.509 +@internalComponent
1.510 +
1.511 +@return A value depending on whethe the virus scanner files are
1.512 +being fiddled with.
1.513 +
1.514 +@param aDriveNum The drive number of the request which called into
1.515 +the test virus scanning hook.
1.516 +
1.517 +@param aName The full pathname of the file being accessed by the
1.518 +request to the file server hook.
1.519 +*/
1.520 +TInt CTestVirusHook::ValidateRequest(TFsPluginRequest& aRequest, TFileName& aFileName)
1.521 + {
1.522 + TInt driveNumber = aRequest.DriveNumber();
1.523 +
1.524 + TInt err = GetName(&aRequest, aFileName);
1.525 + if(err != KErrNone)
1.526 + return(err);
1.527 +
1.528 + if (driveNumber == EDriveC)
1.529 + {
1.530 + TInt r = aFileName.Find(_L("\\virusdef.txt"));
1.531 +
1.532 + if (r != KErrNotFound)
1.533 + {
1.534 + //Do not allow the deletion of the virus definition file.
1.535 + return KErrAccessDenied;
1.536 + }
1.537 +
1.538 + r = aFileName.Find(_L("\\system\\libs\\t_vshook.pxt"));
1.539 + if (r != KErrNotFound)
1.540 + {
1.541 + //Do not allow the deletion of the this dll
1.542 + return KErrAccessDenied;
1.543 + }
1.544 + r = aFileName.Find(_L("\\sys\\bin\\t_vshook.pxt"));
1.545 + if (r != KErrNotFound)
1.546 + {
1.547 + //Do not allow the deletion of the this dll
1.548 + return KErrAccessDenied;
1.549 + }
1.550 + }
1.551 + return KErrNone;
1.552 + }
1.553 +
1.554 +/**
1.555 +Processes a message which describes the detection of an
1.556 +infected file. Appends the relevant text at the end of the
1.557 +file to say that it has been "cleaned". This allows the virus
1.558 +test program to confirm that the test virus scanner is
1.559 +behaving as expected.
1.560 +
1.561 +@internalComponent
1.562 +@param aMessage The message to be processed.
1.563 +*/
1.564 +void CTestVirusHook::CleanFile(const TDesC& aName, TInt aOperation)
1.565 + {
1.566 +
1.567 + RFile infectedFile;
1.568 + TBool bChangedToRw=EFalse;
1.569 + TInt pos=0;
1.570 +
1.571 + TUint fileAtt;
1.572 + TInt r = iFs.Att(aName, fileAtt);
1.573 + if (r != KErrNone)
1.574 + {
1.575 + return;
1.576 + }
1.577 +
1.578 + if (fileAtt & KEntryAttReadOnly)
1.579 + {
1.580 + bChangedToRw = ETrue;
1.581 + r = iFs.SetAtt(aName, 0, KEntryAttReadOnly);
1.582 + }
1.583 +
1.584 + r = infectedFile.Open(iFs, aName, EFileShareAny | EFileWrite);
1.585 +
1.586 + if (r != KErrNone)
1.587 + {
1.588 + return;
1.589 + }
1.590 +
1.591 + //To show we've fixed the file, append "Infection deleted" to the end of it.
1.592 + infectedFile.Seek(ESeekEnd, pos);
1.593 + switch (aOperation)
1.594 + {
1.595 + case EFileOpen:
1.596 + infectedFile.Write(_L8("infection detected - file open\\n"));
1.597 + break;
1.598 + case EFileDelete:
1.599 + infectedFile.Write(_L8("infection detected - file delete\\n"));
1.600 + break;
1.601 + case EFileRename:
1.602 + infectedFile.Write(_L8("infection detected - file rename\\n"));
1.603 + break;
1.604 + case EFileClose:
1.605 + infectedFile.Write(_L8("infection detected - file close\\n"));
1.606 + break;
1.607 + }
1.608 +
1.609 + infectedFile.Close();
1.610 +
1.611 + if (bChangedToRw)
1.612 + {
1.613 + iFs.SetAtt(aName, KEntryAttReadOnly,0);
1.614 + }
1.615 + }
1.616 +
1.617 +//factory functions
1.618 +
1.619 +class CVsHookFactory : public CFsPluginFactory
1.620 + {
1.621 +public:
1.622 + CVsHookFactory();
1.623 + virtual TInt Install();
1.624 + virtual CFsPlugin* NewPluginL();
1.625 + virtual CFsPlugin* NewPluginConnL();
1.626 + virtual TInt UniquePosition();
1.627 + };
1.628 +
1.629 +/**
1.630 +Constructor for the plugin factory
1.631 +@internalComponent
1.632 +*/
1.633 +CVsHookFactory::CVsHookFactory()
1.634 + {
1.635 + }
1.636 +
1.637 +/**
1.638 +Install function for the plugin factory
1.639 +@internalComponent
1.640 +*/
1.641 +TInt CVsHookFactory::Install()
1.642 + {
1.643 + iSupportedDrives = KPluginAutoAttach;
1.644 +
1.645 + _LIT(KVsHookName,"VsHook");
1.646 + return(SetName(&KVsHookName));
1.647 + }
1.648 +
1.649 +/**
1.650 +@internalComponent
1.651 +*/
1.652 +TInt CVsHookFactory::UniquePosition()
1.653 + {
1.654 + return(0x3EC);
1.655 + }
1.656 +
1.657 +/**
1.658 +Plugin factory function
1.659 +@internalComponent
1.660 +*/
1.661 +CFsPlugin* CVsHookFactory::NewPluginL()
1.662 +
1.663 + {
1.664 + return CTestVirusHook::NewL();
1.665 + }
1.666 +
1.667 +/**
1.668 +Plugin factory function
1.669 +@internalComponent
1.670 +*/
1.671 +CFsPlugin* CVsHookFactory::NewPluginConnL()
1.672 +
1.673 + {
1.674 + return CTestVirusHook::NewL();
1.675 + }
1.676 +
1.677 +/**
1.678 +Create a new Plugin
1.679 +@internalComponent
1.680 +*/
1.681 +extern "C" {
1.682 +
1.683 +EXPORT_C CFsPluginFactory* CreateFileSystem()
1.684 + {
1.685 + return(new CVsHookFactory());
1.686 + }
1.687 +}
1.688 +