Example #1
0
        internal static async Task RewriteParts(string PartPath)
        {
            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            foreach (var part in Directory.EnumerateFiles(PartPath))
            {
                var partname = part.Split('\\').Last().Replace(".img", "");
                try
                {
                    LogFile.Log($"Writing {partname} to the device.", LogType.ConsoleOnly);

                    LogFile.Log("", LogType.ConsoleOnly);

                    MassStorage.RestorePartition(part, partname, (v, t) =>
                    {
                        LogFile.Log("Progress: " + v + "%", LogType.ConsoleOnly);
                    });
                    LogFile.Log("", LogType.ConsoleOnly);
                }
                catch
                {
                    LogFile.Log("", LogType.ConsoleOnly);
                    LogFile.Log($"Failed writing {partname} to the device.", LogType.ConsoleOnly);
                };
            }
        }
        internal SwitchModeViewModel(PhoneNotifierViewModel PhoneNotifier, PhoneInterfaces?TargetMode)
            : base()
        {
            if ((PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Label) && (PhoneNotifier.CurrentInterface != PhoneInterfaces.Lumia_Normal))
            {
                throw new ArgumentException();
            }

            this.PhoneNotifier = PhoneNotifier;
            this.CurrentModel  = (NokiaPhoneModel)PhoneNotifier.CurrentModel;
            this.CurrentMode   = PhoneNotifier.CurrentInterface;
            this.TargetMode    = TargetMode;

            if (this.CurrentMode == null)
            {
                LogFile.Log("Waiting for phone to connect...", LogType.FileAndConsole);
                PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            }
            else
            {
                // Make sure this ViewModel has its View loaded before we continue,
                // or else loading of Views can get mixed up.
                if (SynchronizationContext.Current == null)
                {
                    StartSwitch();
                }
                else
                {
                    SynchronizationContext.Current.Post((s) =>
                    {
                        ((SwitchModeViewModel)s).StartSwitch();
                    }, this);
                }
            }
        }
Example #3
0
        internal BackupViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action Callback)
            : base()
        {
            IsFlashModeOperation = true;

            this.PhoneNotifier      = PhoneNotifier;
            this.SwitchToUnlockBoot = SwitchToUnlockBoot;
            this.Callback           = Callback;
        }
Example #4
0
        internal DownloadsViewModel(PhoneNotifierViewModel Notifier)
        {
            IsSwitchingInterface       = false;
            IsFlashModeOperation       = false;
            this.Notifier              = Notifier;
            Notifier.NewDeviceArrived += Notifier_NewDeviceArrived;

            RegistryKey Key = Registry.CurrentUser.OpenSubKey(@"Software\WPInternals", true);

            if (Key == null)
            {
                Key = Registry.CurrentUser.CreateSubKey(@"Software\WPInternals");
            }
            DownloadFolder = (string)Key.GetValue("DownloadFolder", @"C:\ProgramData\WPinternals\Repository");
            Key.Close();

            SpeedTimer = new Timer(TimerCallback, this, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

            AddFFUCommand = new DelegateCommand(() =>
            {
                string FFUPath = null;

                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
                dlg.DefaultExt = ".ffu";                    // Default file extension
                dlg.Filter     = "ROM images (.ffu)|*.ffu"; // Filter files by extension

                bool?result = dlg.ShowDialog();

                if (result == true)
                {
                    FFUPath        = dlg.FileName;
                    string FFUFile = System.IO.Path.GetFileName(FFUPath);

                    try
                    {
                        App.Config.AddFfuToRepository(FFUPath);
                        App.Config.WriteConfig();
                        LastStatusText = "File \"" + FFUFile + "\" was added to the repository.";
                    }
                    catch (WPinternalsException Ex)
                    {
                        LastStatusText = "Error: " + Ex.Message + ". File \"" + FFUFile + "\" was not added.";
                    }
                    catch
                    {
                        LastStatusText = "Error: File \"" + FFUFile + "\" was not added.";
                    }
                }
                else
                {
                    LastStatusText = null;
                }
            });
        }
Example #5
0
        internal RestoreViewModel(PhoneNotifierViewModel PhoneNotifier, Action <PhoneInterfaces> RequestModeSwitch, Action SwitchToUnlockBoot, Action SwitchToFlashRom, Action Callback)
            : base()
        {
            IsSwitchingInterface = true;

            this.PhoneNotifier      = PhoneNotifier;
            this.Callback           = Callback;
            this.RequestModeSwitch  = RequestModeSwitch;
            this.SwitchToUnlockBoot = SwitchToUnlockBoot;
            this.SwitchToFlashRom   = SwitchToFlashRom;
        }
Example #6
0
        internal static async Task RewriteGPT(string GPTPath)
        {
            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(1, GPTPath);
        }
        internal LumiaModeViewModel(PhoneNotifierViewModel PhoneNotifier, Action Callback)
            : base()
        {
            this.PhoneNotifier = PhoneNotifier;
            this.Callback      = Callback;

            CurrentInterface = PhoneNotifier.CurrentInterface;
            CurrentModel     = PhoneNotifier.CurrentModel;

            PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            PhoneNotifier.DeviceRemoved    += DeviceRemoved;
        }
        internal BackupTargetSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action <string> BackupArchiveCallback, Action <string, string, string> BackupCallback)
            : base()
        {
            this.PhoneNotifier         = PhoneNotifier;
            this.BackupCallback        = BackupCallback;
            this.BackupArchiveCallback = BackupArchiveCallback;
            this.SwitchToUnlockBoot    = SwitchToUnlockBoot;

            this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            this.PhoneNotifier.DeviceRemoved    += DeviceRemoved;

            new Thread(() => EvaluateViewState()).Start();
        }
