private void CreateEnvironmentContexts(ECU parentEcu, CTFLanguage language) { /* * EnvironmentContexts = new EnvironmentContext[EnvironmentContextsPoolOffsets.Count]; * * foreach (EnvironmentContext env in parentEcu.GlobalEnvironmentContexts) * { * for (int i = 0; i < EnvironmentContextsPoolOffsets.Count; i++) * { * if (env.PoolIndex == EnvironmentContextsPoolOffsets[i]) * { * EnvironmentContexts[i] = env; * } * } * } */ EnvironmentContexts = new DiagService[EnvironmentContextsPoolOffsets.Count]; foreach (DiagService env in parentEcu.GlobalEnvironmentContexts) { for (int i = 0; i < EnvironmentContextsPoolOffsets.Count; i++) { if (env.PoolIndex == EnvironmentContextsPoolOffsets[i]) { EnvironmentContexts[i] = env; } } } }
// 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 void Restore(CTFLanguage language, ECU parentEcu) { ParentECU = parentEcu; foreach (VCFragment fragment in VCFragments) { fragment.Restore(parentEcu, this, language); } }
private void CreateVCDomains(BinaryReader reader, ECU parentEcu, CTFLanguage language) { VCDomains = new List <VCDomain>(); foreach (int variantCodingDomainEntry in VCDomainPoolOffsets) { VCDomain vcDomain = new VCDomain(reader, parentEcu, language, variantCodingDomainEntry); VCDomains.Add(vcDomain); } }
private void CreateXrefs(BinaryReader reader, ECU parentEcu, CTFLanguage language) { Xrefs = new int[Xref_Count]; reader.BaseStream.Seek(BaseAddress + Xref_Offset, SeekOrigin.Begin); for (int i = 0; i < Xref_Count; i++) { Xrefs[i] = reader.ReadInt32(); } }
public void Restore(ECU parentEcu, VCDomain parentDomain, CTFLanguage language) { ParentECU = parentEcu; ParentDomain = parentDomain; foreach (VCSubfragment subfragment in Subfragments) { subfragment.Restore(language); } }
private void CreateDTCs(ECU parentEcu, CTFLanguage language) { int dtcPoolSize = DTCsPoolOffsetsWithBounds.Count; DTCs = new DTC[dtcPoolSize]; for (int i = 0; i < dtcPoolSize; i++) { if (i == DTCsPoolOffsetsWithBounds[i].Item1) { DTCs[i] = parentEcu.GlobalDTCs[i]; DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2; DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3; } } DTCsPoolOffsetsWithBounds.Sort((x, y) => x.Item1.CompareTo(y.Item1)); int lowestIndex = 0; int loopMax = ParentECU.GlobalDTCs.Count; for (int i = 0; i < dtcPoolSize; i++) { if (DTCs[i] != null) { continue; } for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++) { if (ParentECU.GlobalDTCs[globalIndex].PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1) { DTCs[i] = parentEcu.GlobalDTCs[globalIndex]; DTCs[i].XrefStart = DTCsPoolOffsetsWithBounds[i].Item2; DTCs[i].XrefCount = DTCsPoolOffsetsWithBounds[i].Item3; lowestIndex = globalIndex; break; } } } /* * // same thing as above, just more readable and slower * foreach (DTC dtc in parentEcu.GlobalDTCs) * { * for (int i = 0; i < DTCsPoolOffsetsWithBounds.Count; i++) * { * if (dtc.PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1) * { * // this is only valid on the assumption that DTC instances are unique (e.g. not shared from a base variant) * dtc.XrefStart = DTCsPoolOffsetsWithBounds[i].Item2; * dtc.XrefCount = DTCsPoolOffsetsWithBounds[i].Item3; * DTCs[i] = dtc; * } * } * } */ }
private void CreateVCDomains(ECU parentEcu, CTFLanguage language) { VCDomains = new List <VCDomain>(); foreach (int variantCodingDomainEntry in VCDomainPoolOffsets) { /* * VCDomain vcDomain = new VCDomain(reader, parentEcu, language, variantCodingDomainEntry); * VCDomains.Add(vcDomain); */ VCDomains.Add(ParentECU.GlobalVCDs[variantCodingDomainEntry]); } }
private void CreateDiagServices(ECU parentEcu, CTFLanguage language) { // unlike variant domains, storing references to the parent objects in the ecu is preferable since this is relatively larger //DiagServices = new List<DiagService>(); DiagServices = new DiagService[DiagServicesPoolOffsets.Count]; /* * // computationally expensive, 40ish % runtime is spent here * // easier to read, below optimization essentially accomplishes this in a shorter period * * foreach (DiagService diagSvc in parentEcu.GlobalDiagServices) * { * for (int i = 0; i < DiagServicesPoolOffsets.Count; i++) * { * if (diagSvc.PoolIndex == DiagServicesPoolOffsets[i]) * { * DiagServices[i] = diagSvc; * } * } * } */ // optimization hack int poolSize = DiagServicesPoolOffsets.Count; for (int i = 0; i < poolSize; i++) { if (i == DiagServicesPoolOffsets[i]) { DiagServices[i] = parentEcu.GlobalDiagServices[i]; } } DiagServicesPoolOffsets.Sort(); int lowestIndex = 0; int loopMax = parentEcu.GlobalDiagServices.Count; for (int i = 0; i < poolSize; i++) { if (DiagServices[i] != null) { continue; } for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++) { if (parentEcu.GlobalDiagServices[globalIndex].PoolIndex == DiagServicesPoolOffsets[i]) { DiagServices[i] = parentEcu.GlobalDiagServices[globalIndex]; lowestIndex = globalIndex; break; } } } }
private void CreateEnvironmentContexts(ECU parentEcu, CTFLanguage language) { int envPoolSize = EnvironmentContextsPoolOffsets.Count; EnvironmentContexts = new DiagService[envPoolSize]; for (int i = 0; i < envPoolSize; i++) { if (i == EnvironmentContextsPoolOffsets[i]) { EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[i]; } } EnvironmentContextsPoolOffsets.Sort(); int lowestIndex = 0; int loopMax = parentEcu.GlobalEnvironmentContexts.Count; for (int i = 0; i < envPoolSize; i++) { if (EnvironmentContexts[i] != null) { continue; } for (int globalIndex = lowestIndex; globalIndex < loopMax; globalIndex++) { if (parentEcu.GlobalEnvironmentContexts[globalIndex].PoolIndex == EnvironmentContextsPoolOffsets[i]) { EnvironmentContexts[i] = parentEcu.GlobalEnvironmentContexts[globalIndex]; lowestIndex = globalIndex; break; } } } /* * // same thing, more readable, much slower * foreach (DiagService env in parentEcu.GlobalEnvironmentContexts) * { * for (int i = 0; i < EnvironmentContextsPoolOffsets.Count; i++) * { * if (env.PoolIndex == EnvironmentContextsPoolOffsets[i]) * { * EnvironmentContexts[i] = env; * } * } * } */ }
private void CreateDTCs(ECU parentEcu, CTFLanguage language) { DTCs = new DTC[DTCsPoolOffsetsWithBounds.Count]; foreach (DTC dtc in parentEcu.GlobalDTCs) { for (int i = 0; i < DTCsPoolOffsetsWithBounds.Count; i++) { if (dtc.PoolIndex == DTCsPoolOffsetsWithBounds[i].Item1) { // this is only valid on the assumption that DTC instances are unique (e.g. not shared from a base variant) dtc.XrefStart = DTCsPoolOffsetsWithBounds[i].Item2; dtc.XrefCount = DTCsPoolOffsetsWithBounds[i].Item3; DTCs[i] = dtc; } } } }
public void Restore(CTFLanguage language, ECU parentEcu) { Language = language; ParentECU = parentEcu; CreateVCDomains(parentEcu, language); CreateDiagServices(parentEcu, language); CreateDTCs(parentEcu, language); CreateEnvironmentContexts(parentEcu, language); /* * // no restoring required * foreach (ECUVariantPattern vp in VariantPatterns) * { * vp.Restore(); * } */ // CreateComParameters(reader, parentEcu); // already serialized in json }
private void CreateDiagServices(BinaryReader reader, ECU parentEcu, CTFLanguage language) { // unlike variant domains, storing references to the parent objects in the ecu is preferable since this is relatively larger //DiagServices = new List<DiagService>(); // computationally expensive, 40ish % runtime is spent here DiagServices = new DiagService[DiagServicesPoolOffsets.Count]; foreach (DiagService diagSvc in parentEcu.GlobalDiagServices) { for (int i = 0; i < DiagServicesPoolOffsets.Count; i++) { if (diagSvc.PoolIndex == DiagServicesPoolOffsets[i]) { DiagServices[i] = diagSvc; } } } }
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 void CreateComParameters(BinaryReader reader, ECU parentEcu) { // this is unusual as it doesn't use the usual caesar-style bitflag reads // for reasons unknown the comparam is attached to the basevariant long comparamBaseAddress = BaseAddress + ComParamsOffset; // Console.WriteLine($"Comparam base: 0x{comparamBaseAddress:X} : number of comparams: {ComParamsCount} "); reader.BaseStream.Seek(comparamBaseAddress, SeekOrigin.Begin); List <long> comparameterOffsets = new List <long>(); for (int comIndex = 0; comIndex < ComParamsCount; comIndex++) { comparameterOffsets.Add(reader.ReadInt32() + comparamBaseAddress); } if (parentEcu.ECUInterfaces.Count == 0) { throw new Exception("Invalid communication parameter : no parent interface"); } foreach (long comparamOffset in comparameterOffsets) { ComParameter param = new ComParameter(reader, comparamOffset, parentEcu.ECUInterfaces, Language); // KW2C3PE uses a different parent addressing style int parentIndex = param.ParentInterfaceIndex > 0 ? param.ParentInterfaceIndex : param.SubinterfaceIndex; if (param.ParentInterfaceIndex >= parentEcu.ECUInterfaceSubtypes.Count) { throw new Exception("ComParam: tried to assign to nonexistent interface"); } else { parentEcu.ECUInterfaceSubtypes[parentIndex].CommunicationParameters.Add(param); } } }
public void Restore(CTFLanguage language, ECU parentEcu) { Language = language; ParentECU = parentEcu; foreach (DiagPreparation dp in InputPreparations) { dp.Restore(language, parentEcu, this); } foreach (List <DiagPreparation> dpl in OutputPreparations) { foreach (DiagPreparation dp in dpl) { dp.Restore(language, parentEcu, this); } } /* * // nothing in comparam to restore * foreach (ComParameter cp in DiagComParameters) * { * * } */ }
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); }
public void Restore(CTFLanguage language, ECU parentEcu) { ParentECU = parentEcu; Language = language; }
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"); } } }
private void FindFragmentSize(BinaryReader reader) { ImplementationUpper = ImplementationType & 0xFF0; ImplementationLower = ImplementationType & 0xF; BitLength = 0; // fixup the bit length if (ImplementationLower > 6) { throw new NotImplementedException("The disassembly throws an exception when fragmentImplementationLower > 6, copying verbatim"); } if (ImplementationUpper > 0x420) { // Console.WriteLine($"fragment value upper: {fragmentImplementationUpper:X}"); ECU ecu = ParentDomain.ParentECU; byte[] infoPool = ecu.ReadECUInfoPool(reader); // int infoEntryWidth = ecu.ecuInfoPool_tableEntrySize; // Console.WriteLine($"Info entry width: {infoEntryWidth}"); // 8 using (BinaryReader poolReader = new BinaryReader(new MemoryStream(infoPool))) { DiagPresentation pres = ParentECU.GlobalInternalPresentations[InfoPoolIndex]; /* * // depreciate use of ReadCBFWithOffset * poolReader.BaseStream.Seek(ecu.Info_EntrySize * InfoPoolIndex, SeekOrigin.Begin); * int presentationStructOffset = poolReader.ReadInt32(); * int presentationStructSize = poolReader.ReadInt32(); * * //Console.WriteLine($"struct offset: 0x{presentationStructOffset:X} , size: {presentationStructSize} , meaningA 0x{fragmentMeaningA_Presentation:X} infoBase 0x{ecu.ecuInfoPool_fileoffset_7:X}\n"); * * reader.BaseStream.Seek(presentationStructOffset + ecu.Info_BlockOffset, SeekOrigin.Begin); * byte[] presentationStruct = reader.ReadBytes(presentationStructSize); * * int presentationMode = CaesarStructure.ReadCBFWithOffset(0x1C, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_Type * int presentationLength = CaesarStructure.ReadCBFWithOffset(0x1A, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // PRESS_TypeLength * if (presentationLength > 0) * { * BitLength = presentationLength; * } * else * { * BitLength = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ??? * } */ BitLength = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21; // if value was specified in bytes, convert to bits if (pres.Type_1C == 0) { BitLength *= 8; } } } else { if (ImplementationUpper == 0x420) { BitLength = FragmentLengthTable[ImplementationLower]; } else if (ImplementationUpper == 0x320) { BitLength = FragmentLengthTable[ImplementationLower]; } else if (ImplementationUpper == 0x330) { BitLength = RawBitLength; } else if (ImplementationUpper == 0x340) { //throw new NotImplementedException("Requires implementation of ITT handle"); Console.WriteLine($"[!] Warning: Please avoid {ParentDomain.Qualifier} -> {Qualifier} as it could not be parsed (requires ITT)."); } else { throw new NotImplementedException($"No known fragment length format. Fragment upper: 0x{ImplementationUpper:X}"); } } if (BitLength == 0) { // not sure if there are dummy entries that might trip below exception // throw new NotImplementedException("Fragment length cannot be zero"); } }
public void Restore(CTFLanguage language, ECU parentEcu, DiagService parentDiagService) { Language = language; ParentECU = parentEcu; ParentDiagService = parentDiagService; }
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 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 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; 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 SubsectionD_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 8 SubsectionD_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 9 DiagServicesCount = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 10 DiagServicesOffset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 11 SubsectionF_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 12 SubsectionF_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 13 SubsectionG_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 14 SubsectionG_Offset = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 15 SubsectionH_Count = CaesarReader.ReadBitflagInt32(ref bitFlags, variantReader); // 16 SubsectionH_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 VCDomainPoolOffsets = new List <int>(); variantReader.BaseStream.Seek(VCDomainsOffset, SeekOrigin.Begin); for (int variantCodingIndex = 0; variantCodingIndex < VCDomainsCount; variantCodingIndex++) { VCDomainPoolOffsets.Add(variantReader.ReadInt32()); } DiagServicesPoolOffsets = new List <int>(); variantReader.BaseStream.Seek(DiagServicesOffset, SeekOrigin.Begin); for (int diagIndex = 0; diagIndex < DiagServicesCount; diagIndex++) { DiagServicesPoolOffsets.Add(variantReader.ReadInt32()); } } CreateVCDomains(reader, parentEcu, language); CreateDiagServices(reader, parentEcu, language); CreateVariantPatterns(reader); CreateComParameters(reader, parentEcu); }