// 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(); }
// 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]; } }
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 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 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 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 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 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 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 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 DiagService(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu) { ParentECU = parentEcu; PoolIndex = poolIndex; BaseAddress = baseAddress; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); ulong bitflagExtended = reader.ReadUInt32(); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); DataClass_ServiceType = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); DataClass_ServiceTypeShifted = 1 << (DataClass_ServiceType - 1); IsExecutable = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);; ClientAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);; SecurityAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);; T_ComParam_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); T_ComParam_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Q_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Q_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); R_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); R_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); InputRefNameMaybe = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); U_prep_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); U_prep_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); // array of DWORDs, probably reference to elsewhere V_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); V_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); RequestBytes_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader); RequestBytes_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); W_OutPres_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); W_OutPres_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); field50 = CaesarReader.ReadBitflagUInt16(ref bitflags, reader); NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); // negative response name UnkStr3 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); UnkStr4 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); P_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); P_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); DiagServiceCodeCount = CaesarReader.ReadBitflagInt32(ref bitflags, reader); DiagServiceCodeOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); S_Count = CaesarReader.ReadBitflagInt16(ref bitflags, reader); S_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); bitflags = bitflagExtended; X_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); X_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Y_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Y_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Z_Count = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Z_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader); if (RequestBytes_Count > 0) { reader.BaseStream.Seek(baseAddress + RequestBytes_Offset, SeekOrigin.Begin); RequestBytes = reader.ReadBytes(RequestBytes_Count); } else { RequestBytes = new byte[] { }; } // u_table to u_entries InputPreparations = new List <DiagPreparation>(); for (int prepIndex = 0; prepIndex < U_prep_Count; prepIndex++) { long presentationTableOffset = baseAddress + U_prep_Offset; reader.BaseStream.Seek(presentationTableOffset + (prepIndex * 10), SeekOrigin.Begin); // DIOpenDiagService (reads 4, 4, 2 then calls DiagServiceReadPresentation) to build a presentation int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW) int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW) ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W) DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this); //preparation.PrintDebug(); InputPreparations.Add(preparation); } OutputPreparations = new List <List <DiagPreparation> >(); long outPresBaseAddress = BaseAddress + W_OutPres_Offset; for (int presIndex = 0; presIndex < W_OutPres_Count; presIndex++) { reader.BaseStream.Seek(outPresBaseAddress + (presIndex * 8), SeekOrigin.Begin); int resultPresentationCount = reader.ReadInt32(); int resultPresentationOffset = reader.ReadInt32(); List <DiagPreparation> ResultPresentationSet = new List <DiagPreparation>(); for (int presInnerIndex = 0; presInnerIndex < resultPresentationCount; presInnerIndex++) { long presentationTableOffset = outPresBaseAddress + resultPresentationOffset; reader.BaseStream.Seek(presentationTableOffset + (presIndex * 10), SeekOrigin.Begin); int prepEntryOffset = reader.ReadInt32(); // file: 0 (DW) int prepEntryBitPos = reader.ReadInt32(); // file: 4 (DW) ushort prepEntryMode = reader.ReadUInt16(); // file: 8 (W) DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this); ResultPresentationSet.Add(preparation); } OutputPreparations.Add(ResultPresentationSet); } DiagComParameters = new List <ComParameter>(); long comParamTableBaseAddress = BaseAddress + T_ComParam_Offset; for (int cpIndex = 0; cpIndex < T_ComParam_Count; cpIndex++) { reader.BaseStream.Seek(comParamTableBaseAddress + (cpIndex * 4), SeekOrigin.Begin); int resultCpOffset = reader.ReadInt32(); long cpEntryBaseAddress = comParamTableBaseAddress + resultCpOffset; ComParameter cp = new ComParameter(reader, cpEntryBaseAddress, parentEcu.ECUInterfaces); DiagComParameters.Add(cp); } // DJ_Zugriffsberechtigung_Abgleich // DJ_Zugriffsberechtigung // DT_Abgasklappe_kontinuierlich // FN_HardReset // WVC_Implizite_Variantenkodierung_Write // NR_Disable_Resp_required noexec // DT_Laufzeiten_Resetzaehler_nicht_implementiert exec /* * if (false && qualifierName.Contains("RVC_SCN_Variantencodierung_VGS_73_Lesen")) * { * * Console.WriteLine($"{nameof(field50)} : {field50}"); * Console.WriteLine($"{nameof(IsExecutable)} : {IsExecutable} {IsExecutable != 0}"); * Console.WriteLine($"{nameof(AccessLevel)} : {AccessLevel}"); * Console.WriteLine($"{nameof(SecurityAccessLevel)} : {SecurityAccessLevel}"); * Console.WriteLine($"{nameof(DataClass)} : {DataClass}"); * * * * Console.WriteLine($"{qualifierName} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, Preparation: {U_prep_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}"); * Console.WriteLine($"at 0x{baseAddress:X}, W @ 0x{W_Offset:X}, DSC @ 0x{DiagServiceCodeOffset:X}"); * Console.WriteLine($"ReqBytes: {BitUtility.BytesToHex(RequestBytes)}"); * } */ //Console.WriteLine($"{qualifierName} - O: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, U: {U_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}"); byte[] dscPool = parentEcu.ParentContainer.CaesarCFFHeader.DSCPool; long dscTableBaseAddress = BaseAddress + DiagServiceCodeOffset; using (BinaryReader dscPoolReader = new BinaryReader(new MemoryStream(dscPool))) { for (int dscIndex = 0; dscIndex < DiagServiceCodeCount; dscIndex++) { reader.BaseStream.Seek(dscTableBaseAddress + (4 * dscIndex), SeekOrigin.Begin); long dscEntryBaseAddress = reader.ReadInt32() + dscTableBaseAddress; reader.BaseStream.Seek(dscEntryBaseAddress, SeekOrigin.Begin); ulong dscEntryBitflags = reader.ReadUInt16(); uint idk1 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader); uint idk2 = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader); int dscPoolOffset = CaesarReader.ReadBitflagInt32(ref dscEntryBitflags, reader); string dscQualifier = CaesarReader.ReadBitflagStringWithReader(ref dscEntryBitflags, reader, dscEntryBaseAddress); dscPoolReader.BaseStream.Seek(dscPoolOffset * 8, SeekOrigin.Begin); long dscRecordOffset = dscPoolReader.ReadInt32() + parentEcu.ParentContainer.CaesarCFFHeader.DscBlockOffset; int dscRecordSize = dscPoolReader.ReadInt32(); reader.BaseStream.Seek(dscRecordOffset, SeekOrigin.Begin); // Console.WriteLine($"DSC {qualifierName} @ 0x{dscTableBaseAddress:X8} {idk1}/{idk2} pool @ 0x{dscPoolOffset:X}, name: {dscQualifier}"); byte[] dscBytes = reader.ReadBytes(dscRecordSize); #if DEBUG //string dscName = $"{parentEcu.Qualifier}_{Qualifier}_{dscIndex}.pal"; //Console.WriteLine($"Exporting DSC: {dscName}"); //File.WriteAllBytes(dscName, dscBytes); #endif // at this point, the DSC binary is available in dscBytes, intended for use in DSCContext (but is currently unimplemented) // Console.WriteLine($"DSC actual at 0x{dscRecordOffset:X}, size=0x{dscRecordSize:X}\n"); } } }
// 0x05 [6, 4,4,4,4, 4,4,4,4, 4,4,4,4, 2,2,2,4, 4,4,4,4, 4,4,4,4, 4,4,1,1, 1,1,1,4, 4,4,2,4, 4,4], public DiagPresentation(BinaryReader reader, long baseAddress, int presentationsIndex, CTFLanguage language) { BaseAddress = baseAddress; PresentationIndex = presentationsIndex; Language = language; reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin); ulong bitflags = reader.ReadUInt32(); ulong extendedBitflags = reader.ReadUInt16(); // skip 2 bytes Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress); Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); ScaleTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); ScaleCountMaybe = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk6 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk7 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk8 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk9 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UnkA = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UnkB = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UnkC = CaesarReader.ReadBitflagInt32(ref bitflags, reader); UnkD = CaesarReader.ReadBitflagInt16(ref bitflags, reader); UnkE = CaesarReader.ReadBitflagInt16(ref bitflags, reader); UnkF = CaesarReader.ReadBitflagInt16(ref bitflags, reader); DisplayedUnit_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk11 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk12 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); EnumMaxValue = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk14 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk15 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Description2_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk17 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk18 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk19 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); TypeLength_1A = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk1b = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1); Type_1C = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1); Unk1d = CaesarReader.ReadBitflagInt8(ref bitflags, reader); EnumType_1E = CaesarReader.ReadBitflagInt8(ref bitflags, reader); Unk1F = CaesarReader.ReadBitflagInt8(ref bitflags, reader); Unk20 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); bitflags = extendedBitflags; TypeLengthBytesMaybe_21 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1); Unk23 = CaesarReader.ReadBitflagInt16(ref bitflags, reader); Unk24 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk25 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); Unk26 = CaesarReader.ReadBitflagInt32(ref bitflags, reader); long scaleTableBase = BaseAddress + ScaleTableOffset; Scales = new List <Scale>(); for (int i = 0; i < ScaleCountMaybe; i++) { reader.BaseStream.Seek(scaleTableBase + (i * 4), SeekOrigin.Begin); int entryRelativeOffset = reader.ReadInt32(); Scale scale = new Scale(reader, scaleTableBase + entryRelativeOffset, language); Scales.Add(scale); } }
public VCFragment(BinaryReader reader, VCDomain parentDomain, long fragmentTable, int fragmentIndex, CTFLanguage language, ECU parentEcu) { // see DIOpenVarCodeFrag ParentDomain = parentDomain; ParentECU = parentEcu; long fragmentTableEntry = fragmentTable + (10 * fragmentIndex); reader.BaseStream.Seek(fragmentTableEntry, SeekOrigin.Begin); // no bitflag required for 10-byte table entry since it is mandatory int fragmentNewBaseOffset = reader.ReadInt32(); ByteBitPos = reader.ReadInt32(); ImplementationType = reader.ReadUInt16(); // Console.WriteLine($"Fragment new base @ 0x{fragmentNewBaseOffset:X}, byteBitPos 0x{fragmentByteBitPos:X}, implementationType: 0x{implementationType:X}"); long fragmentBaseAddress = fragmentTable + fragmentNewBaseOffset; reader.BaseStream.Seek(fragmentBaseAddress, SeekOrigin.Begin); ulong fragmentBitflags = reader.ReadUInt32(); // Console.WriteLine($"Fragment new bitflag @ 0x{fragmentBitflags:X}"); Name_CTF = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1); Description_CTF = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1); ReadAccessLevel = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader); WriteAccessLevel = CaesarReader.ReadBitflagUInt8(ref fragmentBitflags, reader); ByteOrder = CaesarReader.ReadBitflagUInt16(ref fragmentBitflags, reader); RawBitLength = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader); IttOffset = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader); InfoPoolIndex = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1); MeaningB = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1); MeaningC = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader, -1); CCFHandle = CaesarReader.ReadBitflagInt16(ref fragmentBitflags, reader, -1); VarcodeDumpSize = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader); VarcodeDump = CaesarReader.ReadBitflagDumpWithReader(ref fragmentBitflags, reader, VarcodeDumpSize, fragmentBaseAddress); SubfragmentCount = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader); SubfragmentFileOffset = CaesarReader.ReadBitflagInt32(ref fragmentBitflags, reader); Qualifier = CaesarReader.ReadBitflagStringWithReader(ref fragmentBitflags, reader, fragmentBaseAddress); // Console.WriteLine($"{nameof(fragmentName)} : {fragmentName}, child {fragmentNoOfSubFragments} @ 0x{fragmentSubfragmentFileOffset:X} base {fragmentBaseAddress:X}"); if ((ByteOrder != 0) && (BitLength > 0)) { //throw new Exception("Currently assumes everything is little-endian"); Console.WriteLine($"WARNING: {Qualifier} (Size: {BitLength}) has an unsupported byte order. Please proceed with caution"); //PrintDebug(true); } long subfragmentTableAddress = SubfragmentFileOffset + fragmentBaseAddress; Subfragments.Clear(); for (int subfragmentIndex = 0; subfragmentIndex < SubfragmentCount; subfragmentIndex++) { reader.BaseStream.Seek(subfragmentTableAddress + (subfragmentIndex * 4), SeekOrigin.Begin); long subfragmentAddress = reader.ReadInt32() + subfragmentTableAddress; VCSubfragment subfragment = new VCSubfragment(reader, this, language, subfragmentAddress); Subfragments.Add(subfragment); } // PrintDebug(); // Console.WriteLine($"implementation-default : {implementationType:X4} upper: {(implementationType & 0xFF0):X4} lower: {(implementationType & 0xF):X4}"); FindFragmentSize(reader); }