Skip to content

Commit

Permalink
v2.1.0 (#49)
Browse files Browse the repository at this point in the history
Widevine, rm BID & SN; read the factory key (WVL)
  • Loading branch information
mashed-potatoes authored Mar 29, 2021
1 parent 1ae13f1 commit cda463c
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 125 deletions.
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "Potato.ImageFlasher"]
path = Potato.ImageFlasher
url = https://github.com/mashed-potatoes/Potato.ImageFlasher.git
[submodule "Potato.Fastboot"]
path = Potato.Fastboot
url = https://github.com/mashed-potatoes/Potato.Fastboot.git
[submodule "HiSiBootloaders"]
path = HiSiBootloaders
url = https://github.com/mashed-potatoes/HiSiBootloaders.git
1 change: 1 addition & 0 deletions HiSiBootloaders
Submodule HiSiBootloaders added at 013b9a
1 change: 1 addition & 0 deletions Potato.Fastboot
Submodule Potato.Fastboot added at 626760
1 change: 1 addition & 0 deletions Potato.ImageFlasher
Submodule Potato.ImageFlasher added at 49b4ab
20 changes: 20 additions & 0 deletions PotatoNV-next.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PotatoNV-next", "PotatoNV-next\PotatoNV-next.csproj", "{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Potato.Fastboot", "Potato.Fastboot\Potato.Fastboot\Potato.Fastboot.csproj", "{6C04F303-A659-4872-8136-D5C1D48A8F75}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Potato.ImageFlasher", "Potato.ImageFlasher\Potato.ImageFlasher\Potato.ImageFlasher.csproj", "{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +25,22 @@ Global
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|Any CPU.Build.0 = Release|Any CPU
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|x64.ActiveCfg = Release|x64
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|x64.Build.0 = Release|x64
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Debug|x64.ActiveCfg = Debug|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Debug|x64.Build.0 = Debug|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Release|Any CPU.Build.0 = Release|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Release|x64.ActiveCfg = Release|Any CPU
{6C04F303-A659-4872-8136-D5C1D48A8F75}.Release|x64.Build.0 = Release|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Debug|x64.ActiveCfg = Debug|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Debug|x64.Build.0 = Debug|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Release|Any CPU.Build.0 = Release|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Release|x64.ActiveCfg = Release|Any CPU
{B74D03CC-AC13-447A-BCD8-C2044DA84EEB}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
9 changes: 0 additions & 9 deletions PotatoNV-next/Controls/NVForm.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,10 @@
<Label Content="Bootloader" />
<ComboBox Name="deviceBootloader" />
</StackPanel>
<StackPanel>
<Label Content="Serial number (optional)" />
<TextBox x:Name="nvSerialNumber" />
</StackPanel>
<StackPanel>
<Label Content="Board ID (optional)" />
<TextBox x:Name="nvBidNumber" />
</StackPanel>
<StackPanel>
<Label Content="Unlock code" />
<TextBox x:Name="nvUnlockCode" />
</StackPanel>

<StackPanel>
<CheckBox x:Name="disableFBLOCK" Content="Disable FBLOCK" IsChecked="True" />
<Button x:Name="startButton" Content="Start!" Height="40" Margin="0,10,0,0" Click="StartButton_Click" />
Expand Down
10 changes: 0 additions & 10 deletions PotatoNV-next/Controls/NVForm.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ public class FormEventArgs : EventArgs
{
public UsbController.Device.DMode TargetMode { get; set; }
public string Target { get; set; }
public string BoardID { get; set; }
public string UnlockCode { get; set; }
public string SerialNumber { get; set; }
public bool DisableFBLOCK { get; set; }
public Bootloader Bootloader { get; set; } = null;
}
Expand Down Expand Up @@ -113,10 +111,6 @@ private void StartButton_Click(object sender, RoutedEventArgs e)

Assert(deviceBootloader.SelectedIndex != -1, "Couldn't find any valid bootloader!");

Assert(VerifyNVValue(nvSerialNumber.Text), "Serial number is not valid.");

Assert(VerifyNVValue(nvBidNumber.Text), "BoardID is not valid.");

Assert(VerifyNVValue(nvUnlockCode.Text, true), "Unlock code is not valid.");
}
catch
Expand All @@ -132,9 +126,7 @@ private void StartButton_Click(object sender, RoutedEventArgs e)
? UsbController.Device.DMode.Fastboot
: UsbController.Device.DMode.DownloadVCOM,
Target = deviceList.SelectedItem.ToString(),
BoardID = nvBidNumber.Text,
UnlockCode = nvUnlockCode.Text,
SerialNumber = nvSerialNumber.Text,
DisableFBLOCK = disableFBLOCK.IsChecked.Value
};