Example #9
0
        private void Empty_Loaded(object sender, RoutedEventArgs e)
        {
            // Find the phone notifier
            DependencyObject obj = (DependencyObject)sender;

            while (!(obj is MainWindow))
            {
                obj = VisualTreeHelper.GetParent(obj);
            }
            PhoneNotifier = ((MainViewModel)(((MainWindow)obj).DataContext)).PhoneNotifier;

            PhoneNotifier.NewDeviceArrived += PhoneNotifier_NewDeviceArrived;
        }
        internal LumiaUnlockRootViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToDumpRom, Action SwitchToFlashRom, bool DoUnlock, Action Callback)
            : base()
        {
            IsSwitchingInterface = false;
            IsFlashModeOperation = true;

            this.PhoneNotifier      = PhoneNotifier;
            this.SwitchToDumpRom    = SwitchToDumpRom;
            this.SwitchToFlashRom   = SwitchToFlashRom;
            this.SwitchToUnlockBoot = SwitchToUnlockBoot;
            this.DoUnlock           = DoUnlock;
            this.Callback           = Callback;
        }
        internal LumiaFlashRomViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToDumpFFU, Action SwitchToBackup, Action Callback)
            : base()
        {
            IsSwitchingInterface = false;
            IsFlashModeOperation = true;

            this.PhoneNotifier      = PhoneNotifier;
            this.SwitchToUnlockBoot = SwitchToUnlockBoot;
            this.SwitchToUnlockRoot = SwitchToUnlockRoot;
            this.SwitchToDumpFFU    = SwitchToDumpFFU;
            this.SwitchToBackup     = SwitchToBackup;
            this.Callback           = Callback;
        }
Example #12
0
        internal LumiaInfoViewModel(PhoneNotifierViewModel PhoneNotifier, Action <PhoneInterfaces> ModeSwitchRequestCallback, Action SwitchToGettingStarted)
            : base()
        {
            this.PhoneNotifier             = PhoneNotifier;
            this.ModeSwitchRequestCallback = ModeSwitchRequestCallback;
            this.SwitchToGettingStarted    = SwitchToGettingStarted;

            CurrentInterface = PhoneNotifier.CurrentInterface;
            CurrentModel     = PhoneNotifier.CurrentModel;

            PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            PhoneNotifier.DeviceRemoved    += DeviceRemoved;
        }
