/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public Tuple<ushort, byte[]> ReadDataBlock(LeImageReader rdr) { ushort count; ushort uAddr; byte b; // Eat bytes until 1 followed by 0. do { while (rdr.TryReadByte(out b) && b != 1) ; if (b != 1) return null; // invalid file if (!rdr.TryReadByte(out b)) return null; } while (b != 0); if (!rdr.TryReadLeUInt16(out count)) return null; if (!rdr.TryReadLeUInt16(out uAddr)) return null; if (count == 6) return new Tuple<ushort, byte[]>(uAddr, null); var data = rdr.ReadBytes(count - 6); if (data == null || data.Length < count - 6) return null; if (!rdr.TryReadByte(out b)) // read (and ignore) checksum return null; Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return Tuple.Create(uAddr, data); }
/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes, including the first 6 bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public (ushort, byte[]?) ReadDataBlock(LeImageReader rdr) { ushort count; ushort uAddr; byte b; // Eat bytes until 1 followed by 0. do { while (rdr.TryReadByte(out b) && b != 1) { ; } if (b != 1) { return(0, null); // invalid file } if (!rdr.TryReadByte(out b)) { return(0, null); } } while (b != 0); if (!rdr.TryReadLeUInt16(out count)) { return(0, null); } if (!rdr.TryReadLeUInt16(out uAddr)) { return(0, null); } if (count == 6) { return(uAddr, null); } var data = rdr.ReadBytes(count - 6); if (data == null || data.Length < count - 6) { return(0, null); } if (!rdr.TryReadByte(out b)) // read (and ignore) checksum { return(0, null); } Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return(uAddr, data); }
/// <summary> /// Reads LDA data blocks /// </summary> /// <remarks> /// The format of LDA blocks is: /// +------+ /// | 0001 | - word16 - Magic /// |------| /// | BC | - word16 - Count /// |------| /// | ADDR | - word16 - Absolute load address /// |------| /// | Data | - byte[] - Data (`Count` bytes) /// ... /// |------| /// | Chk | - byte - Checksum /// +------+ /// </remarks> /// <param name="rdr"></param> /// <returns></returns> public ImageSegment ReadDataBlock(LeImageReader rdr) { ushort w; ushort count; ushort uAddr; byte b; if (!rdr.TryReadLeUInt16(out w) || w != 0x0001) { return(null); } if (!rdr.TryReadLeUInt16(out count)) { return(null); } if (!rdr.TryReadLeUInt16(out uAddr)) { return(null); } var data = rdr.ReadBytes(count); if (data == null || data.Length < count) { return(null); } if (!rdr.TryReadByte(out b)) { return(null); } Debug.Print("Data block: {0:X4} {1:X4}", uAddr, count); return(new ImageSegment( string.Format("seg{0:X4}", uAddr), new MemoryArea(Address.Ptr16(uAddr), data), AccessMode.ReadWriteExecute)); }
public bool SetupLibCheck(IServiceProvider services, string fpath, byte[] bytes) { var listener = services.RequireService<DecompilerEventListener>(); var rdr = new LeImageReader(bytes); ushort w, len; int i; //readProtoFile(); /* Read the parameters */ if (!rdr.TryReadLeUInt32(out uint fileSig) || fileSig != 0x73636364) // "dccs" { listener.Warn(string.Format("{0} is not a DCC signature file.", fpath)); return false; } numKeys = rdr.ReadLeUInt16(); numVert = rdr.ReadLeUInt16(); PatLen = rdr.ReadLeUInt16(); SymLen = rdr.ReadLeUInt16(); if ((PatLen != PATLEN) || (SymLen != SYMLEN)) { listener.Warn(string.Format("Can't use signature file with sym and pattern lengths of {0} and {1}.", SymLen, PatLen)); return false; } // Initialise the perfhlib stuff. Also allocates T1, T2, g, etc // Set the parameters for the hash table g_pattern_hasher.setHashParams( numKeys, // The number of symbols PatLen, // The length of the pattern to be hashed 256, // The character set of the pattern (0-FF) (char)0, // Minimum pattern character value numVert); // Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details T1base = g_pattern_hasher.readT1(); T2base = g_pattern_hasher.readT2(); g = g_pattern_hasher.readG(); /* Read T1 and T2 tables */ ushort ww; if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3154) // "T1" { Debug.Print("Expected 'T1'"); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } len = (ushort) (PatLen * 256u * 2); // 2 = sizeof ushort w = rdr.ReadLeUInt16(); if (w != len) { Debug.Print("Problem with size of T1: file {0}, calc {1}", w, len); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } readFileSection(T1base, len, rdr); if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3254) // "T2" { Debug.Print("Expected 'T2'"); return false; } w = rdr.ReadLeUInt16(); if (w != len) { Debug.Print("Problem with size of T2: file %d, calc %d\n", w, len); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } readFileSection(T2base, len, rdr); /* Now read the function g[] */ if (!rdr.TryReadLeUInt16(out ww) || ww != 0x6767) // "gg" { Debug.Print("Expected 'gg'"); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } len = (ushort) (numVert * 2); // sizeof(uint16_t)); w = rdr.ReadLeUInt16(); if (w != len) { Debug.Print("Problem with size of g[]: file {0}, calc {1}", w, len); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } readFileSection(g, len, rdr); /* This is now the hash table */ /* First allocate space for the table */ ht = new HT[numKeys]; if (!rdr.TryReadLeUInt16(out ww) || ww != 0x7468) // "ht" { Debug.Print("Expected 'ht'"); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } w = rdr.ReadLeUInt16(); if (w != numKeys * (SymLen + PatLen + 2)) // sizeof(uint16_t))) { Debug.Print("Problem with size of hash table: file {0}, calc {1}", w, len); listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath)); return false; } ht = new HT[numKeys]; for (i = 0; i < numKeys; i++) { var aSym = rdr.ReadBytes(SymLen) .TakeWhile(b => b != 0).ToArray(); ht[i] = new HT { htSym = Encoding.ASCII.GetString(aSym), htPat = rdr.ReadBytes(PatLen) }; } return true; }