Expand All @@ -150,8 +142,6 @@ private void NVForm_IsEnabledChanged(object sender, DependencyPropertyChangedEve
{
deviceList.IsEnabled = IsEnabled;
deviceBootloader.IsEnabled = IsEnabled;
nvBidNumber.IsEnabled = IsEnabled;
nvSerialNumber.IsEnabled = IsEnabled;
nvUnlockCode.IsEnabled = IsEnabled;
disableFBLOCK.IsEnabled = IsEnabled;
startButton.IsEnabled = IsEnabled;
Expand Down
118 changes: 83 additions & 35 deletions PotatoNV-next/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ class Core
private Fastboot fb;
private Controls.NVForm.FormEventArgs args;

private void LogResponse(Fastboot.Response response)
{
Log.Debug($"response: {Encoding.UTF8.GetString(response.RawData)}");
}

private void FlashBootloader(Bootloader bootloader, string port)
{
var flasher = new ImageFlasher();
Expand All @@ -27,23 +32,20 @@ private void FlashBootloader(Bootloader bootloader, string port)
int asize = 0, dsize = 0;

foreach (var image in bootloader.Images)
{
Log.Debug($"VrStat of {image.Role}: {image.IsValid}");

{
if (!image.IsValid)
{
throw new Exception($"Image `{image.Role}` is invalid!");
throw new Exception($"Image `{image.Role}` is not valid!");
}

asize += image.Size;
}

Log.Success("Verification passed!");
Log.Debug($"Opening {port}...");

flasher.Open(port);

Log.Info($"Uploading {bootloader.Name} bootloader");
Log.Info($"Uploading {bootloader.Name}...");

foreach (var image in bootloader.Images)
{
Expand All @@ -60,39 +62,43 @@ private void FlashBootloader(Bootloader bootloader, string port)

flasher.Close();

Log.Success("Bootloader uploaded");
Log.SetProgressBar(false);
}

private void ReadInfo()
{
var serial = fb.GetSerialNumber();
Log.Info($"- Serial number: {serial}");
Log.Info($"Serial number: {serial}");

var bsn = fb.Command("oem read_bsn");
Log.Info($"- Board ID: {bsn.Payload}");
if (bsn.Status == Fastboot.Status.Okay)
{
Log.Info($"Board ID: {bsn.Payload}");
}

var model = fb.Command("oem get-product-model");
Log.Info($"- Model: {model.Payload}");
Log.Info($"Model: {model.Payload}");

var build = fb.Command("oem get-build-number");
Log.Info($"- Build number: {build.Payload.Replace(":", "")}");
Log.Info($"Build number: {build.Payload.Replace(":", "")}");

var regex = new Regex(@"FB[\w: ]{1,}UNLOCKED");
var fblock = fb.Command("oem lock-state info");
var state = regex.IsMatch(fblock.Payload);

Log.Info($"- FBLOCK state: {(state ? "unlocked" : "locked")}");
Log.Info($"FBLOCK state: {(state ? "unlocked" : "locked")}");
LogResponse(fblock);

if (!state)
{
throw new Exception("FBLOCK is locked!");
Log.Error("FBLOCK is locked!");
// throw new Exception("FBLOCK is locked!");
}
}

private void SetNVMEProp(string prop, byte[] value, string role = null)
private void SetNVMEProp(string prop, byte[] value)
{
Log.Info($"- Writing {role ?? prop}");
Log.Info($"Writing {prop}...");

var cmd = new List<byte>();

Expand All @@ -101,17 +107,14 @@ private void SetNVMEProp(string prop, byte[] value, string role = null)

var res = fb.Command(cmd.ToArray());

LogResponse(res);

if (!res.Payload.Contains("set nv ok"))
{
throw new Exception($"Failed to set prop: {res.Payload}");
throw new Exception($"Failed to set: {res.Payload}");
}
}

private void SetNVMEProp(string prop, string value, string role = null)
{
SetNVMEProp(prop, Encoding.ASCII.GetBytes(value), role);
}

public static byte[] GetSHA256(string str)
{
using (var sha256 = SHA256.Create())
Expand All @@ -120,20 +123,66 @@ public static byte[] GetSHA256(string str)
}
}

private void WriteNVME()
private void SetHWDogCertify(byte state)
{
SetNVMEProp("FBLOCK", new[] { (byte)(args.DisableFBLOCK ? 0 : 1) }, "FBLOCK state");
foreach (var command in new[] { "hwdog certify set", "backdoor set" })
{
Log.Info($"Trying {command}...");
var res = fb.Command($"oem {command} {state}");
LogResponse(res);
if (res.Status == Fastboot.Status.Okay || res.Payload.Contains("equal"))
{
Log.Success($"{command}: success");
return;
}
}
Log.Error("Failed to set FBLOCK state!");
}

SetNVMEProp("USRKEY", GetSHA256(args.UnlockCode), "User key");
private void WidevineLock()
{
Log.Debug("WV Lock");
var res = fb.Command("getvar:nve:WVLOCK");
LogResponse(res);
if (res.Status != Fastboot.Status.Fail && res.Payload.Replace("\n", "").Trim() != "UUUUUUUUUUUUUUUU")
{
Log.Info($"Read factory key: {res.Payload}");
}

if (!string.IsNullOrWhiteSpace(args.SerialNumber))
try
{
SetNVMEProp("SN", args.SerialNumber, "Serial number");
SetNVMEProp("WVLOCK", Encoding.ASCII.GetBytes(args.UnlockCode));
}
catch
{
Log.Error("Failed to set the WVLOCK.");
}
}

private void WriteNVME()
{
var fblockState = (byte)(args.DisableFBLOCK ? 0 : 1);

try
{
SetNVMEProp("FBLOCK", new[] { fblockState });
}
catch (Exception ex)
{
Log.Error("Failed to set the FBLOCK, using the alternative method...");
Log.Debug(ex.Message);
SetHWDogCertify(fblockState);
}

if (!string.IsNullOrWhiteSpace(args.BoardID))
try
{
SetNVMEProp("USRKEY", GetSHA256(args.UnlockCode));
WidevineLock();
}
catch (Exception ex)
{
SetNVMEProp("BOARDID", args.BoardID, "Board ID");
Log.Error("Failed to set the key.");
Log.Debug(ex.Message);
}
}

Expand All @@ -146,28 +195,23 @@ private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
if (args.TargetMode == UsbController.Device.DMode.DownloadVCOM)
{
Log.Info("--> Flashing bootloader");
FlashBootloader(args.Bootloader, args.Target.Split(':')[0]);

Log.Info("Waiting for any device...");
fb.Wait();
}

Log.Info("--> Reading information");
Log.Info("Connecting to fastboot device...");
Log.Info("Connecting...");

fb.Connect();
ReadInfo();

Log.Info("--> Updating NVME");
WriteNVME();

Log.Success("Update done!");
Log.Info("Rebooting...");

fb.Command("reboot");

Log.Info($"Bootloader unlock code: {args.UnlockCode}");
Log.Info($"New bootloader unlock code: {args.UnlockCode}");

fb.Disconnect();
}
Expand All @@ -176,6 +220,10 @@ private void Worker_DoWork(object sender, DoWorkEventArgs e)
Log.Error(ex.Message);
Log.Debug(ex.StackTrace);
}
finally
{
fb.Disconnect();
}
}

public void StartProcess(Controls.NVForm.FormEventArgs args)
Expand Down
1 change: 0 additions & 1 deletion PotatoNV-next/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
</Style>

<Style TargetType="TextBox">
<Setter Property="FontFamily" Value="Consolas" />
<Setter Property="MaxLength" Value="16" />
</Style>

Expand Down
2 changes: 0 additions & 2 deletions PotatoNV-next/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam

public MainWindow()
{
IntegrityCheck.Run();

Icon = MediaConverter.ImageSourceFromBitmap(Properties.Resources.Fire.ToBitmap());
InitializeComponent();

Expand Down
Loading

0 comments on commit cda463c

Please sign in to comment.