Example #13
0
        internal static async Task TestProgrammer(System.Threading.SynchronizationContext UIContext, string ProgrammerPath)
        {
            LogFile.BeginAction("TestProgrammer");
            try
            {
                LogFile.Log("Starting Firehose Test", LogType.FileAndConsole);

                PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();
                UIContext.Send(s => Notifier.Start(), null);
                if (Notifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download)
                {
                    LogFile.Log("Phone found in emergency mode", LogType.FileAndConsole);
                }
                else
                {
                    LogFile.Log("Phone needs to be switched to emergency mode.", LogType.FileAndConsole);
                    await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);

                    PhoneInfo Info = ((NokiaFlashModel)Notifier.CurrentModel).ReadPhoneInfo();
                    Info.Log(LogType.ConsoleOnly);
                    await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Qualcomm_Download);

                    if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
                    {
                        throw new WPinternalsException("Switching mode failed.");
                    }
                    LogFile.Log("Phone is in emergency mode.", LogType.FileAndConsole);
                }

                // Send and start programmer
                QualcommSerial Serial = (QualcommSerial)Notifier.CurrentModel;
                QualcommSahara Sahara = new QualcommSahara(Serial);

                if (await Sahara.Reset(ProgrammerPath))
                {
                    LogFile.Log("Emergency programmer test succeeded", LogType.FileAndConsole);
                }
                else
                {
                    LogFile.Log("Emergency programmer test failed", LogType.FileAndConsole);
                }
            }
            catch (Exception Ex)
            {
                LogFile.LogException(Ex);
            }
            finally
            {
                LogFile.EndAction("TestProgrammer");
            }
        }
        internal RestoreSourceSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action <PhoneInterfaces> RequestModeSwitch, Action SwitchToUnlockBoot, Action SwitchToFlashRom, Action <string, string, string> RestoreCallback)
            : base()
        {
            this.PhoneNotifier      = PhoneNotifier;
            this.RestoreCallback    = RestoreCallback;
            this.RequestModeSwitch  = RequestModeSwitch;
            this.SwitchToUnlockBoot = SwitchToUnlockBoot;
            this.SwitchToFlashRom   = SwitchToFlashRom;

            this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            this.PhoneNotifier.DeviceRemoved    += DeviceRemoved;

            new Thread(() => EvaluateViewState()).Start();
        }
        internal LumiaRootAccessTargetSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToDumpRom, Action SwitchToFlashRom, Action UnlockPhoneCallback, Action <string, string> UnlockImageCallback)
            : base()
        {
            this.PhoneNotifier       = PhoneNotifier;
            this.SwitchToDumpRom     = SwitchToDumpRom;
            this.SwitchToFlashRom    = SwitchToFlashRom;
            this.SwitchToUnlockBoot  = SwitchToUnlockBoot;
            this.UnlockPhoneCallback = UnlockPhoneCallback;
            this.UnlockImageCallback = UnlockImageCallback;

            this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            this.PhoneNotifier.DeviceRemoved    += DeviceRemoved;

            new Thread(() => EvaluateViewState()).Start();
        }
        internal LumiaFlashRomSourceSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToUnlockRoot, Action SwitchToDumpFFU, Action SwitchToBackup, Action <string, string, string> FlashPartitionsCallback, Action <string> FlashArchiveCallback, Action <string> FlashFFUCallback)
            : base()
        {
            this.PhoneNotifier           = PhoneNotifier;
            this.SwitchToUnlockBoot      = SwitchToUnlockBoot;
            this.SwitchToUnlockRoot      = SwitchToUnlockRoot;
            this.SwitchToDumpFFU         = SwitchToDumpFFU;
            this.SwitchToBackup          = SwitchToBackup;
            this.FlashPartitionsCallback = FlashPartitionsCallback;
            this.FlashArchiveCallback    = FlashArchiveCallback;
            this.FlashFFUCallback        = FlashFFUCallback;

            this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
            this.PhoneNotifier.DeviceRemoved    += DeviceRemoved;

            new Thread(() => EvaluateViewState()).Start();
        }
Example #17
0
        internal static async Task RewriteMBRGPT()
        {
            FFU    FFU     = new FFU(@"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\RX100_9825.ffu");
            string GPTPath = @"E:\Device Backups\Alpha\9200_1230.0025.9200.9825\CorrectGPT.bin";

            PhoneNotifierViewModel Notifier = new PhoneNotifierViewModel();

            Notifier.Start();
            await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_MassStorage);

            MassStorage MassStorage = (MassStorage)Notifier.CurrentModel;

            byte[] MBR = FFU.GetSectors(0, 1);
            LogFile.Log("Writing MBR to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(0, MBR);

            LogFile.Log("Writing GPT to the device.", LogType.ConsoleOnly);
            MassStorage.WriteSectors(1, GPTPath);
        }
        internal LumiaUnlockBootViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToFlashRom, Action SwitchToUndoRoot, Action SwitchToDownload, bool DoUnlock, Action Callback)
            : base()
        {
            IsSwitchingInterface = false;
            IsFlashModeOperation = true;

            this.PhoneNotifier    = PhoneNotifier;
            this.SwitchToFlashRom = SwitchToFlashRom;
            this.SwitchToUndoRoot = SwitchToUndoRoot;
            this.SwitchToDownload = SwitchToDownload;
            this.DoUnlock         = DoUnlock;
            this.Callback         = Callback;

            State = MachineState.Default;

            this.PhoneNotifier.NewDeviceArrived += NewDeviceArrived;

            // ViewState will be evaluated as soon as this object is set as DataContext
        }
Example #19
0
        internal static void InterruptBootChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            App.InterruptBoot = (bool)e.NewValue;

            if ((bool)e.NewValue)
            {
                // Find the phone notifier
                DependencyObject obj = d;
                while (!(obj is MainWindow))
                {
                    obj = VisualTreeHelper.GetParent(obj);
                }
                PhoneNotifierViewModel PhoneNotifier = ((MainViewModel)(((MainWindow)obj).DataContext)).PhoneNotifier;

                if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
                {
                    App.InterruptBoot = false;
                    LogFile.Log("Found Lumia BootMgr and user forced to interrupt the boot process. Force to Flash-mode.");
                    Task.Run(() => SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Lumia_Flash));
                }
            }
        }
        internal async static Task <IDisposable> SwitchToWithStatus(PhoneNotifierViewModel Notifier, PhoneInterfaces?TargetMode, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, string RequestedVolumeForMassStorage = "MainOS")
        {
            if (Notifier.CurrentInterface == TargetMode)
            {
                return(Notifier.CurrentModel);
            }

            IDisposable Result            = null;
            string      LocalErrorMessage = null;

            AsyncAutoResetEvent Event = new AsyncAutoResetEvent(false);

            SwitchModeViewModel Switch = new SwitchModeViewModel(
                Notifier,
                TargetMode,
                null,
                (string ErrorMessage) =>
            {
                LocalErrorMessage = ErrorMessage;
                Event.Set();
            },
                (IDisposable NewModel, PhoneInterfaces NewInterface) =>
            {
                Result = NewModel;
                Event.Set();
            }, SetWorkingStatus, UpdateWorkingStatus
                );

            await Event.WaitAsync(Timeout.InfiniteTimeSpan);

            if (LocalErrorMessage != null)
            {
                throw new WPinternalsException(LocalErrorMessage);
            }

            return(Result);
        }
