// looks exactly like the definition in DIOpenDiagService (#T) public ComParameter(BinaryReader reader, long baseAddress, List <ECUInterface> parentEcuInterfaceList, CTFLanguage language) { BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt16(); ComParamIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader); ParentInterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader); SubinterfaceIndex = CaesarReader.ReadBitflagInt16(ref bitflags, reader, 0); Unk5 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); Unk_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // no -1? ctf strings should have -1 Phrase = CaesarReader.ReadBitflagInt16(ref bitflags, reader); DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress); ComParamValue = 0; if (DumpSize == 4) { ComParamValue = BitConverter.ToInt32(Dump, 0); } ECUInterface parentEcuInterface = parentEcuInterfaceList[ParentInterfaceIndex]; if (ComParamIndex >= parentEcuInterface.ComParameterNames.Count) { // throw new Exception("Invalid communication parameter : parent interface has no matching key"); ParamName = "CP_UNKNOWN_MISSING_KEY"; Console.WriteLine($"Warning: Tried to load a communication parameter without a parent (value: {ComParamValue}), parent: {parentEcuInterface.Qualifier}."); } else { ParamName = parentEcuInterface.ComParameterNames[ComParamIndex]; } }
// void __cdecl DiagServiceReadPresentation(int *inBase, DECODED_PRESENTATION *outPresentation) // Looks like its actually a presentation // See DIDiagservice* functions public DiagPreparation(BinaryReader reader, CTFLanguage language, long baseAddress, int bitPosition, ushort modeConfig, ECU parentEcu, DiagService parentDiagService) { BitPosition = bitPosition; ModeConfig = modeConfig; Language = language; BaseAddress = baseAddress; ParentECU = parentEcu; ParentDiagService = parentDiagService; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk1 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk2 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); AlternativeBitWidth = CaesarReader.ReadBitflagInt32(ref bitflags, reader); IITOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); InfoPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader); PresPoolIndex = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Field1E = CaesarReader.ReadBitflagInt32(ref bitflags, reader); SystemParam = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1); DumpMode = CaesarReader.ReadBitflagInt16(ref bitflags, reader); DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader); if (DumpMode == 5) { // dump is actually a string, use // CaesarReader.ReadBitflagDumpWithReaderAsString } Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, DumpSize, baseAddress); SizeInBits = GetSizeInBits(reader); // PrintDebug(); }
public VCSubfragment(BinaryReader reader, VCFragment parentFragment, CTFLanguage language, long baseAddress) { // see DIOpenCBF_FragValHandle reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt16(); Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); if (parentFragment.CCFHandle == 5) { // fragment should be parsed as PBSGetDumpAsStringFn, though internally we perceive this as the same } Dump = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, parentFragment.VarcodeDumpSize, baseAddress); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); QualifierUsuallyDisabled = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Unk3 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk4 = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1); SupplementKey = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); NameCTFResolved = language.GetString(Description_CTF); //int subfragmentIdk2 = reader.ReadInt32(); //int subfragmentName = reader.ReadInt32(); //int subfragmentIdkIncremented = reader.ReadInt32(); //Console.WriteLine($"Subfragment: {subfragmentIdk1:X} {subfragmentIdk2:X} {language.GetString(subfragmentName)} {subfragmentIdkIncremented:X}"); //PrintDebug(); }
public CFFHeader(BinaryReader reader) { reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin); CffHeaderSize = reader.ReadInt32(); BaseAddress = reader.BaseStream.Position; ulong bitFlags = reader.ReadUInt16(); CaesarVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); GpdVersion = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); EcuCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); EcuOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); CtfOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); StringPoolSize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); DscOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); DscCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); DscEntrySize = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); CbfVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); GpdVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); XmlString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); long dataBufferOffsetAfterStrings = StringPoolSize + CffHeaderSize + 0x414; if (DscCount > 0) { DscBlockOffset = DscOffset + dataBufferOffsetAfterStrings; DscBlockSize = DscEntrySize * DscCount; reader.BaseStream.Seek(DscBlockOffset, SeekOrigin.Begin); DSCPool = reader.ReadBytes(DscBlockSize); } }
public ECUInterface(BinaryReader reader, long baseAddress) { BaseAddress = baseAddress; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); // we can now properly operate on the interface block ulong interfaceBitflags = reader.ReadUInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress); Name_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader, -1); VersionString = CaesarReader.ReadBitflagStringWithReader(ref interfaceBitflags, reader, BaseAddress); Version = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader); ComParamCount = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader); ComParamListOffset = CaesarReader.ReadBitflagInt32(ref interfaceBitflags, reader); Unk6 = CaesarReader.ReadBitflagInt16(ref interfaceBitflags, reader); long comparamFileOffset = ComParamListOffset + BaseAddress; // Console.WriteLine($"interface string table offset from definition block : {interfaceStringTableOffset_fromDefinitionBlock:X}"); for (int interfaceStringIndex = 0; interfaceStringIndex < ComParamCount; interfaceStringIndex++) { // seek to string pointer reader.BaseStream.Seek(comparamFileOffset + (interfaceStringIndex * 4), SeekOrigin.Begin); // from pointer, seek to string long interfaceStringReadoutPtr = reader.ReadInt32() + comparamFileOffset; reader.BaseStream.Seek(interfaceStringReadoutPtr, SeekOrigin.Begin); string comParameter = CaesarReader.ReadStringFromBinaryReader(reader); comParameters.Add(comParameter); } }
public CTFHeader(BinaryReader reader, long baseAddress, int headerSize) { BaseAddress = baseAddress; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong ctfBitflags = reader.ReadUInt16(); CtfUnk1 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress); CtfUnk3 = CaesarReader.ReadBitflagInt16(ref ctfBitflags, reader); CtfUnk4 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader); CtfLanguageCount = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader); CtfLanguageTableOffset = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader); CtfUnkString = CaesarReader.ReadBitflagStringWithReader(ref ctfBitflags, reader, BaseAddress); long ctfLanguageTableOffsetRelativeToDefintions = CtfLanguageTableOffset + BaseAddress; // parse every language record CtfLanguages = new List <CTFLanguage>(); for (int languageEntry = 0; languageEntry < CtfLanguageCount; languageEntry++) { long languageTableEntryOffset = ctfLanguageTableOffsetRelativeToDefintions + (languageEntry * 4); reader.BaseStream.Seek(languageTableEntryOffset, SeekOrigin.Begin); long realLanguageEntryAddress = reader.ReadInt32() + ctfLanguageTableOffsetRelativeToDefintions; CTFLanguage language = new CTFLanguage(reader, realLanguageEntryAddress, headerSize); CtfLanguages.Add(language); } }
public Scale(BinaryReader reader, long baseAddress, CTFLanguage language) { BaseAddress = baseAddress; Language = language; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt16(); Unk1 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // typically qualifier Unk2 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // typically description PrepLowBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // could be float PrepUpBound = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // could be float MultiplyFactor = CaesarReader.ReadBitflagFloat(ref bitflags, reader); AddConstOffset = CaesarReader.ReadBitflagFloat(ref bitflags, reader); SICount = CaesarReader.ReadBitflagInt32(ref bitflags, reader); OffsetSI = CaesarReader.ReadBitflagInt32(ref bitflags, reader); USCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader); OffsetUS = CaesarReader.ReadBitflagInt32(ref bitflags, reader); EnumDescription = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); UnkC = CaesarReader.ReadBitflagInt32(ref bitflags, reader); }
public static uint ReadCBFWithOffsetUnsigned(int memberIndex, StructureName structureName, byte[] input) { int byteOffset = CaesarStructure.GetCBFOffset(memberIndex, structureName, input); using (BinaryReader reader = new BinaryReader(new MemoryStream(input))) { byte[] layout = CaesarStructure.GetCaesarLayout(structureName); return(CaesarReader.ReadUIntWithSize(reader, layout[memberIndex], byteOffset)); } }
// DIIAddCBFFile /* * 21 bits active * f [6, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 4,4,4,4, 1], */ public FlashHeader(BinaryReader reader) { reader.BaseStream.Seek(StubHeader.StubHeaderSize, SeekOrigin.Begin); CffHeaderSize = reader.ReadInt32(); BaseAddress = reader.BaseStream.Position; ulong bitFlags = reader.ReadUInt32(); reader.ReadUInt16(); // unused FlashName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); FlashGenerationParams = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); Unk3 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); Unk4 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); FileAuthor = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); FileCreationTime = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); AuthoringToolVersion = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); FTRAFOVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); FTRAFOVersionNumber = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); CFFVersionString = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); NumberOfFlashAreas = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); FlashDescriptionTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); DataBlockTableCountProbably = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); DataBlockRefTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); CTFHeaderTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); LanguageBlockLength = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); NumberOfECURefs = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); ECURefTable = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); UnkTableCount = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); UnkTableProbably = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); Unk15 = CaesarReader.ReadBitflagUInt8(ref bitFlags, reader); DescriptionHeaders = new List <FlashDescriptionHeader>(); for (int flashDescIndex = 0; flashDescIndex < NumberOfFlashAreas; flashDescIndex++) { long flashTableEntryAddress = FlashDescriptionTable + BaseAddress + (flashDescIndex * 4); reader.BaseStream.Seek(flashTableEntryAddress, SeekOrigin.Begin); long flashEntryBaseAddress = FlashDescriptionTable + BaseAddress + reader.ReadInt32(); FlashDescriptionHeader fdh = new FlashDescriptionHeader(reader, flashEntryBaseAddress); DescriptionHeaders.Add(fdh); } DataBlocks = new List <FlashDataBlock>(); for (int dataBlockIndex = 0; dataBlockIndex < DataBlockTableCountProbably; dataBlockIndex++) { long datablockEntryAddress = DataBlockRefTable + BaseAddress + (dataBlockIndex * 4); reader.BaseStream.Seek(datablockEntryAddress, SeekOrigin.Begin); long datablockBaseAddress = DataBlockRefTable + BaseAddress + reader.ReadInt32(); FlashDataBlock fdb = new FlashDataBlock(reader, datablockBaseAddress); DataBlocks.Add(fdb); } }
public FlashDataBlock(BinaryReader reader, long baseAddress) { BaseAddress = baseAddress; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); reader.ReadUInt16(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); LongName = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Description = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FlashData = CaesarReader.ReadBitflagInt32(ref bitflags, reader); BlockLength = CaesarReader.ReadBitflagInt32(ref bitflags, reader); DataFormat = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FileName = CaesarReader.ReadBitflagInt32(ref bitflags, reader); NumberOfFilters = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FiltersOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); NumberOfSegments = CaesarReader.ReadBitflagInt32(ref bitflags, reader); SegmentOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); EncryptionMode = CaesarReader.ReadBitflagInt16(ref bitflags, reader); KeyLength = CaesarReader.ReadBitflagInt32(ref bitflags, reader); KeyBuffer = CaesarReader.ReadBitflagInt32(ref bitflags, reader); NumberOfOwnIdents = CaesarReader.ReadBitflagInt32(ref bitflags, reader); IdentsOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); NumberOfSecurities = CaesarReader.ReadBitflagInt32(ref bitflags, reader); SecuritiesOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); DataBlockType = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); UniqueObjectId = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FlashDataInfo_Idk = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); FlashDataInfoLang1 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FlashDataInfoLang2 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FlashDataInfo_Idk2 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // CtfUnk1 = CaesarReader.ReadBitflagInt32(ref ctfBitflags, reader); FlashSegments = new List <FlashSegment>(); for (int segmentIndex = 0; segmentIndex < NumberOfSegments; segmentIndex++) { long segmentEntryAddress = SegmentOffset + BaseAddress + (segmentIndex * 4); reader.BaseStream.Seek(segmentEntryAddress, SeekOrigin.Begin); long segmentBaseAddress = SegmentOffset + BaseAddress + reader.ReadInt32(); FlashSegment segment = new FlashSegment(reader, segmentBaseAddress); FlashSegments.Add(segment); } }
public static bool VerifyChecksum(byte[] fileBytes, out uint checksum) { uint computedChecksum = CaesarReader.ComputeFileChecksumLazy(fileBytes); uint providedChecksum = ReadFileChecksum(fileBytes); checksum = providedChecksum; if (computedChecksum != providedChecksum) { Console.WriteLine($"WARNING: Checksum mismatch : computed/provided: {computedChecksum:X8}/{providedChecksum:X8}"); return(false); } return(true); }
public void LoadStrings(BinaryReader reader, int headerSize, Encoding encoding) { StringEntries = new List <string>(); int caesarStringTableOffset = headerSize + 0x410 + 4; // header.CffHeaderSize; strange that this has to be manually computed for (int i = 0; i < StringCount; i++) { reader.BaseStream.Seek(caesarStringTableOffset + (i * 4), SeekOrigin.Begin); int stringOffset = reader.ReadInt32(); reader.BaseStream.Seek(caesarStringTableOffset + stringOffset, SeekOrigin.Begin); string result = CaesarReader.ReadStringFromBinaryReader(reader, encoding); StringEntries.Add(result); } }
public CTFLanguage(BinaryReader reader, long baseAddress, int headerSize) { BaseAddress = baseAddress; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong languageEntryBitflags = reader.ReadUInt16(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref languageEntryBitflags, reader, BaseAddress); LanguageIndex = CaesarReader.ReadBitflagInt16(ref languageEntryBitflags, reader); StringPoolSize = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); MaybeOffsetFromStringPoolBase = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); StringCount = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); LoadStrings(reader, headerSize, CaesarReader.DefaultEncoding); }
public long GetMappedAddressFileOffset(BinaryReader reader) { reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitFlags = reader.ReadUInt16(); if (CaesarReader.CheckAndAdvanceBitflag(ref bitFlags)) { return(reader.BaseStream.Position); } else { return(-1); } }
public long GetSegmentLengthFileOffset(BinaryReader reader) { reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitFlags = reader.ReadUInt16(); CaesarReader.ReadBitflagInt32(ref bitFlags, reader); // skip FromAddress if (CaesarReader.CheckAndAdvanceBitflag(ref bitFlags)) { return(reader.BaseStream.Position); } else { return(-1); } }
public FlashSegment(BinaryReader reader, long baseAddress) { BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitFlags = reader.ReadUInt16(); // start reading FromAddress = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); SegmentLength = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); Unk3 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); SegmentName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, reader, BaseAddress); Unk5 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); Unk6 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); Unk7 = CaesarReader.ReadBitflagInt32(ref bitFlags, reader); }
public CTFLanguage(BinaryReader reader, long baseAddress, int headerSize) { BaseAddress = baseAddress; reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong languageEntryBitflags = reader.ReadUInt16(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref languageEntryBitflags, reader, BaseAddress); LanguageIndex = CaesarReader.ReadBitflagInt16(ref languageEntryBitflags, reader); StringPoolSize = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); MaybeOffsetFromStringPoolBase = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); StringCount = CaesarReader.ReadBitflagInt32(ref languageEntryBitflags, reader); // I have no idea if encoding data is included, using ascii as a default for now. Some german character data will be lost LoadStrings(reader, headerSize, CaesarReader.DefaultEncoding); //PrintDebug(); }
public ECUVariantPattern(BinaryReader reader, long baseAddress) { BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); UnkBufferSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UnkBuffer = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, UnkBufferSize, baseAddress); Unk3 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk4 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); VendorName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); KwpVendorID = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); Unk8 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); Unk9 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); Unk10 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); Unk11 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk12 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk13 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk14 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk15 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk16 = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, 5, baseAddress); // read with a constant size Unk17 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk18 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk19 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk20 = CaesarReader.ReadBitflagUInt8(ref bitflags, reader); Unk21 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk23 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UdsVendorID = CaesarReader.ReadBitflagInt32(ref bitflags, reader); PatternType = CaesarReader.ReadBitflagInt32(ref bitflags, reader); VariantID = UdsVendorID == 0 ? KwpVendorID : UdsVendorID; // type 3 contains a vendor name }
public static uint ComputeFileChecksum(byte[] fileBytes) { // caesar uses a 0x8000 block size // const int blockSize = 0x8000; const int blockSize = int.MaxValue; // skip the appended checksum fileBytes = fileBytes.Take(fileBytes.Length - 4).ToArray(); int fileCursor = 0; uint currentChecksum = 0xFFFFFFFF; while (fileCursor < fileBytes.Length) { byte[] blockToRead = fileBytes.Skip(fileCursor).Take(blockSize).ToArray(); fileCursor += blockSize; currentChecksum = CaesarReader.CrcAccumulate(blockToRead, currentChecksum); } return(currentChecksum); }
public FlashDescriptionHeader(BinaryReader reader, long baseAddress) { BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong flashBitFlags = reader.ReadUInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref flashBitFlags, reader, baseAddress); Description = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); FlashAreaName = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); FlashTableStructureCount = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); FlashTableStructureOffset = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); NumberOfUploads = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); UploadTableRefTable = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); NumberOfIdentServices = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); IdentServicesOffset = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); UniqueObjectID = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); unkb = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); unkc = CaesarReader.ReadBitflagInt32(ref flashBitFlags, reader); }
public long GetFlashDataOffset(BinaryReader reader) { reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); reader.ReadUInt16(); CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier CaesarReader.ReadBitflagInt32(ref bitflags, reader); // LongName CaesarReader.ReadBitflagInt32(ref bitflags, reader); // Description if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags)) { return(reader.BaseStream.Position); } else { return(-1); } }
public DTC(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu) { ParentECU = parentEcu; PoolIndex = poolIndex; BaseAddress = baseAddress; Language = language; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt16(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Reference_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); #if DEBUG if (bitflags > 0) { Console.WriteLine($"DTC {Qualifier} has additional unparsed fields : 0x{bitflags:X}"); } #endif }
public long GetCALInt16Offset(BinaryReader reader) { reader.BaseStream.Seek(BaseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); ulong bitflagExtended = reader.ReadUInt32(); CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); // Qualifier CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Name CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); // Description CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // Type CaesarReader.ReadBitflagUInt16(ref bitflags, reader); // IsExecutable if (CaesarReader.CheckAndAdvanceBitflag(ref bitflags)) { return(reader.BaseStream.Position); } else { return(-1); } }
public CaesarFlashContainer(byte[] fileBytes) { FileBytes = fileBytes; // from DIOpenCFF using (BinaryReader reader = new BinaryReader(new MemoryStream(fileBytes))) { byte[] header = reader.ReadBytes(StubHeader.StubHeaderSize); int cffHeaderSize = reader.ReadInt32(); byte[] cffHeaderData = reader.ReadBytes(cffHeaderSize); uint computedChecksum = CaesarReader.ComputeFileChecksumLazy(fileBytes); uint providedChecksum = ReadFileChecksum(fileBytes); if (computedChecksum != providedChecksum) { Console.WriteLine($"WARNING: Checksum mismatch : computed/provided: {computedChecksum:X8}/{providedChecksum:X8}"); } ReadFlashCFF(reader); // fix this ReadCTF(reader); } }
public ECUInterfaceSubtype(BinaryReader reader, long baseAddress, int index) { Index = index; BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); // we can now properly operate on the interface block ulong ctBitflags = reader.ReadUInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ctBitflags, reader, BaseAddress); Name_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader, -1); Unk3 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader); Unk4 = CaesarReader.ReadBitflagInt16(ref ctBitflags, reader); Unk5 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader); Unk6 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader); Unk7 = CaesarReader.ReadBitflagInt32(ref ctBitflags, reader); Unk8 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader); Unk9 = CaesarReader.ReadBitflagUInt8(ref ctBitflags, reader); Unk10 = CaesarReader.ReadBitflagInt8(ref ctBitflags, reader); // might be signed }
public ECUVariant(BinaryReader reader, ECU parentEcu, CTFLanguage language, long baseAddress, int blockSize) { // int __usercall DIIFindVariantByECUID@<eax>(ECU_VARIANT *a1@<ebx>, _DWORD *a2, int a3, __int16 a4, int a5) BaseAddress = baseAddress; ParentECU = parentEcu; Language = language; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); byte[] variantBytes = reader.ReadBytes(blockSize); using (BinaryReader variantReader = new BinaryReader(new MemoryStream(variantBytes))) { ulong bitFlags = variantReader.ReadUInt32(); int skip = variantReader.ReadInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader); Name_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader, -1); UnkStr1 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader); UnkStr2 = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader); Unk1 = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 1 MatchingPatternCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 2 MatchingPatternOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 3 SubsectionB_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 4 SubsectionB_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 5 ComParamsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 6 ComParamsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 7 DiagServiceCode_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 8 DiagServiceCode_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 9 DiagServicesCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 10 DiagServicesOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 11 DTC_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 12 DTC_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 13 EnvironmentCtx_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 14 EnvironmentCtx_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 15 Xref_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 16 Xref_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 17 VCDomainsCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 18 VCDomainsOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 19 NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitFlags, variantReader); UnkByte = CaesarReader.ReadBitflagInt8(ref bitFlags, variantReader); // 20 byte // vcdomain VCDomainPoolOffsets = new List <int>(); variantReader.BaseStream.Seek(VCDomainsOffset, SeekOrigin.Begin); for (int variantCodingIndex = 0; variantCodingIndex < VCDomainsCount; variantCodingIndex++) { VCDomainPoolOffsets.Add(variantReader.ReadInt32()); } // diagnostic services DiagServicesPoolOffsets = new List <int>(); variantReader.BaseStream.Seek(DiagServicesOffset, SeekOrigin.Begin); for (int diagIndex = 0; diagIndex < DiagServicesCount; diagIndex++) { DiagServicesPoolOffsets.Add(variantReader.ReadInt32()); } // DTCs //DTCsPoolOffsets = new List<int>(); DTCsPoolOffsetsWithBounds = new List <Tuple <int, int, int> >(); variantReader.BaseStream.Seek(DTC_Offset, SeekOrigin.Begin); for (int dtcIndex = 0; dtcIndex < DTC_Count; dtcIndex++) { int actualIndex = variantReader.ReadInt32(); int xrefStart = variantReader.ReadInt32(); int xrefCount = variantReader.ReadInt32(); // stitch with table H : int __cdecl DIECUGetNumberOfEnvForAllErrors(DI_ECUINFO *ecuh, int a2, int a3) //DTCsPoolOffsets.Add(actualIndex); // todo: depreciate this DTCsPoolOffsetsWithBounds.Add(new Tuple <int, int, int>(actualIndex, xrefStart, xrefCount)); } // EnvCtxs EnvironmentContextsPoolOffsets = new List <int>(); variantReader.BaseStream.Seek(EnvironmentCtx_Offset, SeekOrigin.Begin); for (int envIndex = 0; envIndex < EnvironmentCtx_Count; envIndex++) { EnvironmentContextsPoolOffsets.Add(variantReader.ReadInt32()); } } CreateVCDomains(parentEcu, language); CreateDiagServices(parentEcu, language); CreateVariantPatterns(reader); CreateComParameters(reader, parentEcu); CreateDTCs(parentEcu, language); CreateEnvironmentContexts(parentEcu, language); CreateXrefs(reader, parentEcu, language); //PrintDebug(); }
public static uint ComputeFileChecksumLazy(byte[] fileBytes) { return(CaesarReader.CrcAccumulate(fileBytes, 0xFFFFFFFF, fileBytes.Length - 4)); }
public ECU(BinaryReader reader, CTFLanguage language, CFFHeader header, long baseAddress, CaesarContainer parentContainer) { ParentContainer = parentContainer; BaseAddress = baseAddress; // Read 32+16 bits ulong ecuBitFlags = reader.ReadUInt32(); // after exhausting the 32 bits, load these additional 16 bits ulong ecuBitFlagsExtended = reader.ReadUInt16(); // Console.WriteLine($"ECU bitflags: {ecuBitFlags:X}"); // advancing forward to ecuBase + 10 int ecuHdrIdk1 = reader.ReadInt32(); // no idea // Console.WriteLine($"Skipping: {ecuHdrIdk1:X8}"); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress); EcuName_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1); EcuDescription_CTF = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1); EcuXmlVersion = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress); InterfaceBlockCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); InterfaceTableOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); SubinterfacesCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); SubinterfacesOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); EcuClassName = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress); UnkStr7 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress); UnkStr8 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress); int dataBufferOffsetRelativeToFile = header.StringPoolSize + StubHeader.StubHeaderSize + header.CffHeaderSize + 4; // Console.WriteLine($"{nameof(dataBufferOffsetRelativeToFile)} : 0x{dataBufferOffsetRelativeToFile:X}"); IgnitionRequired = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader); Unk2 = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader); UnkBlockCount = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader); UnkBlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); EcuSgmlSource = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader); Unk6RelativeOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); EcuVariant_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; EcuVariant_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); EcuVariant_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); EcuVariant_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); DiagJob_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; DiagJob_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); DiagJob_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); DiagJob_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Dtc_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; Dtc_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Dtc_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Dtc_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Env_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; Env_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Env_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // bitflags will be exhausted at this point, load the extended bitflags ecuBitFlags = ecuBitFlagsExtended; Env_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); VcDomain_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; VcDomain_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); VcDomain_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); VcDomain_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Presentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; Presentations_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Presentations_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Presentations_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Info_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; Info_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Info_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Info_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Unk_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile; Unk_EntryCount = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Unk_EntrySize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Unk_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); Unk39 = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader); // read ecu's supported interfaces and subtypes // try to read interface block from the interface buffer table // this address is relative to the definitions block long interfaceTableAddress = BaseAddress + InterfaceTableOffset; // Console.WriteLine($"Interface table address: {interfaceTableAddress:X}, given offset: {interfaceTableOffset:X}"); ECUInterfaces = new List <ECUInterface>(); for (int interfaceBufferIndex = 0; interfaceBufferIndex < InterfaceBlockCount; interfaceBufferIndex++) { // Console.WriteLine($"Parsing interface {interfaceBufferIndex + 1}/{interfaceBlockCount}"); // find our interface block offset reader.BaseStream.Seek(interfaceTableAddress + (interfaceBufferIndex * 4), SeekOrigin.Begin); // seek to the actual block (ambiguity: is this relative to the interface table or the current array?) int interfaceBlockOffset = reader.ReadInt32(); long ecuInterfaceBaseAddress = interfaceTableAddress + interfaceBlockOffset; ECUInterface ecuInterface = new ECUInterface(reader, ecuInterfaceBaseAddress); ECUInterfaces.Add(ecuInterface); } // try to read interface subtype block from the interface buffer table // this address is relative to the definitions block ECUInterfaceSubtypes = new List <ECUInterfaceSubtype>(); long ctTableAddress = BaseAddress + SubinterfacesOffset; // Console.WriteLine($"Interface subtype table address: {ctTableAddress:X}, given offset: {ecuChildTypesOffset:X}"); for (int ctBufferIndex = 0; ctBufferIndex < SubinterfacesCount; ctBufferIndex++) { // Console.WriteLine($"Parsing interface subtype {ctBufferIndex + 1}/{ecuNumberOfEcuChildTypes}"); // find our ct block offset reader.BaseStream.Seek(ctTableAddress + (ctBufferIndex * 4), SeekOrigin.Begin); // seek to the actual block (ambiguity: is this relative to the ct table or the current array?) int actualBlockOffset = reader.ReadInt32(); long ctBaseAddress = ctTableAddress + actualBlockOffset; ECUInterfaceSubtype ecuInterfaceSubtype = new ECUInterfaceSubtype(reader, ctBaseAddress, ctBufferIndex); ECUInterfaceSubtypes.Add(ecuInterfaceSubtype); } CreateDiagServices(reader, language); CreateEcuVariants(reader, language); CreatePresentations(reader, language); ECUDescriptionTranslated = language.GetString(EcuDescription_CTF); }
public VCDomain(BinaryReader reader, ECU parentEcu, CTFLanguage language, int variantCodingDomainEntry) { ParentECU = parentEcu; byte[] variantCodingPool = parentEcu.ReadVarcodingPool(reader); using (BinaryReader poolReader = new BinaryReader(new MemoryStream(variantCodingPool))) { poolReader.BaseStream.Seek(variantCodingDomainEntry * parentEcu.VcDomain_EntrySize, SeekOrigin.Begin); int entryOffset = poolReader.ReadInt32(); int entrySize = poolReader.ReadInt32(); uint entryCrc = poolReader.ReadUInt32(); long vcdBlockAddress = entryOffset + parentEcu.VcDomain_BlockOffset; // Console.WriteLine($"VCD Entry @ 0x{entryOffset:X} with size 0x{entrySize:X} and CRC {entryCrc:X8}, abs addr {vcdBlockAddress:X8}"); long baseAddress = vcdBlockAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt16(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); ReadServiceName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); WriteServiceName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); FragmentCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader); FragmentTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader) + (int)baseAddress; // demoting long (warning) DumpSize = CaesarReader.ReadBitflagInt32(ref bitflags, reader); DefaultStringCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader); StringTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk1 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); // PrintDebug(); VCFragments = new List <VCFragment>(); for (int fragmentIndex = 0; fragmentIndex < FragmentCount; fragmentIndex++) { VCFragment fragment = new VCFragment(reader, this, FragmentTableOffset, fragmentIndex, language); VCFragments.Add(fragment); } // ValidateFragmentCoverage(); if (DefaultStringCount > 0) { DefaultData = new List <Tuple <string, byte[]> >(); long stringTableBaseAddress = StringTableOffset + baseAddress; // this could almost be a class of its own but there isn't a distinct name to it for (int stringTableIndex = 0; stringTableIndex < DefaultStringCount; stringTableIndex++) { reader.BaseStream.Seek(stringTableBaseAddress + (4 * stringTableIndex), SeekOrigin.Begin); int offset = reader.ReadInt32(); long stringBaseAddress = stringTableBaseAddress + offset; reader.BaseStream.Seek(stringBaseAddress, SeekOrigin.Begin); ulong strBitflags = reader.ReadUInt16(); int nameUsuallyAbsent_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1); int offsetToBlob = CaesarReader.ReadBitflagInt32(ref strBitflags, reader); int blobSize = CaesarReader.ReadBitflagInt32(ref strBitflags, reader); int valueType_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1); string noIdeaStr1 = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress); int noIdea2_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1); int noIdea3 = CaesarReader.ReadBitflagInt16(ref strBitflags, reader); string noIdeaStr2 = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress); byte[] blob = new byte[] { }; if (blobSize > 0) { long blobFileAddress = stringBaseAddress + offsetToBlob; reader.BaseStream.Seek(blobFileAddress, SeekOrigin.Begin); blob = reader.ReadBytes(blobSize); // memcpy } string valueType = language.GetString(valueType_T); DefaultData.Add(new Tuple <string, byte[]>(valueType, blob)); //Console.WriteLine($"Blob: {BitUtility.BytesToHex(blob)} @ {valueType}"); //Console.WriteLine($"String base address: 0x{stringBaseAddress:X}"); } } } }
public DSCContext(byte[] dscContainerBytes) { const int fnTableEntrySize = 50; using (BinaryReader reader = new BinaryReader(new MemoryStream(dscContainerBytes))) { reader.BaseStream.Seek(0x10, SeekOrigin.Begin); int fnTableOffset = reader.ReadInt32(); // @ 0x10, originally i16 int numberOfFunctions = reader.ReadInt16(); // @ 0x14 int dscOffsetA = reader.ReadInt32(); // @ 0x16, originally i16 int caesarHash = reader.ReadInt16(); // @ 0x1A, size is u32? int idk_field_1c = reader.ReadInt16(); // ?? @ 1C, padding int globalVarAllocSize = reader.ReadInt16(); // @ 1E int idk_field_20 = reader.ReadInt16(); // ?? @ 20, padding int globalVariablesBufferPtr = reader.ReadInt32(); // ?? @ 22 int globalVariablesCount = reader.ReadInt16(); // ?? @ 26 int globalVariablesIdk1 = reader.ReadInt32(); // ?? @ 28 int globalVariablesIdk2 = reader.ReadInt16(); // ?? @ 2C int globalVariablesPreinitBufferPtr = reader.ReadInt32(); // ?? @ 2E int globalVariablesBytesToRead = reader.ReadInt16(); // ?? @ 32 byte[] globalVarByteBuffer = new byte[globalVarAllocSize]; Console.WriteLine($"{nameof(dscOffsetA)} : {dscOffsetA} (0x{dscOffsetA:X})\n"); Console.WriteLine($"{nameof(caesarHash)} : {caesarHash} (0x{caesarHash:X})\n"); Console.WriteLine($"{nameof(globalVarAllocSize)} : {globalVarAllocSize} (0x{globalVarAllocSize:X})\n"); Console.WriteLine($"{nameof(globalVariablesBufferPtr)} : {globalVariablesBufferPtr} (0x{globalVariablesBufferPtr:X})"); Console.WriteLine($"{nameof(globalVariablesCount)} : {globalVariablesCount} (0x{globalVariablesCount:X})\n"); Console.WriteLine($"{nameof(globalVariablesIdk1)} : {globalVariablesIdk1} (0x{globalVariablesIdk1:X})"); Console.WriteLine($"{nameof(globalVariablesIdk2)} : {globalVariablesIdk2} (0x{globalVariablesIdk2:X})\n"); Console.WriteLine($"{nameof(globalVariablesPreinitBufferPtr)} : {globalVariablesPreinitBufferPtr} (0x{globalVariablesPreinitBufferPtr:X})"); Console.WriteLine($"{nameof(globalVariablesBytesToRead)} : {globalVariablesBytesToRead} (0x{globalVariablesBytesToRead:X})\n"); // assemble global vars: MIGlobalVarBuild (parent: MIInterpreterRun) int gvBytesRemaining = globalVariablesBytesToRead; reader.BaseStream.Seek(globalVariablesPreinitBufferPtr, SeekOrigin.Begin); while (gvBytesRemaining > 0) { int gvAddress = reader.ReadInt16(); int gvSize = reader.ReadByte(); byte[] gvData = reader.ReadBytes(gvSize); Console.WriteLine($"GV Fill: 0x{gvAddress:X} ({gvSize} bytes) : {BitUtility.BytesToHex(gvData)}"); Buffer.BlockCopy(gvData, 0, globalVarByteBuffer, gvAddress, gvSize); gvBytesRemaining -= gvSize; gvBytesRemaining -= 3; } if (gvBytesRemaining != 0) { throw new Exception("Global variable preinit has leftover data in the read cursor"); } // CreateGlobalVar for (int gvIndex = 0; gvIndex < globalVariablesCount; gvIndex++) { /* * guesses: * base * 1 -> char * 2 -> word * 3 -> dword * * * derived * 1 -> native * 2 -> array * 3 -> pointer * */ reader.BaseStream.Seek(globalVariablesBufferPtr + (gvIndex * 12), SeekOrigin.Begin); int varName = reader.ReadInt32(); DSCBasicType baseType = (DSCBasicType)reader.ReadInt16(); DSCDerivedType derivedType = (DSCDerivedType)reader.ReadInt16(); int arraySize = reader.ReadInt16(); int positionInGlobalBuffer = reader.ReadInt16(); reader.BaseStream.Seek(varName, SeekOrigin.Begin); string varNameResolved = CaesarReader.ReadStringFromBinaryReader(reader, CaesarReader.DefaultEncoding); int dataSizeInBytes = GetDscTypeSize((int)baseType, (int)derivedType); if (derivedType == DSCDerivedType.Array) { dataSizeInBytes *= arraySize; } byte[] varBytes = new byte[dataSizeInBytes]; Buffer.BlockCopy(globalVarByteBuffer, positionInGlobalBuffer, varBytes, 0, dataSizeInBytes); Console.WriteLine($"\nVar: {baseType}/{derivedType} [{arraySize}] @ {positionInGlobalBuffer} : {varNameResolved}"); Console.WriteLine($"{BitUtility.BytesToHex(varBytes)}"); // actual insertion into global var list is in MIGlobalVarCallback, stored in interpreter's ->GlobalVarList } for (int fnIndex = 0; fnIndex < numberOfFunctions; fnIndex++) { long fnBaseAddress = fnTableEntrySize * fnIndex + fnTableOffset; reader.BaseStream.Seek(fnBaseAddress, SeekOrigin.Begin); int fnIdentifier = reader.ReadInt16(); // @ 0 int fnNameOffset = reader.ReadInt32(); // @ 2 // not exactly sure if int32 is right -- the first fn's ep looks incorrect in both cases. // 16 bit would limit the filesize to ~32KB which seems unlikely int fnEntryPoint = reader.ReadInt32(); // @ 6 //int fnEntryPoint = reader.ReadInt16(); // @ 6 //int fnIdkIsThisStandalone = reader.ReadInt16(); // @ 6 reader.BaseStream.Seek(fnBaseAddress + 38, SeekOrigin.Begin); int inputParamOffset = reader.ReadInt32(); // @ 38 int inputParamCount = reader.ReadInt16(); // @ 42 int outputParamOffset = reader.ReadInt32(); // @ 44 int outputParamCount = reader.ReadInt16(); // @ 48 reader.BaseStream.Seek(fnNameOffset, SeekOrigin.Begin); string fnName = CaesarReader.ReadStringFromBinaryReader(reader); Console.WriteLine($"Fn: {fnName} Ordinal: {fnIdentifier} EP: 0x{fnEntryPoint:X}, InParam: {inputParamCount} @ 0x{inputParamOffset:X}, OutParam: {outputParamCount} @ 0x{outputParamOffset}"); // the EP points to an int16 to initialize the stack height // after the EP, the raw bytecode can be directly interpreted } } }