Enhancements

- Improved error messages
- Added shutdown functionality from mass stoage
- Fixed an issue where 9006 would incorrectly be used for rebooting from mass storage
- Added support for gathering security information from older flash apps
- Added a new indicator in the empty view when a phone in bootloader mode is detected
- Fixed an issue where interrupting the bootloader may fail
- Added more checks to some functions
- Started to work on a bootloader view
- Fixed an issue where x50 phones in label mode would not get detected once being disconnected
- Added logging for Qualcomm Emergency Charging mode
- General bug fixes
This commit is contained in:
Gus
2019-12-28 09:39:02 +01:00
parent fa896b7c39
commit 81145ed0e9
30 changed files with 921 additions and 159 deletions
+1
View File
@@ -68,6 +68,7 @@ namespace WPinternals
case null:
case PhoneInterfaces.Lumia_Bootloader:
ActivateSubContext(null);
//ActivateSubContext(new NokiaBootloaderViewModel((NokiaFlashModel)CurrentModel, ModeSwitchRequestCallback, SwitchToGettingStarted));
break;
case PhoneInterfaces.Lumia_Normal:
ActivateSubContext(new NokiaNormalViewModel((NokiaPhoneModel)CurrentModel, ModeSwitchRequestCallback));
+4
View File
@@ -78,7 +78,11 @@ namespace WPinternals
switch (CurrentInterface)
{
case null:
ActivateSubContext(null);
break;
case PhoneInterfaces.Lumia_Bootloader:
ActivateSubContext(null);
//ActivateSubContext(new NokiaModeBootloaderViewModel((NokiaFlashModel)CurrentModel, OnModeSwitchRequested));
break;
case PhoneInterfaces.Lumia_Normal:
ActivateSubContext(new NokiaModeNormalViewModel((NokiaPhoneModel)CurrentModel, OnModeSwitchRequested));
+5 -2
View File
@@ -134,11 +134,14 @@ namespace WPinternals
TestPos = 1;
UefiSecurityStatusResponse SecurityStatus = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadSecurityStatus();
IsBootLoaderUnlocked = (SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus);
if (SecurityStatus != null)
IsBootLoaderUnlocked = (SecurityStatus.AuthenticationStatus || SecurityStatus.RdcStatus || !SecurityStatus.SecureFfuEfuseStatus);
TestPos = 2;
PhoneInfo Info = ((NokiaFlashModel)PhoneNotifier.CurrentModel).ReadPhoneInfo();
if (SecurityStatus == null)
IsBootLoaderUnlocked = (Info.Authenticated || Info.RdcPresent || !Info.SecureFfuEnabled);
TestPos = 3;
@@ -255,7 +258,7 @@ namespace WPinternals
if (FFUs.Count() > 0)
ProfileFFU = new FFU(FFUs[0].Path);
else
throw new WPinternalsException("Profile FFU missing");
throw new WPinternalsException("Profile FFU missing", "No profile FFU has been found in the repository for your device. You can add a profile FFU within the download section of the tool or by using the command line.");
LogFile.Log("Profile FFU: " + ProfileFFU.Path);
+20 -20
View File
@@ -262,7 +262,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
NewGPT = ((NokiaFlashModel)Notifier.CurrentModel).ReadGPT();
@@ -272,7 +272,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
else
{
@@ -501,7 +501,7 @@ namespace WPinternals
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
throw new WPinternalsException("Phone failed to switch to DLOAD.");
throw new WPinternalsException("Phone failed to switch to emergency download mode.");
}
// Send loader
@@ -512,7 +512,7 @@ namespace WPinternals
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
throw new WPinternalsException("Phone failed to switch to DLOAD.");
throw new WPinternalsException("Phone failed to switch to emergency flash mode.");
}
// Flash bootloader
@@ -584,7 +584,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader && Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{
@@ -593,7 +593,7 @@ namespace WPinternals
}
else
{
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash, download, or emergency flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
SetWorkingStatus("Rebooting phone...");
@@ -603,7 +603,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader && Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
NokiaFlashModel FlashModel = (NokiaFlashModel)Notifier.CurrentModel;
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash && FlashModel.ReadParam("FS")[3] > 0)
@@ -750,7 +750,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
NewGPT = ((NokiaFlashModel)Notifier.CurrentModel).ReadGPT();
@@ -760,7 +760,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
else
{
@@ -1122,7 +1122,7 @@ namespace WPinternals
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Download)
throw new WPinternalsException("Phone failed to switch to DLOAD.");
throw new WPinternalsException("Phone failed to switch to emergency download mode.");
}
// Send loader
@@ -1133,7 +1133,7 @@ namespace WPinternals
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Qualcomm_Flash)
throw new WPinternalsException("Phone failed to switch to DLOAD.");
throw new WPinternalsException("Phone failed to switch to emergency flash mode.");
}
// Flash bootloader
@@ -1211,7 +1211,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader && Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
{
@@ -1222,7 +1222,7 @@ namespace WPinternals
}
else
{
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash, download or emergency flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
await LumiaUnlockBootloaderViewModel.LumiaUnlockUEFI(Notifier, FFUPath, LoadersPath, SupportedFFUPath, SetWorkingStatus, UpdateWorkingStatus, null, (string Message, string SubMessage) =>
@@ -1346,7 +1346,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
byte[] GPTChunk = GetGptChunk(((NokiaFlashModel)Notifier.CurrentModel), 0x20000);
@@ -1368,7 +1368,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash)
throw new WPinternalsException("Phone is in an unexpected mode.");
throw new WPinternalsException("Phone is in an unexpected mode.", "The phone should have been detected in flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
if (IsSpecB || IsUnlockedPartitionSBL3 != null)
@@ -1794,7 +1794,7 @@ namespace WPinternals
Partition EFIESPPartition = GPT.GetPartition("EFIESP");
if (EFIESPPartition == null)
throw new WPinternalsException("EFIESP partition not found!");
throw new WPinternalsException("EFIESP partition not found!", "No EFIESP partition was found in the provided FFU's GPT.");
if ((UInt64)UnlockedEFIESP.Length != (EFIESPPartition.SizeInSectors * 0x200))
throw new WPinternalsException("New EFIESP partition has wrong size. Size = 0x" + UnlockedEFIESP.Length.ToString("X8") + ". Expected size = 0x" + (EFIESPPartition.SizeInSectors * 0x200).ToString("X8"));
@@ -1866,7 +1866,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if ((Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader) && (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash))
throw new WPinternalsException("Error: Phone is in wrong mode");
throw new WPinternalsException("Error: Phone is in wrong mode", "The phone should have been detected in bootloader or flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
if (!IsSpecB && !SBL3Eng)
{
@@ -1994,7 +1994,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
throw new WPinternalsException("Phone is in wrong mode");
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext();
@@ -2140,7 +2140,7 @@ namespace WPinternals
await Notifier.WaitForArrival();
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader)
throw new WPinternalsException("Phone is in wrong mode");
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
}
((NokiaFlashModel)Notifier.CurrentModel).SwitchToFlashAppContext();
@@ -2356,7 +2356,7 @@ namespace WPinternals
PatchResult = App.PatchEngine.Patch(PatchDefinition);
if (!PatchResult)
throw new WPinternalsException("Failed to patch bootloader");
throw new WPinternalsException("Failed to patch bootloader", "An error occured while patching Operating System files on the EFIESP partition provided. Make sure no boot files have been tampered with and you use the latest version of the tool. This error cannot be caused by an incorrect Operating System version as the tool automatically uses replacement if the version isn't supported, unless the replacement files have been tampered with or are not compatible.");
}
LogFile.Log("Edit BCD");
+6 -6
View File
@@ -317,7 +317,7 @@ namespace WPinternals
Partition TargetPartition = GPT.GetPartition(PartitionName);
if (TargetPartition == null)
throw new WPinternalsException("Target partition not found!");
throw new WPinternalsException("Target partition not found!", "Couldn't find \"" + PartitionName + "\" from the device GPT.");
LogFile.Log("Target-partition found at sector: 0x" + TargetPartition.FirstSector.ToString("X8") + " - 0x" + TargetPartition.LastSector.ToString("X8"), LogType.FileAndConsole);
bool IsUnlocked = false;
@@ -498,7 +498,7 @@ namespace WPinternals
FFU FFU = new FFU(FFUPath);
UInt32 UpdateType = ByteOperations.ReadUInt32(FFU.StoreHeader, 0);
if (UpdateType != 0)
throw new WPinternalsException("Only Full Flash images supported");
throw new WPinternalsException("Only Full Flash images supported", "The provided FFU file reports that it doesn't support Full Flash updates, but may support something else such as Partial Flash updates. This is not supported.");
if (FlashParts != null)
{
@@ -519,9 +519,9 @@ namespace WPinternals
}
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");
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");
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 + ".");
UEFI UEFI = new UEFI(FFU.GetPartition("UEFI"));
string BootMgrName = UEFI.EFIs.Where(efi => ((efi.Name != null) && (efi.Name.Contains("BootMgrApp")))).First().Name;
UInt32 EstimatedSizeOfMemGap = (UInt32)UEFI.GetFile(BootMgrName).Length;
@@ -689,7 +689,7 @@ namespace WPinternals
#endregion
if ((Notifier.CurrentInterface != PhoneInterfaces.Lumia_Flash) && (Notifier.CurrentInterface != PhoneInterfaces.Lumia_Bootloader))
throw new WPinternalsException("Phone is in wrong mode");
throw new WPinternalsException("Phone is in wrong mode", "The phone should have been detected in bootloader or flash mode. Instead it has been detected in " + Notifier.CurrentInterface.ToString() + " mode.");
Model = (NokiaFlashModel)Notifier.CurrentModel;
UpdateWorkingStatus("Initializing flash...", null, null);
}
@@ -2076,7 +2076,7 @@ namespace WPinternals
App.PatchEngine.TargetPath = ((MassStorage)Notifier.CurrentModel).Drive + "\\";
bool PatchResult = App.PatchEngine.Patch("SecureBootHack-MainOS");
if (!PatchResult)
throw new WPinternalsException("Patch failed");
throw new WPinternalsException("Patch failed", "An error occured while patching Operating System files on the MainOS partition of your phone. Make sure your phone runs a supported Operating System version.");
LogFile.Log("Fixed bootloader", LogType.FileAndConsole);
LogFile.Log("The phone is left in Mass Storage mode", LogType.FileAndConsole);
LogFile.Log("Press and hold the power-button of the phone for at least 10 seconds to reset the phone", LogType.FileAndConsole);
+76
View File
@@ -0,0 +1,76 @@
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Threading;
namespace WPinternals
{
// Create this class on the UI thread, after the main-window of the application is initialized.
// It is necessary to create the object on the UI thread, because notification events to the View need to be fired on that thread.
// The Model for this ViewModel communicates over USB and for that it uses the hWnd of the main window.
// Therefore the main window must be created before the ViewModel is created.
internal class NokiaBootloaderViewModel : ContextViewModel
{
private NokiaFlashModel CurrentModel;
private Action<PhoneInterfaces> RequestModeSwitch;
internal Action SwitchToGettingStarted;
private object LockDeviceInfo = new object();
internal NokiaBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces> RequestModeSwitch, Action SwitchToGettingStarted)
: base()
{
this.CurrentModel = (NokiaFlashModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch;
this.SwitchToGettingStarted = SwitchToGettingStarted;
}
// Device info should be loaded only one time and only when the ViewModel is active
internal override void EvaluateViewState()
{
if (IsActive)
new Thread(() => StartLoadDeviceInfo()).Start();
}
private void StartLoadDeviceInfo()
{
}
internal void RebootTo(string Mode)
{
switch (Mode)
{
case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break;
case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break;
case "MassStorage":
RequestModeSwitch(PhoneInterfaces.Lumia_MassStorage);
break;
default:
return;
}
}
}
}
+106 -38
View File
@@ -125,6 +125,11 @@ namespace WPinternals
Array.Copy(RawPublicID, 4, PublicID, 0, RawPublicID.Length - 4);
LogFile.Log("Public ID: " + Converter.ConvertHexToString(PublicID, " "));
}
else
{
PublicID = new byte[20];
LogFile.Log("Public ID: " + Converter.ConvertHexToString(PublicID, " "));
}
RootKeyHash = CurrentModel.ReadParam("RRKH");
if (RootKeyHash != null)
LogFile.Log("Root Key Hash: " + Converter.ConvertHexToString(RootKeyHash, " "));
@@ -153,50 +158,66 @@ namespace WPinternals
byte[] CID = CurrentModel.ReadParam("CID");
byte[] EMS = CurrentModel.ReadParam("EMS");
UInt16 MID = (UInt16)(((UInt16)CID[0] << 8) + CID[1]);
UInt64 MemSize = (UInt64)(((UInt32)EMS[0] << 24) + ((UInt32)EMS[1] << 16) + ((UInt32)EMS[2] << 8) + EMS[3]) * 0x200;
double MemSizeDouble = (double)MemSize / 1024 / 1024 / 1024;
MemSizeDouble = (double)(int)(MemSizeDouble * 10) / 10;
string Manufacturer = null;
switch (MID)
if (CID != null && EMS != null)
{
case 0x0002:
case 0x0045:
Manufacturer = "SanDisk";
break;
case 0x0011:
Manufacturer = "Toshiba";
break;
case 0x0013:
Manufacturer = "Micron";
break;
case 0x0015:
Manufacturer = "Samsung";
break;
case 0x0090:
Manufacturer = "Hynix";
break;
case 0x0070:
Manufacturer = "Kingston";
break;
case 0x00EC:
Manufacturer = "GigaDevice";
break;
UInt16 MID = (UInt16)(((UInt16)CID[0] << 8) + CID[1]);
UInt64 MemSize = (UInt64)(((UInt32)EMS[0] << 24) + ((UInt32)EMS[1] << 16) + ((UInt32)EMS[2] << 8) + EMS[3]) * 0x200;
double MemSizeDouble = (double)MemSize / 1024 / 1024 / 1024;
MemSizeDouble = (double)(int)(MemSizeDouble * 10) / 10;
string Manufacturer = null;
switch (MID)
{
case 0x0002:
case 0x0045:
Manufacturer = "SanDisk";
break;
case 0x0011:
Manufacturer = "Toshiba";
break;
case 0x0013:
Manufacturer = "Micron";
break;
case 0x0015:
Manufacturer = "Samsung";
break;
case 0x0090:
Manufacturer = "Hynix";
break;
case 0x0070:
Manufacturer = "Kingston";
break;
case 0x00EC:
Manufacturer = "GigaDevice";
break;
}
if (Manufacturer == null)
eMMC = MemSizeDouble.ToString() + " GB";
else
eMMC = Manufacturer + " " + MemSizeDouble.ToString() + " GB";
SamsungWarningVisible = (MID == 0x0015);
}
if (Manufacturer == null)
eMMC = MemSizeDouble.ToString() + " GB";
else
eMMC = Manufacturer + " " + MemSizeDouble.ToString() + " GB";
SamsungWarningVisible = (MID == 0x0015);
{
eMMC = "Unknown";
SamsungWarningVisible = true;
}
int chargecurrent = CurrentModel.ReadCurrentChargeCurrent().Value;
int? chargecurrent = CurrentModel.ReadCurrentChargeCurrent();
if (chargecurrent < 0)
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + ((-1) * CurrentModel.ReadCurrentChargeCurrent()) + " mA (discharging)";
if (chargecurrent.HasValue)
{
if (chargecurrent < 0)
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + ((-1) * CurrentModel.ReadCurrentChargeCurrent()) + " mA (discharging)";
else
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + CurrentModel.ReadCurrentChargeCurrent() + " mA (charging)";
LogFile.Log("Charging status: " + ChargingStatus);
}
else
ChargingStatus = CurrentModel.ReadCurrentChargeLevel() + "% - " + CurrentModel.ReadCurrentChargeCurrent() + " mA (charging)";
LogFile.Log("Charging status: " + ChargingStatus);
{
ChargingStatus = "Unknown";
LogFile.Log("Charging status: " + ChargingStatus);
}
PhoneInfo Info = CurrentModel.ReadPhoneInfo(true);
if (Info.FlashAppProtocolVersionMajor < 2)
@@ -210,6 +231,53 @@ namespace WPinternals
ProductType = Info.Type;
LogFile.Log("ProductType: " + ProductType);
if (RootKeyHash == null)
{
LogFile.Log("Root Key Hash was null. Gathering information from an alternative source.");
RootKeyHash = Info.RKH;
if (RootKeyHash != null)
LogFile.Log("Root Key Hash: " + Converter.ConvertHexToString(RootKeyHash, " "));
else
{
RootKeyHash = new byte[32];
LogFile.Log("Root Key Hash: " + Converter.ConvertHexToString(RootKeyHash, " "));
}
}
if (PlatformName == null)
{
LogFile.Log("Platform Name was null. Gathering information from an alternative source.");
PlatformName = Info.PlatformID;
LogFile.Log("Platform Name: " + PlatformName);
}
if (SecurityStatus == null)
{
LogFile.Log("Security Status was null. Gathering information from an alternative source.");
PlatformSecureBootStatus = Info.PlatformSecureBootEnabled;
LogFile.Log("Platform Secure Boot Status: " + PlatformSecureBootStatus.ToString());
UefiSecureBootStatus = Info.UefiSecureBootEnabled;
LogFile.Log("Uefi Secure Boot Status: " + UefiSecureBootStatus.ToString());
EffectiveSecureBootStatus = Info.PlatformSecureBootEnabled && Info.UefiSecureBootEnabled;
LogFile.Log("Effective Secure Boot Status: " + EffectiveSecureBootStatus.ToString());
BootloaderSecurityQfuseStatus = Info.SecureFfuEnabled;
LogFile.Log("Bootloader Security Qfuse Status: " + BootloaderSecurityQfuseStatus.ToString());
BootloaderSecurityAuthenticationStatus = Info.Authenticated;
LogFile.Log("Bootloader Security Authentication Status: " + BootloaderSecurityAuthenticationStatus.ToString());
BootloaderSecurityRdcStatus = Info.RdcPresent;
LogFile.Log("Bootloader Security Rdc Status: " + BootloaderSecurityRdcStatus.ToString());
EffectiveBootloaderSecurityStatus = Info.SecureFfuEnabled && !Info.Authenticated && !Info.RdcPresent;
LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString());
NativeDebugStatus = !Info.JtagDisabled;
LogFile.Log("Native Debug Status: " + NativeDebugStatus.ToString());
}
}
catch
{
+119
View File
@@ -0,0 +1,119 @@
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Threading;
namespace WPinternals
{
internal class NokiaModeBootloaderViewModel : ContextViewModel
{
private NokiaFlashModel CurrentModel;
Action<PhoneInterfaces?> RequestModeSwitch;
private object LockDeviceInfo = new object();
bool DeviceInfoLoaded = false;
internal NokiaModeBootloaderViewModel(NokiaPhoneModel CurrentModel, Action<PhoneInterfaces?> RequestModeSwitch)
: base()
{
this.CurrentModel = (NokiaFlashModel)CurrentModel;
this.RequestModeSwitch = RequestModeSwitch;
}
internal override void EvaluateViewState()
{
if (IsActive)
new Thread(() => StartLoadDeviceInfo()).Start();
}
private bool? _EffectiveBootloaderSecurityStatus = null;
public bool? EffectiveBootloaderSecurityStatus
{
get
{
return _EffectiveBootloaderSecurityStatus;
}
set
{
_EffectiveBootloaderSecurityStatus = value;
OnPropertyChanged("EffectiveBootloaderSecurityStatus");
}
}
internal void StartLoadDeviceInfo()
{
lock (LockDeviceInfo)
{
if (!DeviceInfoLoaded)
{
try
{
PhoneInfo Info = CurrentModel.ReadPhoneInfo();
if (Info.FlashAppProtocolVersionMajor < 2)
{
UefiSecurityStatusResponse SecurityStatus = CurrentModel.ReadSecurityStatus();
if (SecurityStatus != null)
{
EffectiveBootloaderSecurityStatus = SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus;
}
}
else
{
EffectiveBootloaderSecurityStatus = Info.UefiSecureBootEnabled;
}
LogFile.Log("Effective Bootloader Security Status: " + EffectiveBootloaderSecurityStatus.ToString());
}
catch
{
LogFile.Log("Reading status from Flash interface was aborted.");
}
DeviceInfoLoaded = true;
}
}
}
internal void RebootTo(string Mode)
{
switch (Mode)
{
case "Normal":
RequestModeSwitch(PhoneInterfaces.Lumia_Normal);
break;
case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break;
case "Label":
RequestModeSwitch(PhoneInterfaces.Lumia_Label);
break;
case "MassStorage":
RequestModeSwitch(PhoneInterfaces.Lumia_MassStorage);
break;
case "Shutdown":
RequestModeSwitch(null);
break;
default:
return;
}
}
}
}
+4
View File
@@ -75,6 +75,10 @@ namespace WPinternals
{
EffectiveBootloaderSecurityStatus = SecurityStatus.SecureFfuEfuseStatus && !SecurityStatus.AuthenticationStatus && !SecurityStatus.RdcStatus;
}
else
{
EffectiveBootloaderSecurityStatus = Info.SecureFfuEnabled && !Info.Authenticated && !Info.RdcPresent;
}
}
else
{
@@ -67,6 +67,9 @@ namespace WPinternals
case "Flash":
RequestModeSwitch(PhoneInterfaces.Lumia_Flash);
break;
case "Shutdown":
RequestModeSwitch(null);
break;
default:
return;
}
+52 -22
View File
@@ -165,8 +165,8 @@ namespace WPinternals
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
}
else if ((e.DevicePath.IndexOf("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_06FC is for Lumia 930
(e.DevicePath.IndexOf("vid_045e&pid_0a00", StringComparison.OrdinalIgnoreCase) >= 0)) // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
(e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_06FC is for Lumia 930
(e.DevicePath.IndexOf("VID_045E&PID_0A00", StringComparison.OrdinalIgnoreCase) >= 0)) // vid_045e & pid_0a00 & mi_03 = Lumia 950 XL normal mode
{
if (((USBNotifier)sender).Guid == OldCombiInterfaceGuid)
{
@@ -215,18 +215,16 @@ namespace WPinternals
}
}
else if ((e.DevicePath.IndexOf("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_0714 is for Lumia 930
(e.DevicePath.IndexOf("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0)) // VID_045E&PID_0A02 is for Lumia 950
(e.DevicePath.IndexOf("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) || // VID_0421&PID_0714 is for Lumia 930
(e.DevicePath.IndexOf("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0)) // VID_045E&PID_0A02 is for Lumia 950
{
CurrentModel = new NokiaFlashModel(e.DevicePath);
((NokiaFlashModel)CurrentModel).InterfaceChanged += InterfaceChanged;
// Attempt to request a param.
// When it succeeds we have full Flash mode.
// When it fails we are in a limited Flash mode, like Bootmanager or Hardreset-screen.
// Limited Flash mode only supports boot-commands; not querying info.
byte[] QueryResult = ((NokiaFlashModel)CurrentModel).ReadParam("SS");
if (QueryResult == null)
FlashAppType type = ((NokiaFlashModel)CurrentModel).GetFlashAppType();
LogFile.Log("Flash App Type: " + type.ToString(), LogType.FileOnly);
if (type == FlashAppType.BootManager)
{
CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
@@ -235,6 +233,15 @@ namespace WPinternals
LogFile.Log("Mode: Bootloader", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
}
else if (type == FlashAppType.PhoneInfoApp)
{
CurrentInterface = PhoneInterfaces.Lumia_Bootloader;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Bootloader (Phone Info)", LogType.FileAndConsole);
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
}
else
{
((NokiaFlashModel)CurrentModel).DisableRebootTimeOut();
@@ -246,8 +253,8 @@ namespace WPinternals
NewDeviceArrived(new ArrivalEventArgs((PhoneInterfaces)CurrentInterface, CurrentModel));
}
}
else if ((e.DevicePath.IndexOf(@"disk&ven_qualcomm&prod_mmc_storage", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0))
else if ((e.DevicePath.IndexOf(@"DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0))
{
#if DEBUG
LogFile.Log("Mass storage arrived: " + e.DevicePath, LogType.FileOnly);
@@ -266,11 +273,14 @@ namespace WPinternals
{
MassStorage NewModel = new MassStorage(e.DevicePath);
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
{
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
{
LogFile.Log("Found 9006 device previously on: " + Qcom9006DevicePath, LogType.FileOnly);
LogFile.Log("Attaching 9006 device", LogType.FileOnly);
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
}
CurrentInterface = PhoneInterfaces.Lumia_MassStorage;
CurrentModel = NewModel;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
@@ -301,11 +311,14 @@ namespace WPinternals
{
MassStorage NewModel = new MassStorage(e.DevicePath);
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
if (NewModel.Drive != null) // When logical drive is already known, we use this model. Or else we wait for the logical drive to arrive.
{
if (!string.IsNullOrEmpty(Qcom9006DevicePath))
{
LogFile.Log("Found 9006 device previously on: " + Qcom9006DevicePath, LogType.FileOnly);
LogFile.Log("Attaching 9006 device", LogType.FileOnly);
NewModel.AttachQualcommSerial(Qcom9006DevicePath);
}
CurrentInterface = PhoneInterfaces.Lumia_MassStorage;
CurrentModel = NewModel;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
@@ -355,12 +368,28 @@ namespace WPinternals
// It is a slightly different version of the Qualcomm Emergency interface, which is implemented in SBL3.
// One important difference is that the base address for sending a loader is not 0x2A000000, but it is 0x82F00000.
Qcom9006DevicePath = e.DevicePath;
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
LogFile.Log("Device path: " + Qcom9006DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Qualcomm Emergency 9006", LogType.FileAndConsole);
Qcom9006DevicePath = e.DevicePath;
if (CurrentModel is MassStorage)
{
LogFile.Log("Found Mass Storage device previously", LogType.FileOnly);
LogFile.Log("Attaching 9006 device", LogType.FileOnly);
((MassStorage)CurrentModel).AttachQualcommSerial(Qcom9006DevicePath);
}
}
else if (e.DevicePath.IndexOf("VID_05C6&PID_F006", StringComparison.OrdinalIgnoreCase) >= 0)
{
// This is part of the charging inteface.
LogFile.Log("Found device on interface: " + ((USBNotifier)sender).Guid.ToString(), LogType.FileOnly);
LogFile.Log("Device path: " + e.DevicePath, LogType.FileOnly);
LogFile.Log("Connected device: Lumia", LogType.FileAndConsole);
LogFile.Log("Mode: Qualcomm Emergency Charging F006", LogType.FileAndConsole);
}
}
catch (Exception Ex)
@@ -386,14 +415,15 @@ namespace WPinternals
if (
(e.DevicePath.IndexOf("VID_0421&PID_0660&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_0713&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_045E&PID_0A01&MI_04", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_0661", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_06FC", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_066E", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_0421&PID_0714", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("vid_045e&pid_0a00", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_045E&PID_0A00", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_045E&PID_0A02", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf("VID_05C6&PID_9008", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf(@"disk&ven_qualcomm&prod_mmc_storage", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf(@"DISK&VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.OrdinalIgnoreCase) >= 0) ||
(e.DevicePath.IndexOf(@"DISK&VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.OrdinalIgnoreCase) >= 0)
)
{
+12
View File
@@ -347,6 +347,12 @@ namespace WPinternals
ModeSwitchProgressWrapper("Rebooting phone to Flash mode...", null);
LogFile.Log("Rebooting phone to Flash mode...", LogType.FileAndConsole);
break;
case null:
((MassStorage)CurrentModel).Reboot();
PhoneNotifier.NewDeviceArrived += NewDeviceArrivedFromMassStorageMode;
ModeSwitchProgressWrapper("First rebooting phone to Flash mode...", null);
LogFile.Log("First rebooting phone to Bootloader mode...", LogType.FileAndConsole);
break;
default:
return;
}
@@ -389,6 +395,9 @@ namespace WPinternals
case PhoneInterfaces.Lumia_Normal:
ModeSwitchErrorWrapper("Failed to switch to Normal mode");
break;
case null:
ModeSwitchSuccessWrapper();
break;
}
}
});
@@ -406,6 +415,9 @@ namespace WPinternals
case PhoneInterfaces.Lumia_Normal:
ModeSwitchErrorWrapper("Failed to switch to Normal mode");
break;
case null:
ModeSwitchErrorWrapper("Failed to shutdown");
break;
}
}
}