Example #21
0
        internal static async Task RecoverBadGPT(string GPTPath, string LoadersPath)
        {
            byte[] GPT = File.ReadAllBytes(GPTPath);

            PhoneNotifierViewModel PhoneNotifier = new PhoneNotifierViewModel();

            PhoneNotifier.Start();
            await SwitchModeViewModel.SwitchTo(PhoneNotifier, PhoneInterfaces.Qualcomm_Download);

            byte[] RootKeyHash = null;
            if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download)
            {
                QualcommDownload Download2 = new QualcommDownload((QualcommSerial)PhoneNotifier.CurrentModel);
                RootKeyHash = Download2.GetRKH();
            }

            List <QualcommPartition> PossibleLoaders = null;

            if (PhoneNotifier.CurrentInterface == PhoneInterfaces.Qualcomm_Download)
            {
                try
                {
                    PossibleLoaders = QualcommLoaders.GetPossibleLoadersForRootKeyHash(LoadersPath, RootKeyHash);
                    if (PossibleLoaders.Count == 0)
                    {
                        throw new Exception("Error: No matching loaders found for RootKeyHash.");
                    }
                }
                catch (Exception Ex)
                {
                    LogFile.LogException(Ex);
                    throw new Exception("Error: Unexpected error during scanning for loaders.");
                }
            }

            QualcommSerial   Serial   = (QualcommSerial)PhoneNotifier.CurrentModel;
            QualcommDownload Download = new QualcommDownload(Serial);

            if (Download.IsAlive())
            {
                int  Attempt = 1;
                bool Result  = false;
                foreach (QualcommPartition Loader in PossibleLoaders)
                {
                    LogFile.Log("Attempt " + Attempt.ToString(), LogType.ConsoleOnly);

                    try
                    {
                        Download.SendToPhoneMemory(0x2A000000, Loader.Binary);
                        Download.StartBootloader(0x2A000000);
                        Result = true;
                        LogFile.Log("Loader sent successfully", LogType.ConsoleOnly);
                    }
                    catch { }

                    if (Result)
                    {
                        break;
                    }

                    Attempt++;
                }
                Serial.Close();

                if (!Result)
                {
                    LogFile.Log("Loader failed", LogType.ConsoleOnly);
                }
            }
            else
            {
                LogFile.Log("Failed to communicate to Qualcomm Emergency Download mode", LogType.ConsoleOnly);
                throw new BadConnectionException();
            }

            if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
            {
                await PhoneNotifier.WaitForArrival();
            }
            if (PhoneNotifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
            {
                throw new WPinternalsException("Phone failed to switch to emergency flash mode.");
            }

            // Flash bootloader
            QualcommSerial Serial2 = (QualcommSerial)PhoneNotifier.CurrentModel;

            Serial2.EncodeCommands = false;

            QualcommFlasher Flasher = new QualcommFlasher(Serial2);

            Flasher.Hello();
            Flasher.SetSecurityMode(0);
            Flasher.OpenPartition(0x21);

            LogFile.Log("Partition opened.", LogType.ConsoleOnly);

            LogFile.Log("Flash GPT at 0x" + ((UInt32)0x200).ToString("X8"), LogType.ConsoleOnly);
            Flasher.Flash(0x200, GPT, 0, 0x41FF); // Bad bounds-check in the flash-loader prohibits to write the last byte.

            Flasher.ClosePartition();

            LogFile.Log("Partition closed. Flashing ready. Rebooting.");

            Flasher.Reboot();

            Flasher.CloseSerial();
        }
