sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32test\loader\security\t_fuzzldr.cpp sl@0: // sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_hash.h" sl@0: sl@0: // Fuzzing parameters sl@0: sl@0: const TInt KFuzzImages = 5; sl@0: const TInt KRandomFieldIterations = 8; sl@0: const TTimeIntervalMicroSeconds32 KDllTimeout = 10 * 1000000; sl@0: sl@0: #define FUZZFIELD(OBJ, NAME) { (const TText*)(L ## #OBJ L"." L ## #NAME), sizeof(((OBJ*)8)->NAME), _FOFF(OBJ, NAME) } sl@0: #define DUMBFIELD(NAME, SIZE, OFFSET) { (const TText*)L ## NAME, SIZE, OFFSET } sl@0: #define FUZZEND { NULL, 0, 0 } sl@0: sl@0: struct SFuzzField sl@0: { sl@0: const TText* name; sl@0: TInt size; sl@0: TInt offset; sl@0: }; sl@0: sl@0: const SFuzzField HeaderFields[] = sl@0: { sl@0: FUZZFIELD(E32ImageHeaderV, iUid1), sl@0: FUZZFIELD(E32ImageHeaderV, iUid2), sl@0: FUZZFIELD(E32ImageHeaderV, iUid3), sl@0: FUZZFIELD(E32ImageHeaderV, iUidChecksum), sl@0: FUZZFIELD(E32ImageHeaderV, iSignature), sl@0: FUZZFIELD(E32ImageHeaderV, iHeaderCrc), sl@0: FUZZFIELD(E32ImageHeaderV, iModuleVersion), sl@0: FUZZFIELD(E32ImageHeaderV, iCompressionType), sl@0: FUZZFIELD(E32ImageHeaderV, iToolsVersion.iMajor), sl@0: FUZZFIELD(E32ImageHeaderV, iToolsVersion.iMinor), sl@0: FUZZFIELD(E32ImageHeaderV, iToolsVersion.iBuild), sl@0: FUZZFIELD(E32ImageHeaderV, iTimeLo), sl@0: FUZZFIELD(E32ImageHeaderV, iTimeHi), sl@0: FUZZFIELD(E32ImageHeaderV, iFlags), sl@0: FUZZFIELD(E32ImageHeaderV, iCodeSize), sl@0: FUZZFIELD(E32ImageHeaderV, iDataSize), sl@0: FUZZFIELD(E32ImageHeaderV, iHeapSizeMin), sl@0: FUZZFIELD(E32ImageHeaderV, iHeapSizeMax), sl@0: FUZZFIELD(E32ImageHeaderV, iStackSize), sl@0: FUZZFIELD(E32ImageHeaderV, iBssSize), sl@0: FUZZFIELD(E32ImageHeaderV, iEntryPoint), sl@0: FUZZFIELD(E32ImageHeaderV, iCodeBase), sl@0: FUZZFIELD(E32ImageHeaderV, iDataBase), sl@0: FUZZFIELD(E32ImageHeaderV, iDllRefTableCount), sl@0: FUZZFIELD(E32ImageHeaderV, iExportDirOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iExportDirCount), sl@0: FUZZFIELD(E32ImageHeaderV, iTextSize), sl@0: FUZZFIELD(E32ImageHeaderV, iCodeOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iDataOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iImportOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iCodeRelocOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iDataRelocOffset), sl@0: FUZZFIELD(E32ImageHeaderV, iProcessPriority), sl@0: FUZZFIELD(E32ImageHeaderV, iCpuIdentifier), sl@0: FUZZFIELD(E32ImageHeaderV, iUncompressedSize), sl@0: FUZZFIELD(E32ImageHeaderV, iS.iSecureId), sl@0: FUZZFIELD(E32ImageHeaderV, iS.iVendorId), sl@0: FUZZFIELD(E32ImageHeaderV, iS.iCaps.iCaps[0]), sl@0: FUZZFIELD(E32ImageHeaderV, iS.iCaps.iCaps[1]), sl@0: FUZZFIELD(E32ImageHeaderV, iExceptionDescriptor), sl@0: FUZZFIELD(E32ImageHeaderV, iSpare2), sl@0: FUZZFIELD(E32ImageHeaderV, iExportDescSize), sl@0: FUZZFIELD(E32ImageHeaderV, iExportDescType), sl@0: FUZZFIELD(E32ImageHeaderV, iExportDesc[0]), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField ImportSectionFields[] = sl@0: { sl@0: FUZZFIELD(E32ImportSection, iSize), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField ImportBlockFields[] = sl@0: { sl@0: FUZZFIELD(E32ImportBlock, iOffsetOfDllName), // we should fuzz the string also sl@0: FUZZFIELD(E32ImportBlock, iNumberOfImports), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField ImportEntryFields[] = sl@0: { sl@0: DUMBFIELD("import", 4, 0), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField RelocSectionFields[] = sl@0: { sl@0: FUZZFIELD(E32RelocSection, iSize), sl@0: FUZZFIELD(E32RelocSection, iNumberOfRelocs), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField RelocBlockFields[] = sl@0: { sl@0: FUZZFIELD(E32RelocBlock, iPageOffset), sl@0: FUZZFIELD(E32RelocBlock, iBlockSize), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField RelocEntryFields[] = sl@0: { sl@0: DUMBFIELD("reloc", 2, 0), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField ExportEntryFields[] = sl@0: { sl@0: DUMBFIELD("export", 4, 0), sl@0: FUZZEND sl@0: }; sl@0: sl@0: const SFuzzField CompressedDataFields[] = sl@0: { sl@0: DUMBFIELD("data1", 4, 0), sl@0: DUMBFIELD("data2", 4, 4), sl@0: DUMBFIELD("data3", 4, 16), sl@0: DUMBFIELD("data4", 4, 64), sl@0: DUMBFIELD("data5", 4, 256), sl@0: DUMBFIELD("data6", 4, 1024), sl@0: DUMBFIELD("data7", 4, 4096), sl@0: FUZZEND sl@0: }; sl@0: sl@0: // Values to try for different sizes, signed here but can be interpreted as either sl@0: // each will also try the smaller sizes' values sl@0: const TInt8 Values8[] = { KMinTInt8, -100, -10, -2, -1, 0, 1, 2, 10, 100, KMaxTInt8 }; sl@0: const TInt Values8Count = sizeof(Values8)/sizeof(TInt8); sl@0: const TInt16 Values16[] = { KMinTInt16, -10000, -256, -255, 128, 255, 256, 10000, KMaxTInt16 }; sl@0: const TInt Values16Count = sizeof(Values16)/sizeof(TInt16); sl@0: const TInt32 Values32[] = { KMinTInt32, -1000000000, -65536, -65535, 32768, 65535, 65536, 268435455, 268435456, 1000000000, KMaxTInt32 }; sl@0: const TInt Values32Count = sizeof(Values32)/sizeof(TInt32); sl@0: const TInt ValuesCount[] = { 0, Values8Count, Values8Count+Values16Count, 0, Values8Count+Values16Count+Values32Count }; sl@0: const TInt Offsets[] = { 1, 2, 4, 16, -1, -2, -4, -16 }; sl@0: const TInt OffsetsCount = sizeof(Offsets)/sizeof(TInt); sl@0: sl@0: // Regular boring definitions and stuff sl@0: sl@0: RTest test(_L("T_FUZZLDR")); sl@0: RFs TheFs; sl@0: CFileMan* FileMan; sl@0: sl@0: _LIT(KOrigDir, "Z:\\sys\\bin\\"); sl@0: _LIT(KSysBin, ":\\sys\\bin\\"); sl@0: _LIT(KSysHash, ":\\sys\\hash\\"); sl@0: _LIT(KImageName, "fuzzv"); sl@0: _LIT(KExeExt, ".exe"); sl@0: _LIT(KDllExt, ".dll"); sl@0: _LIT(KMyself, "t_fuzzldr"); sl@0: _LIT(KSlaveArg, "-l "); sl@0: sl@0: TFileName Provided; sl@0: TFileName Original; sl@0: TFileName Current; sl@0: TFileName Hash; sl@0: TFileName HashDir; sl@0: TBool LoadDll; sl@0: RFile File; sl@0: RTimer Timer; sl@0: TUint8* Target; sl@0: E32ImageHeaderV* Header; sl@0: E32ImageHeaderV* CleanHeader; sl@0: CSHA1* Hasher; sl@0: sl@0: TInt FileSize; sl@0: TInt OutFileSize; sl@0: TUint8* CleanFileData; sl@0: TPtr8 CleanFileDes(CleanFileData, 0); sl@0: TUint8* FileData; sl@0: TPtr8 FileDes(FileData, 0); sl@0: TUint8* EndOfFile; sl@0: TChar Drive = '?', InternalDrive = '?', RemovableDrive = '?'; sl@0: sl@0: TBool Verbose; sl@0: TBool Forever = EFalse; sl@0: TUint32 Seed = 0; sl@0: typedef void (*TFieldFuzzer)(const SFuzzField*, TInt); sl@0: sl@0: enum SetMode { sl@0: ESetLiteral, sl@0: ESetOffset, sl@0: ESetRandom, sl@0: ESetXor, sl@0: }; sl@0: sl@0: enum ValueMode { sl@0: EValLiteral, sl@0: EValOffset, sl@0: EValRandom, sl@0: EValXor, sl@0: EValList, sl@0: EValOffsetList, sl@0: }; sl@0: sl@0: sl@0: TUint32 Rand() sl@0: { sl@0: Seed *= 69069; sl@0: Seed += 5; sl@0: return Seed; sl@0: } sl@0: sl@0: sl@0: TUint32 Rand(TUint32 aLimit) sl@0: { sl@0: TUint64 temp = (TUint64)Rand() * (TUint64)aLimit; sl@0: return (TUint32)(temp>>32); sl@0: } sl@0: sl@0: sl@0: void PrepareName(TInt aNum, TBool aDll) sl@0: { sl@0: Original = KOrigDir; sl@0: Original += KImageName; sl@0: Original.AppendNum(aNum); sl@0: Original += aDll ? KDllExt : KExeExt; sl@0: Current.Zero(); sl@0: Current.Append(Drive); sl@0: Current += KSysBin; sl@0: Current += KImageName; sl@0: Current.AppendNum(aNum); sl@0: Current += aDll ? KDllExt : KExeExt; sl@0: Hash = HashDir; sl@0: Hash += KImageName; sl@0: Hash.AppendNum(aNum); sl@0: Hash += aDll ? KDllExt : KExeExt; sl@0: } sl@0: sl@0: sl@0: void PrepareProvidedName() sl@0: { sl@0: Original = KOrigDir; sl@0: Original += Provided; sl@0: Current.Zero(); sl@0: Current.Append(Drive); sl@0: Current += KSysBin; sl@0: Current += Provided; sl@0: Hash = HashDir; sl@0: Hash += Provided; sl@0: } sl@0: sl@0: sl@0: void MakeCleanCopy() sl@0: { sl@0: Mem::Copy(FileData, CleanFileData, FileSize); sl@0: } sl@0: sl@0: sl@0: void LoadCleanFile() sl@0: { sl@0: test_KErrNone(File.Open(TheFs, Original, EFileRead)); sl@0: test_KErrNone(File.Size(FileSize)); sl@0: OutFileSize = FileSize; sl@0: CleanFileData = new TUint8[FileSize]; sl@0: test_NotNull(CleanFileData); sl@0: FileData = new TUint8[FileSize]; sl@0: EndOfFile = FileData + FileSize; sl@0: test_NotNull(FileData); sl@0: CleanFileDes.Set(CleanFileData, 0, FileSize); sl@0: test_KErrNone(File.Read(CleanFileDes)); sl@0: File.Close(); sl@0: Header = (E32ImageHeaderV*)FileData; sl@0: CleanHeader = (E32ImageHeaderV*)CleanFileData; sl@0: FileDes.Set(FileData, FileSize, FileSize); sl@0: MakeCleanCopy(); sl@0: test(CleanHeader->iUid1==(TUint32)KExecutableImageUidValue || CleanHeader->iUid1==(TUint32)KDynamicLibraryUidValue); sl@0: LoadDll = CleanHeader->iUid1==(TUint32)KDynamicLibraryUidValue; sl@0: } sl@0: sl@0: sl@0: void DoneFile() sl@0: { sl@0: delete[] FileData; sl@0: delete[] CleanFileData; sl@0: } sl@0: sl@0: sl@0: void RecalcChecksums() sl@0: { sl@0: if (Header->iUidChecksum == CleanHeader->iUidChecksum) sl@0: { sl@0: TUidType uids = *(const TUidType*)Header; sl@0: TCheckedUid chkuid(uids); sl@0: const TUint32* pChkUid = (const TUint32*)&chkuid; sl@0: Header->iUidChecksum = pChkUid[3]; sl@0: } sl@0: if (Header->iHeaderCrc == CleanHeader->iHeaderCrc) sl@0: { sl@0: Header->iHeaderCrc = KImageCrcInitialiser; sl@0: TUint32 crc = 0; sl@0: Mem::Crc32(crc, Header, sizeof(E32ImageHeaderV)); sl@0: Header->iHeaderCrc = crc; sl@0: } sl@0: } sl@0: sl@0: sl@0: void Load() sl@0: { sl@0: RecalcChecksums(); sl@0: test_KErrNone(File.Replace(TheFs, Current, EFileWrite)); sl@0: test_KErrNone(File.Write(FileDes, OutFileSize)); sl@0: test_KErrNone(File.Flush()); sl@0: File.Close(); sl@0: if (Drive == RemovableDrive) sl@0: { sl@0: TPtrC8 data(FileData, OutFileSize); sl@0: Hasher->Reset(); sl@0: Hasher->Update(data); sl@0: TBuf8 hashVal = Hasher->Final(); sl@0: test_KErrNone(File.Replace(TheFs, Hash, EFileWrite)); sl@0: test_KErrNone(File.Write(hashVal)); sl@0: test_KErrNone(File.Flush()); sl@0: File.Close(); sl@0: } sl@0: RProcess p; sl@0: TInt r; sl@0: if (LoadDll) sl@0: { sl@0: TFileName args; sl@0: args.Copy(KSlaveArg); sl@0: args.Append(Current); sl@0: test_KErrNone(p.Create(KMyself, args)); sl@0: TRequestStatus logon, rendez, timeout; sl@0: p.Logon(logon); sl@0: p.Rendezvous(rendez); sl@0: p.Resume(); sl@0: User::WaitForRequest(rendez); sl@0: test(rendez==KErrNone); sl@0: Timer.After(timeout, KDllTimeout); sl@0: User::WaitForRequest(logon, timeout); sl@0: if (logon == KRequestPending) sl@0: { sl@0: p.Kill(0); sl@0: User::WaitForRequest(logon); sl@0: } sl@0: else sl@0: { sl@0: Timer.Cancel(); sl@0: User::WaitForRequest(timeout); sl@0: } sl@0: p.Close(); sl@0: // we don't check the return code as passing it back makes the log output sl@0: // super spammy with KPANIC on - it prints for every nonzero return code. sl@0: if (Verbose) test.Printf(_L("\n")); sl@0: } sl@0: else sl@0: { sl@0: r = p.Create(Current, KNullDesC); sl@0: if (r==KErrNone) sl@0: p.Kill(0); sl@0: if (Verbose) test.Printf(_L("=> %d\n"), r); sl@0: } sl@0: p.Close(); sl@0: } sl@0: sl@0: sl@0: template void SetFieldTo(const SFuzzField* aField, T aSetTo, SetMode aMode) sl@0: { sl@0: T* field = (T*)(Target + aField->offset); sl@0: if ((TUint8*)field >= EndOfFile) sl@0: { sl@0: if (Verbose) test.Printf(_L("skipping, eof ")); sl@0: return; sl@0: } sl@0: if (aMode == ESetOffset) sl@0: aSetTo += *field; sl@0: else if (aMode == ESetRandom) sl@0: aSetTo = (T)Rand(); sl@0: else if (aMode == ESetXor) sl@0: aSetTo ^= *field; sl@0: *field = aSetTo; sl@0: if (Verbose) test.Printf(_L("%d "), aSetTo); sl@0: } sl@0: sl@0: sl@0: void SetField(const SFuzzField* aField, TInt aValue, ValueMode aMode) sl@0: { sl@0: if (aMode < EValList) sl@0: { sl@0: switch(aField->size) sl@0: { sl@0: case 1: sl@0: SetFieldTo(aField, aValue, (SetMode)aMode); sl@0: break; sl@0: case 2: sl@0: SetFieldTo(aField, aValue, (SetMode)aMode); sl@0: break; sl@0: case 4: sl@0: SetFieldTo(aField, aValue, (SetMode)aMode); sl@0: break; sl@0: } sl@0: } sl@0: else if (aMode == EValList) sl@0: { sl@0: switch(aField->size) sl@0: { sl@0: case 1: sl@0: SetFieldTo(aField, Values8[aValue], ESetLiteral); sl@0: break; sl@0: case 2: sl@0: if (aValue < ValuesCount[1]) sl@0: SetFieldTo(aField, Values8[aValue], ESetLiteral); sl@0: else sl@0: SetFieldTo(aField, Values16[aValue-ValuesCount[1]], ESetLiteral); sl@0: break; sl@0: case 4: sl@0: if (aValue < ValuesCount[1]) sl@0: SetFieldTo(aField, Values8[aValue], ESetLiteral); sl@0: else if (aValue < ValuesCount[2]) sl@0: SetFieldTo(aField, Values16[aValue-ValuesCount[1]], ESetLiteral); sl@0: else sl@0: SetFieldTo(aField, Values32[aValue-ValuesCount[2]], ESetLiteral); sl@0: break; sl@0: } sl@0: } sl@0: else if (aMode == EValOffsetList) sl@0: { sl@0: switch(aField->size) sl@0: { sl@0: case 1: sl@0: SetFieldTo(aField, Offsets[aValue], ESetOffset); sl@0: break; sl@0: case 2: sl@0: SetFieldTo(aField, Offsets[aValue], ESetOffset); sl@0: break; sl@0: case 4: sl@0: SetFieldTo(aField, Offsets[aValue], ESetOffset); sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: void FuzzFieldsDeterministically(const SFuzzField* aFields, TInt aOffset) sl@0: { sl@0: Target = FileData + aOffset; sl@0: sl@0: TInt f = -1; sl@0: while (aFields[++f].name) sl@0: { sl@0: test.Printf(_L("FIELD: %s ...\n"), aFields[f].name); sl@0: TInt v; sl@0: if (Verbose) test.Next(_L("Using preset values")); sl@0: for (v = 0; v < ValuesCount[aFields[f].size]; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: SetField(&aFields[f], v, EValList); sl@0: Load(); sl@0: } sl@0: if (Verbose) test.Next(_L("Using preset offsets")); sl@0: for (v = 0; v < OffsetsCount; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: SetField(&aFields[f], v, EValOffsetList); sl@0: Load(); sl@0: } sl@0: if (Verbose) test.Next(_L("Flipping single bits")); sl@0: for (v = 0; v < aFields[f].size*8; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: SetField(&aFields[f], 1<iCodeSize + CleanHeader->iCodeOffset; sl@0: for (v = codeend-4; v <= codeend+4; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: SetField(&aFields[f], v, EValLiteral); sl@0: Load(); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: void FuzzFieldsRandomly(const SFuzzField* aFields, TInt aOffset) sl@0: { sl@0: Target = FileData + aOffset; sl@0: sl@0: TInt f = 0; sl@0: while (aFields[f].name) sl@0: { sl@0: test.Printf(_L("FIELD: %s ... (random)\n"), aFields[f].name); sl@0: TInt v; sl@0: for (v = 0; v < KRandomFieldIterations; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: SetField(&aFields[f], 0, EValRandom); sl@0: Load(); sl@0: } sl@0: f++; sl@0: } sl@0: } sl@0: sl@0: sl@0: void FuzzBlockRandomly(TInt aOffset, TInt aSize) sl@0: { sl@0: SFuzzField field; sl@0: field.size = 1; sl@0: Target = FileData + aOffset; sl@0: sl@0: test.Printf(_L("FIELD: random words in data\n")); sl@0: TInt v; sl@0: for (v = 0; v < KRandomFieldIterations * 4; ++v) sl@0: { sl@0: MakeCleanCopy(); sl@0: field.offset = Rand(aSize); sl@0: if (Verbose) test.Printf(_L("@ %d, "), field.offset); sl@0: SetField(&field, 0, EValRandom); sl@0: Load(); sl@0: } sl@0: } sl@0: sl@0: sl@0: void FuzzFile(TBool aRandom) sl@0: { sl@0: TTime before, after; sl@0: before.UniversalTime(); sl@0: LoadCleanFile(); sl@0: sl@0: TFieldFuzzer FuzzFields = aRandom ? FuzzFieldsRandomly : FuzzFieldsDeterministically; sl@0: sl@0: // E32ImageHeader sl@0: FuzzFields(HeaderFields, 0); sl@0: sl@0: if (CleanHeader->iCompressionType == KFormatNotCompressed) sl@0: { sl@0: // import table sl@0: TInt offset = CleanHeader->iImportOffset; sl@0: if (offset != 0) sl@0: { sl@0: FuzzFields(ImportSectionFields, offset); sl@0: offset += sizeof(E32ImportSection); sl@0: FuzzFields(ImportBlockFields, offset); sl@0: offset += sizeof(E32ImportBlock); sl@0: FuzzFields(ImportEntryFields, offset); sl@0: } sl@0: sl@0: // code relocations sl@0: offset = CleanHeader->iCodeRelocOffset; sl@0: if (offset != 0) sl@0: { sl@0: FuzzFields(RelocSectionFields, offset); sl@0: offset += sizeof(E32RelocSection); sl@0: FuzzFields(RelocBlockFields, offset); sl@0: offset += sizeof(E32RelocBlock); sl@0: FuzzFields(RelocEntryFields, offset); sl@0: } sl@0: sl@0: // data relocations sl@0: offset = CleanHeader->iDataRelocOffset; sl@0: if (offset != 0) sl@0: { sl@0: FuzzFields(RelocSectionFields, offset); sl@0: offset += sizeof(E32RelocSection); sl@0: FuzzFields(RelocBlockFields, offset); sl@0: offset += sizeof(E32RelocBlock); sl@0: FuzzFields(RelocEntryFields, offset); sl@0: } sl@0: sl@0: // export table sl@0: offset = CleanHeader->iExportDirOffset; sl@0: if (offset != 0) sl@0: { sl@0: FuzzFields(ExportEntryFields, offset); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: if (aRandom) sl@0: { sl@0: // random bits of the compressed data sl@0: FuzzBlockRandomly(CleanHeader->iCodeOffset, FileSize - CleanHeader->iCodeOffset); sl@0: } sl@0: else sl@0: { sl@0: // arbitrary bits of the compressed data sl@0: FuzzFields(CompressedDataFields, CleanHeader->iCodeOffset); sl@0: } sl@0: } sl@0: sl@0: DoneFile(); sl@0: after.UniversalTime(); sl@0: TTimeIntervalSeconds interval; sl@0: after.SecondsFrom(before, interval); sl@0: test.Printf(_L("Took %d seconds\n"), interval.Int()); sl@0: } sl@0: sl@0: sl@0: void FuzzTruncateTo(TInt size) sl@0: { sl@0: OutFileSize = size - 4; sl@0: if (Verbose) test.Printf(_L("%d "), OutFileSize); sl@0: Load(); sl@0: OutFileSize = size - 1; sl@0: if (Verbose) test.Printf(_L("%d "), OutFileSize); sl@0: Load(); sl@0: if (size == FileSize) sl@0: return; sl@0: OutFileSize = size; sl@0: if (Verbose) test.Printf(_L("%d "), OutFileSize); sl@0: Load(); sl@0: OutFileSize = size + 1; sl@0: if (Verbose) test.Printf(_L("%d "), OutFileSize); sl@0: Load(); sl@0: OutFileSize = size + 4; sl@0: if (Verbose) test.Printf(_L("%d "), OutFileSize); sl@0: Load(); sl@0: } sl@0: sl@0: sl@0: void FuzzTruncate() sl@0: { sl@0: TTime before, after; sl@0: before.UniversalTime(); sl@0: LoadCleanFile(); sl@0: sl@0: FuzzTruncateTo(CleanHeader->iCodeOffset); sl@0: if (CleanHeader->iCompressionType == KFormatNotCompressed) sl@0: FuzzTruncateTo(CleanHeader->iCodeOffset+CleanHeader->iCodeSize); sl@0: FuzzTruncateTo(FileSize); sl@0: sl@0: DoneFile(); sl@0: after.UniversalTime(); sl@0: TTimeIntervalSeconds interval; sl@0: after.SecondsFrom(before, interval); sl@0: test.Printf(_L("Took %d seconds\n"), interval.Int()); sl@0: } sl@0: sl@0: sl@0: void FuzzAllTestImages() sl@0: { sl@0: TInt i; sl@0: Drive = InternalDrive; sl@0: test.Next(_L("Fuzzing deterministically")); sl@0: for (i=1; i<=KFuzzImages; ++i) sl@0: { sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzFile(EFalse); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzFile(EFalse); sl@0: } sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Fuzzing deterministically on removable media")); sl@0: for (i=1; i<=KFuzzImages; ++i) sl@0: { sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzFile(EFalse); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzFile(EFalse); sl@0: } sl@0: Drive = InternalDrive; sl@0: test.Next(_L("Fuzzing by truncation")); sl@0: for (i=1; i<=KFuzzImages; ++i) sl@0: { sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzTruncate(); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzTruncate(); sl@0: } sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Fuzzing by truncation on removable media")); sl@0: for (i=1; i<=KFuzzImages; ++i) sl@0: { sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzTruncate(); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzTruncate(); sl@0: } sl@0: test.Next(_L("Fuzzing randomly")); sl@0: do sl@0: { sl@0: for (i=1; i<=KFuzzImages; ++i) sl@0: { sl@0: Drive = InternalDrive; sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzFile(ETrue); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzFile(ETrue); sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing exe %d on removable media\n"), i); sl@0: PrepareName(i, EFalse); sl@0: FuzzFile(ETrue); sl@0: if(i==5) sl@0: continue; // DLL 5 doesn't exist because toolchain doesn't like DLLs with no exports sl@0: test.Next(_L("Next binary...")); sl@0: test.Printf(_L("Fuzzing dll %d on removable media\n"), i); sl@0: PrepareName(i, ETrue); sl@0: FuzzFile(ETrue); sl@0: } sl@0: } sl@0: while (Forever); sl@0: } sl@0: sl@0: sl@0: void FuzzProvidedImage() sl@0: { sl@0: test.Printf(_L("Fuzzing file %S\n"), &Provided); sl@0: PrepareProvidedName(); sl@0: Drive = InternalDrive; sl@0: test.Next(_L("Fuzzing deterministically")); sl@0: FuzzFile(EFalse); sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Fuzzing deterministically on removable media")); sl@0: FuzzFile(EFalse); sl@0: test.Next(_L("Fuzzing by truncation")); sl@0: FuzzTruncate(); sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Fuzzing by truncation on removable media")); sl@0: FuzzTruncate(); sl@0: test.Next(_L("Fuzzing randomly")); sl@0: do sl@0: { sl@0: Drive = InternalDrive; sl@0: test.Next(_L("Internal drive")); sl@0: FuzzFile(ETrue); sl@0: Drive = RemovableDrive; sl@0: test.Next(_L("Removable drive")); sl@0: FuzzFile(ETrue); sl@0: } sl@0: while (Forever); sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: // default to verbose unless the fasttest trace flag is on sl@0: Verbose = (UserSvr::DebugMask(2)&0x00000002) == 0; sl@0: sl@0: TFileName cmd; sl@0: User::CommandLine(cmd); sl@0: TLex lex(cmd); sl@0: FOREVER sl@0: { sl@0: lex.SkipSpace(); sl@0: if (lex.Eos()) sl@0: break; sl@0: TChar next = lex.Peek(); sl@0: if (next == '-' || next == '/') sl@0: { sl@0: // option sl@0: lex.Inc(); sl@0: switch(lex.Get()) sl@0: { sl@0: case 'v': sl@0: Verbose = ETrue; sl@0: break; sl@0: case 'q': sl@0: Verbose = EFalse; sl@0: break; sl@0: case 'l': sl@0: { sl@0: // being used as a slave to load a DLL sl@0: TPtrC libname(lex.NextToken()); sl@0: RLibrary l; sl@0: RProcess::Rendezvous(KErrNone); sl@0: l.Load(libname); sl@0: return KErrNone; sl@0: } sl@0: case 's': sl@0: // random seed sl@0: lex.SkipSpace(); sl@0: test_KErrNone(lex.Val(Seed, EHex)); sl@0: test.Printf(_L("Using supplied random seed %08x\n"), Seed); sl@0: break; sl@0: case 'f': sl@0: // run forever sl@0: Forever = ETrue; sl@0: break; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // filename, at least i assume it is :) sl@0: Provided.Copy(lex.NextToken()); sl@0: } sl@0: } sl@0: sl@0: test.Title(); sl@0: test.Next(_L("Setup")); sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanup; sl@0: cleanup=CTrapCleanup::New(); sl@0: sl@0: if (Seed == 0) sl@0: { sl@0: TTime time; sl@0: time.UniversalTime(); sl@0: Seed = (TUint32)time.Int64(); sl@0: test.Printf(_L("Random seed is %08x\n"), Seed); sl@0: } sl@0: sl@0: test_KErrNone(TheFs.Connect()); sl@0: test_TRAP(FileMan=CFileMan::NewL(TheFs)); sl@0: test_KErrNone(Timer.CreateLocal()); sl@0: test_TRAP(Hasher=CSHA1::NewL()); sl@0: HashDir.Append(TheFs.GetSystemDriveChar()); sl@0: HashDir.Append(KSysHash); sl@0: TInt r = TheFs.MkDirAll(HashDir); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: sl@0: // Find some interesting drives sl@0: for (TInt driveno = EDriveA; driveno <= EDriveZ; ++driveno) sl@0: { sl@0: TDriveInfo di; sl@0: test_KErrNone(TheFs.Drive(di, driveno)); sl@0: if (di.iType == EMediaNotPresent) sl@0: continue; sl@0: TChar drivechar; sl@0: test_KErrNone(TheFs.DriveToChar(driveno, drivechar)); sl@0: if ((di.iDriveAtt & KDriveAttInternal) && InternalDrive == '?') sl@0: InternalDrive = drivechar; sl@0: else if ((di.iDriveAtt & KDriveAttRemovable) && RemovableDrive == '?') sl@0: RemovableDrive = drivechar; sl@0: else sl@0: continue; sl@0: sl@0: TFileName fn; sl@0: fn.Append(drivechar); sl@0: fn.Append(KSysBin); sl@0: TheFs.MkDirAll(fn); sl@0: test(r == KErrNone || r == KErrAlreadyExists); sl@0: } sl@0: test.Printf(_L("Using %c as internal drive, %c as removable\n"), (TUint)InternalDrive, (TUint)RemovableDrive); sl@0: sl@0: // Turn off evil lazy dll unloading sl@0: RLoader l; sl@0: test_KErrNone(l.Connect()); sl@0: test_KErrNone(l.CancelLazyDllUnload()); sl@0: l.Close(); sl@0: sl@0: test.Start(_L("Fuzzing loader")); sl@0: if (Provided.Length() == 0) sl@0: FuzzAllTestImages(); sl@0: else sl@0: FuzzProvidedImage(); sl@0: test.End(); sl@0: sl@0: delete Hasher; sl@0: Timer.Close(); sl@0: delete FileMan; sl@0: TheFs.Close(); sl@0: test.Close(); sl@0: delete cleanup; sl@0: __UHEAP_MARKEND; sl@0: return KErrNone; sl@0: } sl@0: sl@0: