private bool CalculateLayer2Checksum(string filename, int OffsetLayer2, bool forceSilent) { bool Layer2ChecksumValid = false; uint checksum0 = 0; uint checksum1 = 0; uint sum0 = 0; uint matrix_dimension = 0; uint partial_address = 0; uint x = 0; /* Get 0x100 byte buffer from CHPTR – CHPTR + 0xFF Because level 1 is in that area level1 must be correct first Prepare coded_buffer (0x100 buffer from chptr) with loop: coded_buffer(x) = (buffer (x) + 0xD6) xor 0x21 (add 0xd6 to every byte of buffer, then xor it by 0x21) [ 1 indexed, not 0 indexed ] So, 0x101 byte buffer with first byte ignored (convention) * */ byte[] coded_buffer = readdatafromfile(filename, OffsetLayer2, 0x100); for (int i = 0; i < coded_buffer.Length; i++) { byte b = coded_buffer[i]; b += 0xD6; b ^= 0x21; coded_buffer[i] = b; //Console.Write(b.ToString("X2") + " "); } //logger.Debug(""); byte[] complete_file = readdatafromfile(filename, 0, m_currentfile_size); int index = 0; bool chk_found = false; while (index < 0x100 && !chk_found) { if ((coded_buffer[index] == 0xFB) && (coded_buffer[index + 6] == 0xFC) && (coded_buffer[index + 0x0C] == 0xFD)) { sum0 = ((uint)coded_buffer[index + 1] * 0x01000000 + (uint)coded_buffer[index + 2] * 0x010000 + (uint)coded_buffer[index + 3] * 0x100 + (uint)coded_buffer[index + 4]); matrix_dimension = (uint)coded_buffer[index + 7] * 0x01000000 + (uint)coded_buffer[index + 8] * 0x010000 + (uint)coded_buffer[index + 9] * 0x100 + (uint)coded_buffer[index + 10]; partial_address = (uint)coded_buffer[index + 0x0d] * 0x01000000 + (uint)coded_buffer[index + 0x0e] * 0x010000 + (uint)coded_buffer[index + 0x0F] * 0x100 + (uint)coded_buffer[index + 0x10]; if (matrix_dimension >= 0x020000) { checksum0 = 0; x = partial_address /*+ 1*/; while (x < (matrix_dimension - 4)) { checksum0 = checksum0 + (uint)complete_file[x]; x++; } checksum0 = checksum0 + (uint)complete_file[matrix_dimension - 1]; checksum1 = 0; x = partial_address /*+ 1*/; while (x < (matrix_dimension - 4)) { checksum1 = checksum1 + (uint)complete_file[x] * 0x01000000 + (uint)complete_file[x + 1] * 0x10000 + (uint)complete_file[x + 2] * 0x100 + (uint)complete_file[x + 3]; x = x + 4; } if ((checksum0 & 0xFFF00000) != (sum0 & 0xFFF00000)) { checksum0 = checksum1; } if (checksum0 != sum0) { //MessageBox.Show("Layer 2 checksum was invalid, should be updated!"); if (m_appSettings.AutoChecksum || forceSilent) { byte[] checksum_to_file = new byte[4]; checksum_to_file[0] = Convert.ToByte((checksum0 >> 24) & 0x000000FF); checksum_to_file[1] = Convert.ToByte((checksum0 >> 16) & 0x000000FF); checksum_to_file[2] = Convert.ToByte((checksum0 >> 8) & 0x000000FF); checksum_to_file[3] = Convert.ToByte((checksum0) & 0x000000FF); checksum_to_file[0] = Convert.ToByte(((checksum_to_file[0] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[1] = Convert.ToByte(((checksum_to_file[1] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[2] = Convert.ToByte(((checksum_to_file[2] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[3] = Convert.ToByte(((checksum_to_file[3] ^ 0x21) - (byte)0xD6) & 0x000000FF); //CreateBinaryBackup(); savedatatobinary(index + OffsetLayer2 + 1, 4, checksum_to_file, filename, false); Layer2ChecksumValid = true; } else { frmChecksum frmchecksum = new frmChecksum(); frmchecksum.Layer = "Checksum validation Layer 2"; string layer2file = sum0.ToString("X8"); string layer2calc = checksum0.ToString("X8"); frmchecksum.FileChecksum = layer2file; frmchecksum.RealChecksum = layer2calc; if (frmchecksum.ShowDialog() == DialogResult.OK) { byte[] checksum_to_file = new byte[4]; checksum_to_file[0] = Convert.ToByte((checksum0 >> 24) & 0x000000FF); checksum_to_file[1] = Convert.ToByte((checksum0 >> 16) & 0x000000FF); checksum_to_file[2] = Convert.ToByte((checksum0 >> 8) & 0x000000FF); checksum_to_file[3] = Convert.ToByte((checksum0) & 0x000000FF); checksum_to_file[0] = Convert.ToByte(((checksum_to_file[0] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[1] = Convert.ToByte(((checksum_to_file[1] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[2] = Convert.ToByte(((checksum_to_file[2] ^ 0x21) - (byte)0xD6) & 0x000000FF); checksum_to_file[3] = Convert.ToByte(((checksum_to_file[3] ^ 0x21) - (byte)0xD6) & 0x000000FF); //CreateBinaryBackup(); savedatatobinary(index + OffsetLayer2 + 1, 4, checksum_to_file, filename, true); Layer2ChecksumValid = true; coded_buffer[index/* + 1*/] = Convert.ToByte((checksum0 >> 24) & 0x000000FF); coded_buffer[index/* + 2*/] = Convert.ToByte((checksum0 >> 16) & 0x000000FF); coded_buffer[index/* + 3*/] = Convert.ToByte((checksum0 >> 8) & 0x000000FF); coded_buffer[index/* + 4*/] = Convert.ToByte((checksum0) & 0x000000FF); for (int i = 0; i < 4; i++) { //TODO: Actually update the file!!! //complete_file[i + index + OffsetLayer2] = Convert.ToByte((coded_buffer[index + i] ^ 0x21) - 0xD6); } // checksum is ready } else { Layer2ChecksumValid = false; } } } else { Layer2ChecksumValid = true; } chk_found = true; } } index++; } if (!chk_found) { //MessageBox.Show("Layer 2 checksum could not be calculated [ file incompatible ]"); } return Layer2ChecksumValid; }
private void UpdateChecksum(string filename, bool forceSilent) { int m_ChecksumAreaOffset = GetChecksumAreaOffset(filename); if (m_ChecksumAreaOffset > m_currentfile_size) return; bool do_layer2 = true; bool _layer1Valid = false; bool _layer2Valid = false; barChecksumInfo.Caption = "Checksum: validating..."; System.Windows.Forms.Application.DoEvents(); //logger.Debug("Checksum area offset: " + m_ChecksumAreaOffset.ToString("X8")); byte[] hash = CalculateLayer1ChecksumMD5(filename, m_ChecksumAreaOffset, forceSilent); // compare hash to bytes after checksumareaoffset byte[] layer1checksuminfile = readdatafromfile(filename, m_ChecksumAreaOffset + 2, 16); if (!CompareByteArray(hash, layer1checksuminfile)) { //CreateBinaryBackup(); //savedatatobinary(m_ChecksumAreaOffset + 2, 16, hash, filename); if (m_appSettings.AutoChecksum || forceSilent) { savedatatobinary(m_ChecksumAreaOffset + 2, 16, hash, filename, false); _layer1Valid = true; do_layer2 = true; } else { frmChecksum frmchecksum = new frmChecksum(); frmchecksum.Layer = "Checksum validation Layer 1"; string layer1file = string.Empty; string layer1calc = string.Empty; for (int i = 0; i < layer1checksuminfile.Length; i++) { layer1file += layer1checksuminfile[i].ToString("X2") + " "; layer1calc += hash[i].ToString("X2") + " "; } frmchecksum.FileChecksum = layer1file; frmchecksum.RealChecksum = layer1calc; if (frmchecksum.ShowDialog() == DialogResult.OK) { savedatatobinary(m_ChecksumAreaOffset + 2, 16, hash, filename, false); _layer1Valid = true; do_layer2 = true; } else { do_layer2 = false; } } } else { _layer1Valid = true; } if (do_layer2) { if (CalculateLayer2Checksum(filename, m_ChecksumAreaOffset, forceSilent)) { _layer2Valid = true; } else { _layer2Valid = false; } } // show result in statusbar if (_layer1Valid && _layer2Valid) { barChecksumInfo.Caption = "Checksum: OK"; } else if (!_layer1Valid) { barChecksumInfo.Caption = "Checksum: Layer 1 invalid"; } else if (!_layer2Valid) { barChecksumInfo.Caption = "Checksum: Layer 2 invalid"; } }