Example #22
0
        public void StartOperation()
        {
            IsMenuEnabled = true;

            _GettingStartedViewModel = new GettingStartedViewModel(
                () =>
            {
                ContextViewModel           = new DisclaimerViewModel(
                    () => ContextViewModel = _GettingStartedViewModel
                    );
            },
                SwitchToUnlockBoot,
                SwitchToUnlockRoot,
                SwitchToBackup,
                SwitchToDumpFFU,
                SwitchToFlashRom,
                SwitchToDownload
                );
            this.ContextViewModel = _GettingStartedViewModel;

            PhoneNotifier = new PhoneNotifierViewModel();
            PhoneNotifier.NewDeviceArrived += PhoneNotifier_NewDeviceArrived;
            PhoneNotifier.DeviceRemoved    += PhoneNotifier_DeviceRemoved;

            InfoViewModel = new LumiaInfoViewModel(PhoneNotifier, (TargetInterface) =>
            {
                ModeViewModel.OnModeSwitchRequested(TargetInterface);
                ContextViewModel = ModeViewModel;
            },
                                                   () =>
            {
                ContextViewModel = _GettingStartedViewModel;
            });
            InfoViewModel.ActivateSubContext(null);

            ModeViewModel = new LumiaModeViewModel(PhoneNotifier, SwitchToInfoViewModel);
            ModeViewModel.ActivateSubContext(null);

            BootUnlockViewModel = new LumiaUnlockBootViewModel(PhoneNotifier, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, true, SwitchToInfoViewModel);
            BootUnlockViewModel.ActivateSubContext(null);

            BootRestoreViewModel = new LumiaUnlockBootViewModel(PhoneNotifier, SwitchToFlashRom, SwitchToUndoRoot, SwitchToDownload, false, SwitchToInfoViewModel);
            BootRestoreViewModel.ActivateSubContext(null);

            RootUnlockViewModel = new LumiaUnlockRootViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToDumpFFU, SwitchToFlashRom, true, SwitchToInfoViewModel);
            RootUnlockViewModel.ActivateSubContext(null);

            RootRestoreViewModel = new LumiaUnlockRootViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToDumpFFU, SwitchToFlashRom, false, SwitchToInfoViewModel);
            RootRestoreViewModel.ActivateSubContext(null);

            BackupViewModel = new BackupViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToInfoViewModel);
            BackupViewModel.ActivateSubContext(null);

            RestoreViewModel = new RestoreViewModel(PhoneNotifier, SwitchToDifferentInterface, SwitchToUnlockBoot, SwitchToFlashRom, SwitchToInfoViewModel);
            RestoreViewModel.ActivateSubContext(null);

            LumiaFlashRomViewModel = new LumiaFlashRomViewModel(PhoneNotifier, SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToDumpFFU, SwitchToBackup, SwitchToInfoViewModel);
            LumiaFlashRomViewModel.ActivateSubContext(null);

            DumpRomViewModel = new DumpRomViewModel(SwitchToUnlockBoot, SwitchToUnlockRoot, SwitchToFlashRom);
            DumpRomViewModel.ActivateSubContext(null);

            DownloadsViewModel  = new DownloadsViewModel(PhoneNotifier);
            App.DownloadManager = DownloadsViewModel;

            PhoneNotifier.Start();
        }
        internal SwitchModeViewModel(PhoneNotifierViewModel PhoneNotifier, PhoneInterfaces?TargetMode, ModeSwitchProgressHandler ModeSwitchProgress, ModeSwitchErrorHandler ModeSwitchError, ModeSwitchSuccessHandler ModeSwitchSuccess, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null)
            : base()
        {
            if ((PhoneNotifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) && (TargetMode == PhoneInterfaces.Lumia_Flash))
            {
                PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo(false);
                if (Info.BootManagerProtocolVersionMajor >= 2)
                {
                    try
                    {
                        // The implementation of SwitchToFlashAppContext() is improved
                        // SwitchToFlashAppContext() should only be used with BootMgr v2
                        // For switching from BootMgr to FlashApp, it will use NOKS
                        // That will switch to a charging state, whereas a normal context switch will not start charging
                        // The implementation of NOKS in BootMgr mode has changed in BootMgr v2
                        // It does not disconnect / reconnect anymore and the apptype is changed immediately
                        // NOKS still doesnt return a status
                        // BootMgr v1 uses normal NOKS and waits for arrival of FlashApp
                        ((NokiaFlashModel)PhoneNotifier.CurrentModel).SwitchToFlashAppContext();

                        // But this was called as a real switch, so we will raise an arrival event.
                        PhoneNotifier.CurrentInterface = PhoneInterfaces.Lumia_Flash;
                        PhoneNotifier.NotifyArrival();
                    }
                    catch { }
                }
            }

            if (PhoneNotifier.CurrentInterface == TargetMode)
            {
                ModeSwitchSuccess(PhoneNotifier.CurrentModel, (PhoneInterfaces)PhoneNotifier.CurrentInterface);
            }
            else
            {
                this.PhoneNotifier = PhoneNotifier;
                this.CurrentModel  = (NokiaPhoneModel)PhoneNotifier.CurrentModel;
                this.CurrentMode   = PhoneNotifier.CurrentInterface;
                this.TargetMode    = TargetMode;
                if (ModeSwitchProgress != null)
                {
                    this.ModeSwitchProgress += ModeSwitchProgress;
                }
                if (ModeSwitchError != null)
                {
                    this.ModeSwitchError += ModeSwitchError;
                }
                if (ModeSwitchSuccess != null)
                {
                    this.ModeSwitchSuccess += ModeSwitchSuccess;
                }
                if (SetWorkingStatus != null)
                {
                    this.SetWorkingStatus = SetWorkingStatus;
                }
                if (UpdateWorkingStatus != null)
                {
                    this.UpdateWorkingStatus = UpdateWorkingStatus;
                }

                if (this.CurrentMode == null)
                {
                    LogFile.Log("Waiting for phone to connect...", LogType.FileAndConsole);
                    PhoneNotifier.NewDeviceArrived += NewDeviceArrived;
                }
                else
                {
                    // Make sure this ViewModel has its View loaded before we continue,
                    // or else loading of Views can get mixed up.
                    if (SynchronizationContext.Current == null)
                    {
                        StartSwitch();
                    }
                    else
                    {
                        SynchronizationContext.Current.Post((s) =>
                        {
                            ((SwitchModeViewModel)s).StartSwitch();
                        }, this);
                    }
                }
            }
        }
 internal async static Task <IDisposable> SwitchTo(PhoneNotifierViewModel Notifier, PhoneInterfaces?TargetMode, string RequestedVolumeForMassStorage = "MainOS")
 {
     return(await SwitchToWithProgress(Notifier, TargetMode, null, RequestedVolumeForMassStorage));
 }
