private void Load3Dump() { if (Settings.Default.UseDefaultKeys) { ODD.LoadDefaultKeys(); ShowKeys(true); has3DumpLoaded = true; } else { string EID4Str = Settings.Default.EID4Str; string KEStr = Settings.Default.KEStr; string IEStr = Settings.Default.IEStr; theAppState = AppStates.DETECTING; has3DumpLoaded = EID4Str.Length != 0 && EID4Str.Length != 0 && EID4Str.Length != 0; if (!has3DumpLoaded) { AddEvent("No key data, please load your 3Dump.bin", ReportType.Warning); return; } EID4 = EID4Str.AsByteArray(); KE = KEStr.AsByteArray(); IE = IEStr.AsByteArray(); ODD.LoadKeys(EID4, KE, IE); ShowKeys(false); } }
/************************************************************* *************************************************************/ private void DetectDrives(string drive = null) { lock (detectingDrivesObject) { if (isDetectingDrives) { return; } isDetectingDrives = true; } ODD odd = string.IsNullOrEmpty(drive) ? CdRom.FindDrive() : CdRom.CheckDrive(drive); if (odd == null && theODD == null) { isDetectingDrives = false; return; } if (theODD != null) { theODD.Close(); } theODD = odd; isDetectingDrives = false; if (theODD == null) { return; } StateMachine(AppStims.DRIVE_DETECTED); Interaction.Instance.ReportMessage("Drive Detected OK", ReportType.Success); AuthenticateDrive(); }
/************************************************************* *************************************************************/ private void btnLoadKeys_Click(object sender, EventArgs e) { if (open3DumpFileDialog.ShowDialog() != DialogResult.OK) { return; } byte[] eid4 = new byte[0x20]; byte[] cmac = new byte[0x10]; byte[] ke = new byte[0x20]; byte[] ie = new byte[0x10]; try { using (FileStream the3DumpFile = new FileStream(open3DumpFileDialog.FileName, FileMode.Open, FileAccess.Read)) { using (BinaryReader br = new BinaryReader(the3DumpFile)) { br.Read(eid4, 0, 0x20); br.Read(cmac, 0, 0x10); br.Read(ke, 0, 0x20); br.Read(ie, 0, 0x10); } } } catch (Exception ee) { string fail = ee.Message; AddEvent(fail, ReportType.Fail); return; } string hex = BitConverter.ToString(eid4); hex = hex.Replace("-", ""); Settings.Default.EID4Str = hex; hex = BitConverter.ToString(cmac); hex = hex.Replace("-", ""); Settings.Default.CMACStr = hex; hex = BitConverter.ToString(ke); hex = hex.Replace("-", ""); Settings.Default.KEStr = hex; hex = BitConverter.ToString(ie); hex = hex.Replace("-", ""); Settings.Default.IEStr = hex; Settings.Default.Save(); has3DumpLoaded = true; ODD.LoadKeys(eid4, ke, ie); ShowKeys(false); AuthenticateDrive(); }
/************************************************************* *************************************************************/ public bool AnalyseISO(ODD odd) { bool IsPlain = true; try { using (DiscStream inputStream = new DiscStream(odd)) { byte[] buffer = new byte[0x1000]; inputStream.Read(buffer, 0, 0x1000); NumPlainRegions = BitConverter.ToUInt32(buffer, 0).Swap(); Regions = new Region[(NumPlainRegions * 2) - 1]; if (buffer[0xF70 + 0xA] != '3' || buffer[0xF70 + 0xB] != 'K') { Interaction.Instance.ReportMessage("Invalid ISO file. This file does not contain PIC/D1/D2 data"); return(false); } IsDecrypting = buffer[0xF70] != 0x44; // Begins with E or D IsBuildedISO = buffer[0xF70 + 0xD] == 0x42; // End in BLD IsValidHash = IsBuildedISO && buffer[0xF70 + 0xF] != 0x44; // Ends in BLF int pos = 8; UInt32 Current = BitConverter.ToUInt32(buffer, pos).Swap(); pos += 4; for (UInt32 i = 0; i < (2 * NumPlainRegions) - 1; i++) { UInt32 Next = BitConverter.ToUInt32(buffer, pos).Swap(); pos += 4; if (IsPlain) { Regions[i] = new PlainRegion(i, IsDecrypting, IsBuildedISO, IsValidHash, Current, Next); } else { Regions[i] = IsDecrypting ? (Region) new CryptedRegion(i, inputStream.Data1, inputStream.Data2, Current, Next, false) : new DecryptedRegion(i, inputStream.Data1, inputStream.Data2, Current, Next, false); } IsPlain = !IsPlain; Current = Next; } /* Record this for later */ amountOfSectors = Current; // Game ID is at offset 0x810, length = 10 GameID = Encoding.ASCII.GetString(buffer, 0x810, 10); } } catch (Exception e) { Console.WriteLine(e); return(false); } return(true); }
protected CryptoRegion(UInt32 region, byte[] d1, byte[] d2, UInt32 StartSector, UInt32 Next) : base(region) { byte[] user_key_erk = { 0x38, 0x0B, 0xCF, 0x0B, 0x53, 0x45, 0x5B, 0x3C, 0x78, 0x17, 0xAB, 0x4F, 0xA3, 0xBA, 0x90, 0xED }; byte[] user_key_riv = { 0x69, 0x47, 0x47, 0x72, 0xAF, 0x6F, 0xDA, 0xB3, 0x42, 0x74, 0x3A, 0xEF, 0xAA, 0x18, 0x62, 0x87 }; Start = StartSector + 1; Length = Next - Start; DiskKey = new byte[0x10]; ODD.AESEncrypt(user_key_erk, user_key_riv, d1, 0, 0x10, DiskKey, 0); }
/************************************************************* *************************************************************/ private void ShowKeys(bool UsingDefaults) { if (UsingDefaults) { AddEvent("Using Default Keys"); } else { AddEvent("Key1 : " + ODD.GetKey1().AsString()); AddEvent("Key2 : " + ODD.GetKey2().AsString()); } }
/************************************************************* *************************************************************/ private async void AuthenticateDrive() { if (theODD == null) { return; } if (!has3DumpLoaded) { return; } if (Settings.Default.UseDefaultKeys) { ODD.LoadDefaultKeys(); if (!theODD.AuthenticateDrive()) { bool writeKeys = await formsInteraction.UIExecute(() => MessageBox.Show( Resources.UseDefaultKeys, Resources.DefaultKeysCaption, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes); if (writeKeys) { // Authentication failed, if (!theODD.WritePBlock()) { Interaction.Instance.ReportMessage("Couldn't load P Block - Drive Authentication Failed", ReportType.Fail); return; } } } } bool theResult = theODD.AuthenticateDrive(); if (!theResult) { Interaction.Instance.ReportMessage("Drive Authentication Failed", ReportType.Fail); StateMachine(AppStims.DRIVE_AUTH_FAILED); await formsInteraction.UIExecute(() => { btnLoadKeys.Enabled = true; }); } else { Interaction.Instance.ReportMessage("Drive Authenticated OK", ReportType.Success); StateMachine(AppStims.DRIVE_AUTH_PASSED); await formsInteraction.UIExecute(() => { btnLoadKeys.Enabled = false; }); StateMachine(AppStims.DISK_PRESENT); await formsInteraction.UIExecute(() => DiskTypeDetectionWorker.RunWorkerAsync()); } }
private void lblData2_DoubleClick(object sender, EventArgs e) { if (isdecrypted) { ODD.AESEncrypt(Utilities.D2_KEY, Utilities.D2_IV, d2, 0, d2.Length, d2, 0); } else { ODD.AESDecrypt(Utilities.D2_KEY, Utilities.D2_IV, d2, 0, d2.Length, d2, 0); } lblData2.Text = d2.AsString(); isdecrypted = !isdecrypted; }
public static ODD FindDrive() { ODD odd = null; IEnumerable <DriveInfo> cd = DriveInfo.GetDrives().Where(c => c.DriveType == DriveType.CDRom); foreach (var driveInfo in cd) { odd = CheckDrive(driveInfo.RootDirectory.Name.Substring(0, 2)); if (odd != null) { break; } } return(odd); }
private static ODD TestCDB(CDB cdb) { theInquiryResponse = new byte[0x3C]; if (CDB.DoInquiry(theInquiryResponse) != CDB.IoResult.OK) { Trace.WriteLine(string.Format("INQ on drive {0} failed", driveLetter)); CDB.Close(); return(null); } string IStr = Encoding.ASCII.GetString(theInquiryResponse, 0x08, 0x1C); ODD odd = PS3_Drive.Parse(driveLetter, IStr); if (odd != null) { return(odd); } Interaction.Instance.ReportMessage(string.Format("Drive {0} is NOT a PS3 drive", driveLetter), ReportType.Warning); CDB.Close(); return(null); }
// This method will add crap to the D2 data private void PatchD2() { byte[] d2 = new byte[Data2.Length]; ODD.AESDecrypt(Utilities.D2_KEY, Utilities.D2_IV, Data2, 0, Data2.Length, d2, 0); // Fetch the last 4 bytes int val = BitConverter.ToInt32(d2, 12); if (val == 0) { return; } // Fill the last part with a 1, and let the iso builder fill it with crap const int newval = 1; byte[] rnd = BitConverter.GetBytes(newval).Swap(); Array.Copy(rnd, 0, d2, 12, rnd.Length); ODD.AESEncrypt(Utilities.D2_KEY, Utilities.D2_IV, d2, 0, d2.Length, Data2, 0); }
/************************************************************* *************************************************************/ private void DiskTypeDetectionWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { bool updateSM = true; bool theResult = (bool)e.Result; switch (theODD.GetCurrentDiskType()) { case ODD.DiskType.PS3: bool isPs3Disc = ODD.ReadMetaData(out gameId); AddEvent(!isPs3Disc ? "Unknown Disk Type" : string.Format("PS3 Game Disk : '{0}'", gameId), isPs3Disc ? ReportType.Normal : ReportType.Warning); break; case ODD.DiskType.PS2: AddEvent("PS2 Game Disk"); break; case ODD.DiskType.PS1: AddEvent("PS1 Game Disk"); break; case ODD.DiskType.UNKNOWN: AddEvent("Unknown Disk Type", ReportType.Warning); break; case ODD.DiskType.EMPTY: AddEvent("No disc in drive", ReportType.Warning); updateSM = false; break; } if (updateSM) { StateMachine(theResult ? AppStims.PS3_DISK : AppStims.NO_PS3_DISK); } btnDdlCreateIrd.Visible = theResult; btnIRDFile.Visible = !theResult; }
private void CryptRegion(CancellationToken cancellation) { using (Aes aes = ODD.CreateAes()) { try { while (!cancellation.IsCancellationRequested) { QueuedItem item = readingCollection.Take(cancellation); for (int i = 0; i < item.Sectors; i++) { // Decrypt the buffer int sector_index = (int)(item.Offset / Utilities.SectorSize) + i; byte[] sector_iv = new byte[0x10]; for (int j = 0; j < 0x10; j++) { sector_iv[16 - j - 1] = (byte)(sector_index & 0xFF); sector_index = sector_index >> 8; } Crypt(aes, DiskKey, sector_iv, item.Buffer, (int)(i * Utilities.SectorSize), (int)Utilities.SectorSize, item.Buffer, (int)(i * Utilities.SectorSize)); } writingCollection[item.Offset] = item; } } catch (InvalidOperationException) { // Collection marked as completed, can't fetch anymore (ugly!) } catch (OperationCanceledException) { // User pressed cancel } } }
internal IrdCreateDisc(ODD odd, bool saveIso) { _odd = odd; _saveIso = saveIso; }
public static IrdCreator Create(ODD odd, bool saveIso = false) { return(new IrdCreateDisc(odd, saveIso)); }
protected override void Crypt(Aes aes, byte[] key, byte[] iv, byte[] source, int sourceOffset, int sourceLength, byte[] dest, int destOffset) { ODD.AESEncrypt(key, iv, source, sourceOffset, sourceLength, dest, destOffset); }
/************************************************************* *************************************************************/ protected override void WndProc(ref Message m) { if (m.Msg == Native.WM_DEVICECHANGE) { Native.DEV_BROADCAST_HDR broadcast = m.LParam.ToStruct <Native.DEV_BROADCAST_HDR>(); // Was a device added? switch ((Native.DeviceBroadcastType)m.WParam.ToInt32()) { case Native.DeviceBroadcastType.Arrival: // Apparently, you'll get this event when a new device has been added, but // also when a disc has been inserted. if (broadcast.DeviceType == Native.DeviceType.Volume) { Native.DEV_BROADCAST_VOLUME volume = (Native.DEV_BROADCAST_VOLUME)m.GetLParam(typeof(Native.DEV_BROADCAST_VOLUME)); IEnumerable <string> drives = Native.MaskToDrives(volume.Unitmask); foreach (string drive in drives) { //AddEvent("Volume " + drive + " added"); if (theODD == null || theODD.DriveLetter != drive) // This event can contain the same drive! { DetectDriveAsync(drive); } if (theODD == null || theODD.DriveLetter != drive || (volume.Flags & Native.BroadcastFlags.Media) == 0) { continue; } // CD-ROM inserted into the drive // Check if this is a PS3 DVD. If it is, enable the rip button AddEvent("Disc inserted"); StateMachine(AppStims.DISK_PRESENT); AuthenticateDrive(); } } break; case Native.DeviceBroadcastType.QueryRemove: // Prevent windows from ejecting the device safe when we are still ripping case Native.DeviceBroadcastType.RemoveComplete: // Check again if our drive or volume still exists. if (broadcast.DeviceType == Native.DeviceType.Volume) { Native.DEV_BROADCAST_VOLUME volume = (Native.DEV_BROADCAST_VOLUME)m.GetLParam(typeof(Native.DEV_BROADCAST_VOLUME)); IEnumerable <string> drives = Native.MaskToDrives(volume.Unitmask).ToList(); if (theODD == null && drives.Any()) { // Perhaps we can now redetect the drive? foreach (string drive in drives) { DetectDrives(drive); if (theODD != null) { break; } } } if (drives.Any(drive => theODD != null && drive == theODD.DriveLetter)) { Debug.WriteLine("This is our authenticated drive! F00l."); if ((volume.Flags & Native.BroadcastFlags.Media) > 0) { // CD-ROM removed from the drive AddEvent("Disc removed"); StateMachine(AppStims.NO_DISK_PRESENT); btnDdlCreateIrd.Visible = false; btnIRDFile.Visible = true; } else { if (theODD != null) { theODD.Close(); theODD = null; } AddEvent("Drive removed!"); StateMachine(AppStims.DRIVE_ABSENT); btnDdlCreateIrd.Visible = false; btnIRDFile.Visible = true; } } } break; } } base.WndProc(ref m); }
public static ODD CheckDrive(string driveletter) { ODD odd = ODD.getODD(driveletter); return(odd); }