// 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 CreateDiagServices(BinaryReader reader, CTFLanguage language) { byte[] diagjobPool = ReadDiagjobPool(reader); // arrays since list has become too expensive DiagService[] globalDiagServices = new DiagService[DiagJob_EntryCount]; using (BinaryReader poolReader = new BinaryReader(new MemoryStream(diagjobPool))) { for (int diagjobIndex = 0; diagjobIndex < DiagJob_EntryCount; diagjobIndex++) { int offset = poolReader.ReadInt32(); int size = poolReader.ReadInt32(); uint crc = poolReader.ReadUInt32(); uint config = poolReader.ReadUInt16(); long diagjobBaseAddress = offset + DiagJob_BlockOffset; // Console.WriteLine($"DJ @ {offset:X} with size {size:X}"); DiagService dj = new DiagService(reader, language, diagjobBaseAddress, diagjobIndex, this); // GlobalDiagServices.Add(dj); globalDiagServices[diagjobIndex] = dj; } } GlobalDiagServices = new List <DiagService>(globalDiagServices); }
public void CreateEnvironments(BinaryReader reader, CTFLanguage language) { /* * byte[] envPool = ReadECUEnvPool(reader); * EnvironmentContext[] globalEnvs = new EnvironmentContext[Env_EntryCount]; * using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool))) * { * for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++) * { * int offset = poolReader.ReadInt32(); * int size = poolReader.ReadInt32(); * long envBaseAddress = offset + Env_BlockOffset; * * // Console.WriteLine($"0x{envBaseAddress:X}"); * EnvironmentContext env = new EnvironmentContext(reader, language, envBaseAddress, envIndex, this); * globalEnvs[envIndex] = env; * } * } * GlobalEnvironmentContexts = new List<EnvironmentContext>(globalEnvs); */ byte[] envPool = ReadECUEnvPool(reader); DiagService[] globalEnvs = new DiagService[Env_EntryCount]; using (BinaryReader poolReader = new BinaryReader(new MemoryStream(envPool))) { for (int envIndex = 0; envIndex < Env_EntryCount; envIndex++) { int offset = poolReader.ReadInt32(); int size = poolReader.ReadInt32(); long envBaseAddress = offset + Env_BlockOffset; // Console.WriteLine($"0x{envBaseAddress:X}"); DiagService env = new DiagService(reader, language, envBaseAddress, envIndex, this); globalEnvs[envIndex] = env; } } GlobalEnvironmentContexts = new List <DiagService>(globalEnvs); }
public void Restore(CTFLanguage language, ECU parentEcu, DiagService parentDiagService) { Language = language; ParentECU = parentEcu; ParentDiagService = parentDiagService; }
// look at.. DIInternalRetrieveConstParamPreparation // public int GetSizeInBits(BinaryReader reader, bool verbose = true) { // if (modeConfig & 0xF00) == 0x300, the value is a const param: DIIsConstParameter // VCFragment does the same thing.. with the same ITT exception // BitPosition /= 8 // look for the string "nImplType <= 6" uint modeE = (uint)ModeConfig & 0xF000; uint modeH = (uint)ModeConfig & 0xFF0; uint modeL = (uint)ModeConfig & 0xF; int resultBitSize = 0; if ((ModeConfig & 0xF00) == 0x300) // this check is made in DIDiagServiceRetrievePreparation { if (modeL > 6) { throw new Exception("nImplType <= 6; trying to map a data type that cannot exist"); } // const params : 0x320, 0x330, 0x340 if (modeH == 0x320) { // this behavior is confirmed resultBitSize = IntegerSizeMapping[modeL]; FieldType = InferredDataType.IntegerType; } else if (modeH == 0x330) { // this behavior is also okay resultBitSize = AlternativeBitWidth; // inPres + 20 FieldType = InferredDataType.BitDumpType; } else if (modeH == 0x340) { // from dasm, but unimplemented // DIInternalRetrieveConstParamPreparation FieldType = InferredDataType.UnhandledITType; throw new NotImplementedException("WARNING: valid but unhandled data size (ITT not parsed)"); // resultBitSize = 0; // inPres + 20 } } else { // if systemparam is -1.. load a default system type if (SystemParam == -1) { // apparently both 0x2000 and 0x8000 source from different pools, but use the same PRESENTATION structure if (modeE == 0x8000) { FieldType = InferredDataType.NativeInfoPoolType; byte[] poolBytes = ParentECU.ReadECUInfoPool(reader); using (BinaryReader poolReader = new BinaryReader(new MemoryStream(poolBytes))) { DiagPresentation pres = ParentECU.GlobalInternalPresentations[InfoPoolIndex]; /* * // depreciate use of ReadCBFWithOffset * poolReader.BaseStream.Seek(ParentECU.Info_EntrySize * InfoPoolIndex, SeekOrigin.Begin); * * int presentationStructOffset = poolReader.ReadInt32(); * int presentationStructSize = poolReader.ReadInt32(); * * reader.BaseStream.Seek(presentationStructOffset + ParentECU.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) * { * resultBitSize = presentationLength; * } * else * { * resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ??? * } */ resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21; // if value was specified in bytes, convert to bits if (pres.Type_1C == 0) { resultBitSize *= 8; } } } else if (modeE == 0x2000) { FieldType = InferredDataType.NativePresentationType; byte[] presPool = ParentECU.ReadECUPresentationsPool(reader); using (BinaryReader poolReader = new BinaryReader(new MemoryStream(presPool))) { DiagPresentation pres = ParentECU.GlobalPresentations[PresPoolIndex]; /* * // depreciate use of ReadCBFWithOffset * poolReader.BaseStream.Seek(ParentECU.Presentations_EntrySize * PresPoolIndex, SeekOrigin.Begin); * int presentationStructOffset = poolReader.ReadInt32(); * int presentationStructSize = poolReader.ReadInt32(); * * reader.BaseStream.Seek(presentationStructOffset + ParentECU.Presentations_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) * { * resultBitSize = presentationLength; * } * else * { * resultBitSize = CaesarStructure.ReadCBFWithOffset(0x21, CaesarStructure.StructureName.PRESENTATION_STRUCTURE, presentationStruct); // ??? * } */ resultBitSize = pres.TypeLength_1A > 0 ? pres.TypeLength_1A : pres.TypeLengthBytesMaybe_21; // if value was specified in bytes, convert to bits if (pres.Type_1C == 0) { resultBitSize *= 8; } } } else { // should throw an exception? //Console.WriteLine($"WARNING: Unknown or unhandled type for for {qualifier}"); throw new Exception($"Attempted to load an unknown system type for {Qualifier}"); } } else { // not a const param, not a native param, this is a special param, parsed at DIInternalRetrieveSpecialPreparation // DIInternalRetrieveSpecialPreparation officially supports 0x410, 0x420 only if (modeH == 0x410) { int reducedSysParam = SystemParam - 0x10; if (reducedSysParam == 0) { // specifically requests for LOBYTE (& 0xFF) int resultByteSize = (ParentDiagService.RequestBytes.Length & 0xFF) - (BitPosition / 8); resultBitSize = resultByteSize * 8; FieldType = InferredDataType.ExtendedBitDumpType; // Console.WriteLine($"0x{modeH:X} debug for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} SP: {SystemParam}), sz: {resultBitSize} b ({resultBitSize/8} B)"); } else if (reducedSysParam == 17) { // open a diagservice based on inputRef name // this is experimental, haven't seen a cbf that uses this yet Console.WriteLine($"Parsing experimental 0x410 prep with sysparam 17 at {Qualifier}"); DiagService referencedDs = ParentECU.GlobalDiagServices.Find(x => x.Qualifier == ParentDiagService.InputRefNameMaybe); if (referencedDs != null) { bool referencedDsHasRequestData = referencedDs.RequestBytes.Length > 0; // supposed to check if requestMessage is valid too int internalType = referencedDs.DataClass_ServiceTypeShifted; if (((referencedDs.DataClass_ServiceTypeShifted & 0xC) > 0) && referencedDsHasRequestData) { if ((referencedDs.DataClass_ServiceTypeShifted & 4) > 0) { internalType = 0x10000000; } else { internalType = 0x20000000; } } if ((internalType & 0x10000) != 0) { // referenced type is a global variable resultBitSize = ParentDiagService.P_Count * 8; FieldType = InferredDataType.UnhandledSP17Type; } else { // use pres dump length FieldType = InferredDataType.UnhandledSP17Type; resultBitSize = ParentDiagService.RequestBytes.Length * 8; } } else { Console.WriteLine($"0x410 : sys param: 17 for qualifier {Qualifier} could not find referenced DiagService with index {ParentDiagService.InputRefNameMaybe}"); // throw new NotImplementedException } } else { throw new Exception($"Invalid system parameter for {Qualifier}"); } } else if (modeH == 0x420) { if (modeL > 6) { throw new Exception("nImplType <= 6; trying to map a data type that cannot exist"); } FieldType = InferredDataType.IntegerType; resultBitSize = IntegerSizeMapping[modeL]; } else if (modeH == 0x430) { // mode 0x430 is nonstandard and doesn't seem to exist in the function that I was disassembling /* * AlternativeBitWidth : 128 * SystemParam : 37 * * See 0x320 vs 0x330, seems to be similar */ resultBitSize = AlternativeBitWidth; // inPres + 20 FieldType = InferredDataType.BitDumpType; } else { FieldType = InferredDataType.UnhandledType; Console.WriteLine($"Unhandled type: {modeH} for {Qualifier}"); PrintDebug(); throw new Exception($"Attempted to load an unknown special param type for {Qualifier}"); //Console.WriteLine($"{qualifier} ({poolThing}/{ParentECU.ecuInfoPool_tableEntryCount})\n{BitUtility.BytesToHex(presentationStruct)}\n\n"); } } } /* * if (modeH == 0x430) * { * // guessed * if (verbose) * { * Console.WriteLine($"Unsupported 0x{modeH:X} behavior for {qualifier} (L: {modeL}) (BitWidth: {AlternativeBitWidth} ByteWidth: {SystemParam})"); * } * //PrintDebug(); * resultBitSize = AlternativeBitWidth; // alternate bit width is 128 which should be a nice 16 bytes * } * else if (modeH > 0x430) * { * // guessed from varcoding behavior * if ((PresPool == 0) && (AvailableBitWidth_PoolThing == 0)) * { * return 0; * } * else * { * //Console.WriteLine($"No idea how to handle Pres 0x750 from {qualifier} : {PresPool}"); * } * Console.WriteLine($"No idea how to handle 0x{modeH:X} from {qualifier} ({PresPool}, {AvailableBitWidth_PoolThing})"); * } */ return(resultBitSize); }