Example #25
0
        // V3 exploit
        // Magic
        //
        internal async static Task LumiaV3CustomFlash(PhoneNotifierViewModel Notifier, List <FlashPart> FlashParts, bool CheckSectorAlignment = true, SetWorkingStatus SetWorkingStatus = null, UpdateWorkingStatus UpdateWorkingStatus = null, ExitSuccess ExitSuccess = null, ExitFailure ExitFailure = null)
        {
            if (SetWorkingStatus == null)
            {
                SetWorkingStatus = (m, s, v, a, st) => { }
            }
            ;
            if (UpdateWorkingStatus == null)
            {
                UpdateWorkingStatus = (m, s, v, st) => { }
            }
            ;
            if (ExitSuccess == null)
            {
                ExitSuccess = (m, s) => { }
            }
            ;
            if (ExitFailure == null)
            {
                ExitFailure = (m, s) => { }
            }
            ;

            uint chunkSize  = 131072u;
            int  chunkSizes = 131072;

            if (FlashParts != null)
            {
                foreach (FlashPart Part in FlashParts)
                {
                    if (Part.Stream == null)
                    {
                        throw new ArgumentException("Stream is null");
                    }
                    if (!Part.Stream.CanSeek)
                    {
                        throw new ArgumentException("Streams must be seekable");
                    }
                    if (((Part.StartSector * 0x200) % chunkSize) != 0)
                    {
                        throw new ArgumentException("Invalid StartSector alignment");
                    }
                    if (CheckSectorAlignment)
                    {
                        if ((Part.Stream.Length % chunkSize) != 0)
                        {
                            throw new ArgumentException("Invalid Data length");
                        }
                    }
                }
            }

            try
            {
                NokiaFlashModel Model = (NokiaFlashModel)Notifier.CurrentModel;
                PhoneInfo       Info  = Model.ReadPhoneInfo();

                if ((Info.SecureFfuSupportedProtocolMask & ((ushort)FfuProtocol.ProtocolSyncV2)) == 0) // Exploit needs protocol v2 -> This check is not conclusive, because old phones also report support for this protocol, although it is really not supported.
                {
                    throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that it does not support the Protocol Sync V2.");
                }
                if (Info.FlashAppProtocolVersionMajor < 2) // Old phones do not support the hack. These phones have Flash protocol 1.x.
                {
                    throw new WPinternalsException("Flash failed!", "Protocols not supported. The phone reports that Flash App communication protocol is lower than 2. Reported version by the phone: " + Info.FlashAppProtocolVersionMajor + ".");
                }

                if (Info.UefiSecureBootEnabled)
                {
                    throw new WPinternalsException("Flash failed!", "UEFI Secureboot must be disabled for the Flash V3 exploit to work.");
                }

                // The payloads must be ordered by the number of locations
                //
                // FlashApp processes payloads like this:
                // - First payloads which are with one location, those can be sent in bulk
                // - Then payloads with more than one location, those should not be sent in bulk
                //
                // If you do not order payloads like this, you will get an error, most likely hash mismatch
                //
                LumiaV2UnlockBootViewModel.FlashingPayload[] payloads = new LumiaV2UnlockBootViewModel.FlashingPayload[0];
                if (FlashParts != null)
                {
                    payloads = LumiaV2UnlockBootViewModel.GetNonOptimizedPayloads(FlashParts, chunkSizes, (uint)(Info.WriteBufferSize / chunkSize), SetWorkingStatus, UpdateWorkingStatus).OrderBy(x => x.TargetLocations.Count()).ToArray();
                }

                MemoryStream Headerstream1 = new MemoryStream();

                // ==============================
                // Header 1 start

                ImageHeader image   = new ImageHeader();
                FullFlash   ffimage = new FullFlash();
                Store       simage  = new Store();

                // Todo make this read the image itself
                ffimage.OSVersion         = "10.0.11111.0";
                ffimage.DevicePlatformId0 = Info.PlatformID;
                ffimage.AntiTheftVersion  = "1.1";

                simage.SectorSize     = 512;
                simage.MinSectorCount = Info.EmmcSizeInSectors;

                //Logging.Log("Generating image manifest...");
                string manifest = ManifestIni.BuildUpManifest(ffimage, simage);//, partitions);

                byte[] TextBytes = System.Text.Encoding.ASCII.GetBytes(manifest);

                image.ManifestLength = (UInt32)TextBytes.Length;

                byte[] ImageHeaderBuffer = new byte[0x18];

                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0, image.Size);
                ByteOperations.WriteAsciiString(ImageHeaderBuffer, 0x04, image.Signature);
                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x10, image.ManifestLength);
                ByteOperations.WriteUInt32(ImageHeaderBuffer, 0x14, image.ChunkSize);

                Headerstream1.Write(ImageHeaderBuffer, 0, 0x18);
                Headerstream1.Write(TextBytes, 0, TextBytes.Length);

                RoundUpToChunks(Headerstream1, chunkSize);

                // Header 1 stop + round
                // ==============================

                MemoryStream Headerstream2 = new MemoryStream();

                // ==============================
                // Header 2 start

                StoreHeader store = new StoreHeader();

                store.WriteDescriptorCount = (UInt32)payloads.Count();
                store.FinalTableIndex      = (UInt32)payloads.Count() - store.FinalTableCount;
                store.PlatformId           = Info.PlatformID;

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    store.WriteDescriptorLength += payload.GetStoreHeaderSize();
                }

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    /*if (payload.TargetLocations.First() > PlatEnd)
                     *  break;*/
                    store.FlashOnlyTableIndex += 1;
                }

                byte[] StoreHeaderBuffer = new byte[0xF8];
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0, store.UpdateType);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x04, store.MajorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x06, store.MinorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x08, store.FullFlashMajorVersion);
                ByteOperations.WriteUInt16(StoreHeaderBuffer, 0x0A, store.FullFlashMinorVersion);
                ByteOperations.WriteAsciiString(StoreHeaderBuffer, 0x0C, store.PlatformId);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xCC, store.BlockSizeInBytes);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD0, store.WriteDescriptorCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD4, store.WriteDescriptorLength);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xD8, store.ValidateDescriptorCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xDC, store.ValidateDescriptorLength);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE0, store.InitialTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE4, store.InitialTableCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xE8, store.FlashOnlyTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xEC, store.FlashOnlyTableCount);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF0, store.FinalTableIndex);
                ByteOperations.WriteUInt32(StoreHeaderBuffer, 0xF4, store.FinalTableCount);
                Headerstream2.Write(StoreHeaderBuffer, 0, 0xF8);

                byte[] descriptorsBuffer = new byte[store.WriteDescriptorLength];

                UInt32 NewWriteDescriptorOffset = 0;
                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, (UInt32)payload.TargetLocations.Count()); // Location count
                    ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, payload.ChunkCount);                      // Chunk count
                    NewWriteDescriptorOffset += 0x08;

                    foreach (UInt32 location in payload.TargetLocations)
                    {
                        ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x00, 0x00000000);                          // Disk access method (0 = Begin, 2 = End)
                        ByteOperations.WriteUInt32(descriptorsBuffer, NewWriteDescriptorOffset + 0x04, location);                            // Chunk index
                        NewWriteDescriptorOffset += 0x08;
                    }
                }

                Headerstream2.Write(descriptorsBuffer, 0, (Int32)store.WriteDescriptorLength);

                RoundUpToChunks(Headerstream2, chunkSize);

                // Header 2 stop + round
                // ==============================

                SecurityHeader security = new SecurityHeader();

                Headerstream1.Seek(0, SeekOrigin.Begin);
                Headerstream2.Seek(0, SeekOrigin.Begin);

                security.HashTableSize = 0x20 * (UInt32)((Headerstream1.Length + Headerstream2.Length) / chunkSize);

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    security.HashTableSize += payload.GetSecurityHeaderSize();
                }

                byte[]       HashTable = new byte[security.HashTableSize];
                BinaryWriter bw        = new BinaryWriter(new MemoryStream(HashTable));

                SHA256 crypto = SHA256.Create();
                for (int i = 0; i < Headerstream1.Length / chunkSize; i++)
                {
                    byte[] buffer = new byte[chunkSize];
                    Headerstream1.Read(buffer, 0, (Int32)chunkSize);
                    byte[] hash = crypto.ComputeHash(buffer);
                    bw.Write(hash, 0, hash.Length);
                }

                for (int i = 0; i < Headerstream2.Length / chunkSize; i++)
                {
                    byte[] buffer = new byte[chunkSize];
                    Headerstream2.Read(buffer, 0, (Int32)chunkSize);
                    byte[] hash = crypto.ComputeHash(buffer);
                    bw.Write(hash, 0, hash.Length);
                }

                foreach (LumiaV2UnlockBootViewModel.FlashingPayload payload in payloads)
                {
                    bw.Write(payload.ChunkHashes[0], 0, payload.ChunkHashes[0].Length);
                }

                bw.Close();

                //Logging.Log("Generating image catalog...");
                byte[] catalog = GenerateCatalogFile(HashTable);

                security.CatalogSize = (UInt32)catalog.Length;

                byte[] SecurityHeaderBuffer = new byte[0x20];

                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0, security.Size);
                ByteOperations.WriteAsciiString(SecurityHeaderBuffer, 0x04, security.Signature);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x10, security.ChunkSizeInKb);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x14, security.HashAlgorithm);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x18, security.CatalogSize);
                ByteOperations.WriteUInt32(SecurityHeaderBuffer, 0x1C, security.HashTableSize);

                MemoryStream retstream = new MemoryStream();

                retstream.Write(SecurityHeaderBuffer, 0, 0x20);

                retstream.Write(catalog, 0, (Int32)security.CatalogSize);
                retstream.Write(HashTable, 0, (Int32)security.HashTableSize);

                RoundUpToChunks(retstream, chunkSize);

                Headerstream1.Seek(0, SeekOrigin.Begin);
                Headerstream2.Seek(0, SeekOrigin.Begin);

                byte[] buff = new byte[Headerstream1.Length];
                Headerstream1.Read(buff, 0, (Int32)Headerstream1.Length);

                Headerstream1.Close();

                retstream.Write(buff, 0, buff.Length);

                buff = new byte[Headerstream2.Length];
                Headerstream2.Read(buff, 0, (Int32)Headerstream2.Length);

                Headerstream2.Close();

                retstream.Write(buff, 0, buff.Length);

                // --------

                // Go back to the beginning
                retstream.Seek(0, SeekOrigin.Begin);

                byte[] FfuHeader = new byte[retstream.Length];
                await retstream.ReadAsync(FfuHeader, 0, (int)retstream.Length);

                retstream.Close();

                byte Options = 0;
                if (!Info.IsBootloaderSecure)
                {
                    Options = (byte)((FlashOptions)Options | FlashOptions.SkipSignatureCheck);
                }

                LogFile.Log("Flash in progress...", LogType.ConsoleOnly);
                SetWorkingStatus("Flashing...", null, (UInt64?)payloads.Count(), Status: WPinternalsStatus.Flashing);

                Model.SendFfuHeaderV1(FfuHeader, Options);

                UInt64 counter = 0;

                int    numberOfPayloadsToSendAtOnce = (int)Math.Round((double)Info.WriteBufferSize / chunkSize);
                byte[] payloadBuffer;

                for (int i = 0; i < payloads.Count(); i += numberOfPayloadsToSendAtOnce)
                {
                    if (i + numberOfPayloadsToSendAtOnce - 1 >= payloads.Count())
                    {
                        numberOfPayloadsToSendAtOnce = payloads.Count() - i;
                    }

                    payloadBuffer = new byte[numberOfPayloadsToSendAtOnce * chunkSizes];

                    string ProgressText = "Flashing resources";

                    for (int j = 0; j < numberOfPayloadsToSendAtOnce; j++)
                    {
                        LumiaV2UnlockBootViewModel.FlashingPayload payload = payloads[i + j];

                        UInt32    StreamIndex = payload.StreamIndexes.First();
                        FlashPart flashPart   = FlashParts[(int)StreamIndex];

                        if (flashPart.ProgressText != null)
                        {
                            ProgressText = flashPart.ProgressText;
                        }

                        Stream Stream = flashPart.Stream;
                        Stream.Seek(payload.StreamLocations.First(), SeekOrigin.Begin);
                        Stream.Read(payloadBuffer, j * chunkSizes, chunkSizes);
                        counter++;
                    }

                    Model.SendFfuPayloadV2(payloadBuffer, int.Parse((counter * 100 / (ulong)payloads.Count()).ToString()));
                    UpdateWorkingStatus(ProgressText, null, counter, WPinternalsStatus.Flashing);
                }

                Model.ResetPhone();

                await Notifier.WaitForRemoval();

                ExitSuccess("Flash succeeded!", null);
            }
            catch
            {
                throw new WPinternalsException("Custom flash failed");
            }
        }
    }
}
 public LumiaUndoRootTargetSelectionViewModel(PhoneNotifierViewModel PhoneNotifier, Action SwitchToUnlockBoot, Action SwitchToDumpRom, Action SwitchToFlashRom, Action UnlockPhoneCallback, Action <string, string> UnlockImageCallback)
     : base(PhoneNotifier, SwitchToUnlockBoot, SwitchToDumpRom, SwitchToFlashRom, UnlockPhoneCallback, UnlockImageCallback)
 {
 }