Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a982c119fb | ||
|
|
c6dee3fe33 | ||
|
|
91961b0e7b | ||
|
|
29c6ab06d4 | ||
|
|
b03b561724 | ||
|
|
91f534a7c3 | ||
|
|
f0f3268924 | ||
|
|
c269cfe839 | ||
|
|
7d8aad0e88 | ||
|
|
310d0b97c5 | ||
|
|
8e50c46357 | ||
|
|
e6555741b0 | ||
|
|
c21692491d | ||
|
|
350b6e8f1e | ||
|
|
0101477830 | ||
|
|
a6c017986b | ||
|
|
0174fc8b30 | ||
|
|
c6f6ef4429 | ||
|
|
ab0c35e879 | ||
|
|
676a95dd97 | ||
|
|
8981fd02e9 | ||
|
|
16d3f95971 | ||
|
|
293c649edb | ||
|
|
88efc77887 | ||
|
|
dc6085f185 | ||
|
|
e2cbb9c6fc | ||
|
|
4b7b9621b4 | ||
|
|
96c42a29b5 | ||
|
|
742c89b9bf | ||
|
|
dbd303fd07 | ||
|
|
8d35be447a | ||
|
|
83c09bdc81 | ||
|
|
93a5064751 | ||
|
|
ef6a962a01 | ||
|
|
d32788198d | ||
|
|
7798dd1c34 | ||
|
|
57cd052d61 | ||
|
|
5eb523530c | ||
|
|
8a17b05398 | ||
|
|
dc5ac1e7d4 | ||
|
|
1d14d79fab | ||
|
|
846ea41883 | ||
|
|
452393aaa7 | ||
|
|
17bc763761 | ||
|
|
668a9b7fe2 | ||
|
|
8293c18406 | ||
|
|
48fbfa77df | ||
|
|
709c91cec5 | ||
|
|
611ad122f9 | ||
|
|
d8fd0aa516 | ||
|
|
7f3c8b1777 | ||
|
|
087457fa0d | ||
|
|
bb9f614e82 |
@@ -0,0 +1,60 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Create a bug report to help improve WPinternals
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of what the bug is.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps To Reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Go to '....'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See the error
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected behavior
|
||||||
|
description: A clear and concise description of what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: wpi-version
|
||||||
|
attributes:
|
||||||
|
label: WPinternals Version
|
||||||
|
description: What version of WPinternals are you using?
|
||||||
|
placeholder: v2.9.2
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Windows Version
|
||||||
|
description: What version of Windows are you using? Press <kbd>Win</kbd> + <kbd>Pause/Break</kbd> and copy.
|
||||||
|
placeholder: e.g. Windows 11 21H2 22000.132
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
attributes:
|
||||||
|
label: Phone model
|
||||||
|
description: What phone model did you reproduce the bug on (if applicable)
|
||||||
|
placeholder: e.g. Lumia 950 XL (RM-1085)
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Relevant Assets
|
||||||
|
description: |
|
||||||
|
A list of assets (logs, screenshots) relevant to this bug.
|
||||||
|
|
||||||
|
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
|
||||||
|
placeholder: |
|
||||||
|
To upload the log
|
||||||
|
- Copy the `WPinternals.log` files from `%ALLUSERSPROFILE%\WPinternals`
|
||||||
|
- Drag and drop them into this text area.
|
||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
architecture: [x86, x64]
|
architecture: [x86, x64, arm64]
|
||||||
platform: [win]
|
platform: [win]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Install .NET SDK
|
- name: Install .NET SDK
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: "5.0.101"
|
dotnet-version: "8.0.x"
|
||||||
|
|
||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v1.0.2
|
uses: microsoft/setup-msbuild@v1.0.2
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Windows Phone Internals
|
||||||
|
|
||||||
|
Windows Phone Internals (WPinternals or WPI for short) is a tool designed to unlock the bootloader and/or secure boot of select Lumia devices made by Nokia and Microsoft.
|
||||||
|
Thanks to specifically crafted exploits/techniques the tool is able to disable Bootloader Security/SecureBoot on select Lumia models.
|
||||||
|
|
||||||
|
After unlocking your bootloader you will be able to notably perform the following actions:
|
||||||
|
|
||||||
|
- Boot other Operating Systems
|
||||||
|
- Enable Root Access (on select OS versions)
|
||||||
|
- Flash Custom ROMs
|
||||||
|
- Backup your current Windows Phone ROM
|
||||||
|
- Access your phone internal storage over USB
|
||||||
|
|
||||||
|
## Root Access
|
||||||
|
|
||||||
|
Root Access is a set of patches/hacks disabling security inside Windows Phone at its root. Kernel Security, Permission checks, application container security, deployment capability security and much gets disabled as part of enabling root access.
|
||||||
|
|
||||||
|
## How to get started?
|
||||||
|
|
||||||
|
The tool contains all the documentation you need to know more about the tool, we invite you to read the getting started section of the tool to know more.
|
||||||
|
|
||||||
|
## Where do I download the tool?
|
||||||
|
|
||||||
|
Here: https://github.com/ReneLergner/WPinternals/releases/latest
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<Application
|
||||||
|
x:Class="RootAccessTestUWP.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:RootAccessTestUWP"
|
||||||
|
RequestedTheme="Dark">
|
||||||
|
|
||||||
|
</Application>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.ApplicationModel;
|
||||||
|
using Windows.ApplicationModel.Activation;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
namespace RootAccessTestUWP
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides application-specific behavior to supplement the default Application class.
|
||||||
|
/// </summary>
|
||||||
|
sealed partial class App : Application
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
|
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
|
/// </summary>
|
||||||
|
public App()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
this.Suspending += OnSuspending;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||||
|
/// will be used such as when the application is launched to open a specific file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">Details about the launch request and process.</param>
|
||||||
|
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||||
|
{
|
||||||
|
Frame rootFrame = Window.Current.Content as Frame;
|
||||||
|
|
||||||
|
// Do not repeat app initialization when the Window already has content,
|
||||||
|
// just ensure that the window is active
|
||||||
|
if (rootFrame == null)
|
||||||
|
{
|
||||||
|
// Create a Frame to act as the navigation context and navigate to the first page
|
||||||
|
rootFrame = new Frame();
|
||||||
|
|
||||||
|
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||||
|
|
||||||
|
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||||
|
{
|
||||||
|
//TODO: Load state from previously suspended application
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place the frame in the current Window
|
||||||
|
Window.Current.Content = rootFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.PrelaunchActivated == false)
|
||||||
|
{
|
||||||
|
if (rootFrame.Content == null)
|
||||||
|
{
|
||||||
|
// When the navigation stack isn't restored navigate to the first page,
|
||||||
|
// configuring the new page by passing required information as a navigation
|
||||||
|
// parameter
|
||||||
|
rootFrame.Navigate(typeof(MainPage), e.Arguments);
|
||||||
|
}
|
||||||
|
// Ensure the current window is active
|
||||||
|
Window.Current.Activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when Navigation to a certain page fails
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The Frame which failed navigation</param>
|
||||||
|
/// <param name="e">Details about the navigation failure</param>
|
||||||
|
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when application execution is being suspended. Application state is saved
|
||||||
|
/// without knowing whether the application will be terminated or resumed with the contents
|
||||||
|
/// of memory still intact.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The source of the suspend request.</param>
|
||||||
|
/// <param name="e">Details about the suspend request.</param>
|
||||||
|
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||||
|
{
|
||||||
|
var deferral = e.SuspendingOperation.GetDeferral();
|
||||||
|
//TODO: Save application state and stop any background activity
|
||||||
|
deferral.Complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,89 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace RootAccessTestUWP
|
||||||
|
{
|
||||||
|
public static class Core
|
||||||
|
{
|
||||||
|
[DllImport("KERNELBASE.DLL", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
private static extern int RegQueryValueEx(UIntPtr hKey, string lpValueName, int lpReserved, out Core.RegistryValueKind lpType, IntPtr lpData, ref int lpcbData);
|
||||||
|
|
||||||
|
[DllImport("KERNELBASE.DLL", CharSet = CharSet.Unicode)]
|
||||||
|
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
|
||||||
|
|
||||||
|
[DllImport("KERNELBASE.DLL", SetLastError = true)]
|
||||||
|
private static extern int RegCloseKey(UIntPtr hKey);
|
||||||
|
|
||||||
|
internal static string RegReadStringValue(UIntPtr rootKey, string keyPath, string valueName)
|
||||||
|
{
|
||||||
|
UIntPtr hKey;
|
||||||
|
int num = Core.RegOpenKeyEx(rootKey, keyPath, 0, Core.KEY_READ, out hKey);
|
||||||
|
if (num != 0)
|
||||||
|
{
|
||||||
|
throw new COMException("Failed to open registry key", num);
|
||||||
|
}
|
||||||
|
int cb = 1024;
|
||||||
|
IntPtr intPtr = Marshal.AllocHGlobal(cb);
|
||||||
|
Core.RegistryValueKind registryValueKind;
|
||||||
|
num = Core.RegQueryValueEx(hKey, valueName, 0, out registryValueKind, intPtr, ref cb);
|
||||||
|
if (num != 0)
|
||||||
|
{
|
||||||
|
throw new COMException("Failed to read registry value", num);
|
||||||
|
}
|
||||||
|
if (registryValueKind != Core.RegistryValueKind.String)
|
||||||
|
{
|
||||||
|
throw new Exception("Wrong registry value type");
|
||||||
|
}
|
||||||
|
string result = Marshal.PtrToStringUni(intPtr);
|
||||||
|
Core.RegCloseKey(hKey);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static uint RegReadDwordValue(UIntPtr rootKey, string keyPath, string valueName)
|
||||||
|
{
|
||||||
|
UIntPtr hKey;
|
||||||
|
int num = Core.RegOpenKeyEx(rootKey, keyPath, 0, Core.KEY_READ, out hKey);
|
||||||
|
if (num != 0)
|
||||||
|
{
|
||||||
|
throw new COMException("Failed to open registry key", num);
|
||||||
|
}
|
||||||
|
int cb = 1024;
|
||||||
|
IntPtr intPtr = Marshal.AllocHGlobal(cb);
|
||||||
|
Core.RegistryValueKind registryValueKind;
|
||||||
|
num = Core.RegQueryValueEx(hKey, valueName, 0, out registryValueKind, intPtr, ref cb);
|
||||||
|
if (num != 0)
|
||||||
|
{
|
||||||
|
throw new COMException("Failed to read registry value", num);
|
||||||
|
}
|
||||||
|
if (registryValueKind != Core.RegistryValueKind.DWord)
|
||||||
|
{
|
||||||
|
throw new Exception("Wrong registry value type");
|
||||||
|
}
|
||||||
|
uint result = (uint)Marshal.ReadInt32(intPtr);
|
||||||
|
Core.RegCloseKey(hKey);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)2147483648U;
|
||||||
|
|
||||||
|
public static UIntPtr HKEY_CURRENT_USER = (UIntPtr)2147483649U;
|
||||||
|
|
||||||
|
public static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)2147483650U;
|
||||||
|
|
||||||
|
public static UIntPtr HKEY_USERS = (UIntPtr)2147483651U;
|
||||||
|
|
||||||
|
private static int KEY_READ = 131097;
|
||||||
|
|
||||||
|
public enum RegistryValueKind
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
String,
|
||||||
|
ExpandString,
|
||||||
|
Binary,
|
||||||
|
DWord,
|
||||||
|
MultiString = 7,
|
||||||
|
QWord = 11,
|
||||||
|
None = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<Page
|
||||||
|
x:Class="RootAccessTestUWP.MainPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:RootAccessTestUWP"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
<TextBlock x:Name="TextBlock"
|
||||||
|
Margin="10"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Text=""
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
FontFamily="Courier New" />
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
|
using Windows.UI.Xaml.Controls;
|
||||||
|
using Windows.UI.Xaml.Controls.Primitives;
|
||||||
|
using Windows.UI.Xaml.Data;
|
||||||
|
using Windows.UI.Xaml.Input;
|
||||||
|
using Windows.UI.Xaml.Media;
|
||||||
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
|
||||||
|
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||||
|
|
||||||
|
namespace RootAccessTestUWP
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class MainPage : Page
|
||||||
|
{
|
||||||
|
public MainPage()
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
|
||||||
|
TextBlock.Text = "Reading: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\PhoneProvisioner\\ColdBootDone" + Environment.NewLine + Environment.NewLine;
|
||||||
|
|
||||||
|
bool flag = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Core.RegReadDwordValue(Core.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\PhoneProvisioner", "ColdBootDone");
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
TextBlock.Text = string.Concat(new string[]
|
||||||
|
{
|
||||||
|
TextBlock.Text,
|
||||||
|
"Success!",
|
||||||
|
Environment.NewLine,
|
||||||
|
Environment.NewLine,
|
||||||
|
"Root Access: Enabled"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextBlock.Text = string.Concat(new string[]
|
||||||
|
{
|
||||||
|
TextBlock.Text,
|
||||||
|
"Failed!",
|
||||||
|
Environment.NewLine,
|
||||||
|
Environment.NewLine,
|
||||||
|
"Root Access: Disabled"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<Package
|
||||||
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||||
|
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||||
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||||
|
IgnorableNamespaces="uap mp">
|
||||||
|
|
||||||
|
<Identity
|
||||||
|
Name="66bf96f4-f5ba-41f1-8ceb-ac4e9065ac52"
|
||||||
|
Publisher="CN=Rene"
|
||||||
|
Version="1.0.0.0" />
|
||||||
|
|
||||||
|
<mp:PhoneIdentity PhoneProductId="66bf96f4-f5ba-41f1-8ceb-ac4e9065ac52" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
|
<Properties>
|
||||||
|
<DisplayName>RootAccessTestUWP</DisplayName>
|
||||||
|
<PublisherDisplayName>Rene</PublisherDisplayName>
|
||||||
|
<Logo>Assets\StoreLogo.png</Logo>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Dependencies>
|
||||||
|
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||||
|
</Dependencies>
|
||||||
|
|
||||||
|
<Resources>
|
||||||
|
<Resource Language="x-generate"/>
|
||||||
|
</Resources>
|
||||||
|
|
||||||
|
<Applications>
|
||||||
|
<Application Id="App"
|
||||||
|
Executable="$targetnametoken$.exe"
|
||||||
|
EntryPoint="RootAccessTestUWP.App">
|
||||||
|
<uap:VisualElements
|
||||||
|
DisplayName="RootAccessTestUWP"
|
||||||
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||||
|
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||||
|
Description="RootAccessTestUWP"
|
||||||
|
BackgroundColor="transparent">
|
||||||
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||||
|
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||||
|
</uap:VisualElements>
|
||||||
|
</Application>
|
||||||
|
</Applications>
|
||||||
|
|
||||||
|
<Capabilities>
|
||||||
|
<Capability Name="internetClient" />
|
||||||
|
</Capabilities>
|
||||||
|
</Package>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("RootAccessTestUWP")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("RootAccessTestUWP")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<!--
|
||||||
|
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||||
|
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||||
|
optimizer.
|
||||||
|
|
||||||
|
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919
|
||||||
|
|
||||||
|
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||||
|
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||||
|
|
||||||
|
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||||
|
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||||
|
|
||||||
|
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||||
|
<Namespace Name="DataClasses.ViewModels" Serialize="All" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||||
|
<Application>
|
||||||
|
<!--
|
||||||
|
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||||
|
the application package. The asterisks are not wildcards.
|
||||||
|
-->
|
||||||
|
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Add your application specific runtime directives here. -->
|
||||||
|
|
||||||
|
|
||||||
|
</Application>
|
||||||
|
</Directives>
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||||
|
<ProjectGuid>{8B6AADBB-C750-492E-AF60-82F6323401CC}</ProjectGuid>
|
||||||
|
<OutputType>AppContainerExe</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>RootAccessTestUWP</RootNamespace>
|
||||||
|
<AssemblyName>RootAccessTestUWP</AssemblyName>
|
||||||
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.22000.0</TargetPlatformVersion>
|
||||||
|
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||||
|
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
|
||||||
|
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||||
|
<OutputPath>bin\x86\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||||
|
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>ARM</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\ARM64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'">
|
||||||
|
<OutputPath>bin\ARM64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>ARM64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<NoWarn>;2008</NoWarn>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="App.xaml.cs">
|
||||||
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Core.cs" />
|
||||||
|
<Compile Include="MainPage.xaml.cs">
|
||||||
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AppxManifest Include="Package.appxmanifest">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</AppxManifest>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Properties\Default.rd.xml" />
|
||||||
|
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
|
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||||
|
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||||
|
<Content Include="Assets\StoreLogo.png" />
|
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ApplicationDefinition Include="App.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</ApplicationDefinition>
|
||||||
|
<Page Include="MainPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||||
|
<Version>6.2.13</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
@@ -1518,10 +1518,10 @@ namespace SevenZip.Compression.LZMA
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static readonly string[] kMatchFinderIDs =
|
private static readonly string[] kMatchFinderIDs =
|
||||||
{
|
[
|
||||||
"BT2",
|
"BT2",
|
||||||
"BT4",
|
"BT4",
|
||||||
};
|
];
|
||||||
|
|
||||||
private static int FindMatchFinder(string s)
|
private static int FindMatchFinder(string s)
|
||||||
{
|
{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -83,9 +83,13 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
FFU FFU = null;
|
FFU FFU = null;
|
||||||
PhoneNotifierViewModel Notifier;
|
PhoneNotifierViewModel Notifier;
|
||||||
NokiaFlashModel FlashModel;
|
LumiaFlashAppModel FlashModel;
|
||||||
|
LumiaBootManagerAppModel BootMgrModel;
|
||||||
|
LumiaPhoneInfoAppModel PhoneInfoModel;
|
||||||
NokiaPhoneModel NormalModel;
|
NokiaPhoneModel NormalModel;
|
||||||
PhoneInfo Info;
|
LumiaFlashAppPhoneInfo FlashInfo;
|
||||||
|
LumiaPhoneInfoAppPhoneInfo PhoneInfo;
|
||||||
|
LumiaBootManagerPhoneInfo BootManagerInfo;
|
||||||
string ProductType;
|
string ProductType;
|
||||||
string ProductCode;
|
string ProductCode;
|
||||||
string OperatorCode;
|
string OperatorCode;
|
||||||
@@ -114,7 +118,7 @@ namespace WPinternals
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (args[1].ToLower().TrimStart(new char[] { '-', '/' }))
|
switch (args[1].ToLower().TrimStart(['-', '/']))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
case "test":
|
case "test":
|
||||||
@@ -182,23 +186,14 @@ namespace WPinternals
|
|||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
|
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader); // This also works for Bootloader Spec A
|
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader); // This also works for Bootloader Spec A
|
||||||
|
|
||||||
GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException
|
GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
|
||||||
foreach (Partition Partition in GPT.Partitions)
|
foreach (Partition Partition in GPT.Partitions)
|
||||||
{
|
{
|
||||||
LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly);
|
LogFile.Log(Partition.Name.PadRight(20) + "0x" + Partition.FirstSector.ToString("X8") + " - 0x" + Partition.LastSector.ToString("X8") + " " + Partition.Volume, LogType.ConsoleOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FlashModel.ReadPhoneInfo(false).FlashAppProtocolVersionMajor >= 2)
|
|
||||||
{
|
|
||||||
FlashModel.SwitchToFlashAppContext();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
|
||||||
}
|
|
||||||
|
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
}
|
}
|
||||||
catch (Exception Ex)
|
catch (Exception Ex)
|
||||||
@@ -221,11 +216,14 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
|
||||||
GPT GPT = FlashModel.ReadGPT(); // May throw NotSupportedException
|
GPT GPT = BootMgrModel.ReadGPT(); // May throw NotSupportedException
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(args[2]));
|
string DirPath = Path.GetDirectoryName(args[2]);
|
||||||
|
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(DirPath);
|
||||||
|
}
|
||||||
GPT.WritePartitions(args[2]);
|
GPT.WritePartitions(args[2]);
|
||||||
FlashModel.SwitchToFlashAppContext();
|
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
}
|
}
|
||||||
catch (Exception Ex)
|
catch (Exception Ex)
|
||||||
@@ -237,6 +235,35 @@ namespace WPinternals
|
|||||||
LogFile.EndAction("BackupGPT");
|
LogFile.EndAction("BackupGPT");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "convertgpt":
|
||||||
|
if (args.Length < 4)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Wrong number of arguments. Usage: WPinternals.exe -ConvertGPT <Path to GPT-file> <Path to xml-file>");
|
||||||
|
}
|
||||||
|
|
||||||
|
LogFile.BeginAction("ConvertGPT");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var stream = File.OpenRead(args[2]);
|
||||||
|
byte[] GPTBuffer = new byte[34 * 0x200];
|
||||||
|
stream.Read(GPTBuffer, 0, 34 * 0x200);
|
||||||
|
GPT GPT = new(GPTBuffer);// May throw NotSupportedException
|
||||||
|
string DirPath = Path.GetDirectoryName(args[3]);
|
||||||
|
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(DirPath);
|
||||||
|
}
|
||||||
|
GPT.WritePartitions(args[3]);
|
||||||
|
}
|
||||||
|
catch (Exception Ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(Ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
LogFile.EndAction("ConvertGPT");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "restoregpt":
|
case "restoregpt":
|
||||||
if (args.Length < 3)
|
if (args.Length < 3)
|
||||||
{
|
{
|
||||||
@@ -248,14 +275,13 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
BootMgrModel = (LumiaBootManagerAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Bootloader);
|
||||||
byte[] GptChunk = LumiaUnlockBootloaderViewModel.GetGptChunk(FlashModel, 0x20000);
|
byte[] GptChunk = BootMgrModel.GetGptChunk(0x20000);
|
||||||
GPT GPT = new(GptChunk);
|
GPT GPT = new(GptChunk);
|
||||||
string Xml = File.ReadAllText(args[2]);
|
string Xml = File.ReadAllText(args[2]);
|
||||||
GPT.MergePartitions(Xml, false);
|
GPT.MergePartitions(Xml, false);
|
||||||
GPT.Rebuild();
|
GPT.Rebuild();
|
||||||
await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(Notifier, null, false, false, 0, GptChunk, true, true);
|
await LumiaV2UnlockBootViewModel.LumiaV2CustomFlash(Notifier, null, false, false, 0, GptChunk, true, true);
|
||||||
FlashModel.SwitchToFlashAppContext();
|
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
}
|
}
|
||||||
catch (Exception Ex)
|
catch (Exception Ex)
|
||||||
@@ -285,7 +311,10 @@ namespace WPinternals
|
|||||||
s = new FileStream(args[3], FileMode.Open, FileAccess.Read);
|
s = new FileStream(args[3], FileMode.Open, FileAccess.Read);
|
||||||
Archive = new ZipArchive(s);
|
Archive = new ZipArchive(s);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
if (Archive == null)
|
if (Archive == null)
|
||||||
{
|
{
|
||||||
@@ -393,7 +422,11 @@ namespace WPinternals
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
string EfiPath = Path.Combine(args[3], Name);
|
string EfiPath = Path.Combine(args[3], Name);
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(EfiPath));
|
string DirPath = Path.GetDirectoryName(EfiPath);
|
||||||
|
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(DirPath);
|
||||||
|
}
|
||||||
File.WriteAllBytes(EfiPath, EfiBinary);
|
File.WriteAllBytes(EfiPath, EfiBinary);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -512,9 +545,9 @@ namespace WPinternals
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
|
|
||||||
FFU ProfileFFU = null;
|
FFU ProfileFFU = null;
|
||||||
FFU CurrentFFU;
|
FFU CurrentFFU;
|
||||||
@@ -527,7 +560,7 @@ namespace WPinternals
|
|||||||
string PlatformID = CurrentFFU.PlatformID;
|
string PlatformID = CurrentFFU.PlatformID;
|
||||||
|
|
||||||
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
||||||
if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
if (FlashInfo.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
ProfileFFU = CurrentFFU;
|
ProfileFFU = CurrentFFU;
|
||||||
}
|
}
|
||||||
@@ -536,7 +569,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (ProfileFFU == null)
|
if (ProfileFFU == null)
|
||||||
{
|
{
|
||||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => FlashInfo.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
||||||
ProfileFFU = FFUs.Count > 0
|
ProfileFFU = FFUs.Count > 0
|
||||||
? new FFU(FFUs[0].Path)
|
? new FFU(FFUs[0].Path)
|
||||||
: 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.");
|
: 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.");
|
||||||
@@ -661,9 +694,9 @@ namespace WPinternals
|
|||||||
LogFile.Log("Command: Show phone info", LogType.FileAndConsole);
|
LogFile.Log("Command: Show phone info", LogType.FileAndConsole);
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
break;
|
break;
|
||||||
case "unlockbootloader":
|
case "unlockbootloader":
|
||||||
@@ -673,9 +706,9 @@ namespace WPinternals
|
|||||||
LogFile.Log("Command: Unlock Bootloader", LogType.FileAndConsole);
|
LogFile.Log("Command: Unlock Bootloader", LogType.FileAndConsole);
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
|
|
||||||
FFU ProfileFFU = null;
|
FFU ProfileFFU = null;
|
||||||
FFU SupportedFFU = null;
|
FFU SupportedFFU = null;
|
||||||
@@ -689,7 +722,7 @@ namespace WPinternals
|
|||||||
string PlatformID = CurrentFFU.PlatformID;
|
string PlatformID = CurrentFFU.PlatformID;
|
||||||
|
|
||||||
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
// Check if the current FFU matches the connected phone, so that the FFU can be used for profiling.
|
||||||
if (Info.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
if (FlashInfo.PlatformID.StartsWith(PlatformID, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
ProfileFFU = CurrentFFU;
|
ProfileFFU = CurrentFFU;
|
||||||
}
|
}
|
||||||
@@ -704,7 +737,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (ProfileFFU == null)
|
if (ProfileFFU == null)
|
||||||
{
|
{
|
||||||
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => Info.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
List<FFUEntry> FFUs = App.Config.FFURepository.Where(e => FlashInfo.PlatformID.StartsWith(e.PlatformID, StringComparison.OrdinalIgnoreCase) && e.Exists()).ToList();
|
||||||
ProfileFFU = FFUs.Count > 0
|
ProfileFFU = FFUs.Count > 0
|
||||||
? new FFU(FFUs[0].Path)
|
? new FFU(FFUs[0].Path)
|
||||||
: 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.");
|
: 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.");
|
||||||
@@ -746,9 +779,9 @@ namespace WPinternals
|
|||||||
LogFile.Log("Custom ROM: " + CustomRomPath, LogType.FileAndConsole);
|
LogFile.Log("Custom ROM: " + CustomRomPath, LogType.FileAndConsole);
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole);
|
LogFile.Log("Preparing to flash Custom ROM", LogType.FileAndConsole);
|
||||||
await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(Notifier, CustomRomPath);
|
await LumiaV2UnlockBootViewModel.LumiaV2FlashArchive(Notifier, CustomRomPath);
|
||||||
LogFile.Log("Custom ROM flashed successfully", LogType.FileAndConsole);
|
LogFile.Log("Custom ROM flashed successfully", LogType.FileAndConsole);
|
||||||
@@ -777,11 +810,11 @@ namespace WPinternals
|
|||||||
LogFile.Log("FFU file: " + FFUPath, LogType.FileAndConsole);
|
LogFile.Log("FFU file: " + FFUPath, LogType.FileAndConsole);
|
||||||
Notifier = new PhoneNotifierViewModel();
|
Notifier = new PhoneNotifierViewModel();
|
||||||
UIContext.Send(s => Notifier.Start(), null);
|
UIContext.Send(s => Notifier.Start(), null);
|
||||||
FlashModel = (NokiaFlashModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
FlashModel = (LumiaFlashAppModel)await SwitchModeViewModel.SwitchTo(Notifier, PhoneInterfaces.Lumia_Flash);
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
Info.Log(LogType.ConsoleOnly);
|
FlashInfo.Log(LogType.ConsoleOnly);
|
||||||
LogFile.Log("Flashing FFU...", LogType.FileAndConsole);
|
LogFile.Log("Flashing FFU...", LogType.FileAndConsole);
|
||||||
await Task.Run(() => FlashModel.FlashFFU(new FFU(FFUPath), true, (byte)(!Info.IsBootloaderSecure ? FlashOptions.SkipSignatureCheck : 0)));
|
await Task.Run(() => FlashModel.FlashFFU(new FFU(FFUPath), true, (byte)(!FlashInfo.IsBootloaderSecure ? FlashOptions.SkipSignatureCheck : 0)));
|
||||||
LogFile.Log("FFU flashed successfully", LogType.FileAndConsole);
|
LogFile.Log("FFU flashed successfully", LogType.FileAndConsole);
|
||||||
Notifier.Stop();
|
Notifier.Stop();
|
||||||
}
|
}
|
||||||
@@ -1243,11 +1276,55 @@ namespace WPinternals
|
|||||||
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||||
}
|
}
|
||||||
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash))
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
FlashModel = (NokiaFlashModel)Notifier.CurrentModel;
|
(Notifier.CurrentModel as LumiaBootManagerAppModel).SwitchToPhoneInfoAppContext();
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
|
||||||
ProductCode = Info.ProductCode;
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
|
}
|
||||||
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
|
}
|
||||||
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
|
{
|
||||||
|
bool ModernFlashApp = ((LumiaFlashAppModel)Notifier.CurrentModel).ReadPhoneInfo().FlashAppProtocolVersionMajor >= 2;
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((LumiaFlashAppModel)Notifier.CurrentModel).SwitchToPhoneInfoAppContextLegacy();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
await Notifier.WaitForArrival();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Notifier.CurrentInterface != PhoneInterfaces.Lumia_PhoneInfo)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Unexpected Mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
PhoneInfoModel = (LumiaPhoneInfoAppModel)Notifier.CurrentModel;
|
||||||
|
PhoneInfo = PhoneInfoModel.ReadPhoneInfo();
|
||||||
|
ProductCode = PhoneInfo.ProductCode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1408,11 +1485,19 @@ namespace WPinternals
|
|||||||
ProductType = ProductType.Substring(0, ProductType.IndexOf('_'));
|
ProductType = ProductType.Substring(0, ProductType.IndexOf('_'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash))
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
FlashModel = (NokiaFlashModel)Notifier.CurrentModel;
|
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
BootManagerInfo = BootMgrModel.ReadPhoneInfo();
|
||||||
ProductType = Info.Type;
|
//ProductType = BootManagerInfo.Type; // TODO: FIXME
|
||||||
|
ProductType = "";
|
||||||
|
}
|
||||||
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
|
{
|
||||||
|
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
|
//ProductType = FlashInfo.Type; // TODO: FIXME
|
||||||
|
ProductType = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1519,11 +1604,19 @@ namespace WPinternals
|
|||||||
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
NormalModel = (NokiaPhoneModel)Notifier.CurrentModel;
|
||||||
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
ProductCode = NormalModel.ExecuteJsonMethodAsString("ReadProductCode", "ProductCode");
|
||||||
}
|
}
|
||||||
else if ((Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader) || (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash))
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Bootloader)
|
||||||
{
|
{
|
||||||
FlashModel = (NokiaFlashModel)Notifier.CurrentModel;
|
BootMgrModel = (LumiaBootManagerAppModel)Notifier.CurrentModel;
|
||||||
Info = FlashModel.ReadPhoneInfo();
|
BootManagerInfo = BootMgrModel.ReadPhoneInfo();
|
||||||
ProductCode = Info.ProductCode;
|
//ProductCode = BootManagerInfo.ProductCode; // TODO: FIXME
|
||||||
|
ProductCode = "";
|
||||||
|
}
|
||||||
|
else if (Notifier.CurrentInterface == PhoneInterfaces.Lumia_Flash)
|
||||||
|
{
|
||||||
|
FlashModel = (LumiaFlashAppModel)Notifier.CurrentModel;
|
||||||
|
FlashInfo = FlashModel.ReadPhoneInfo();
|
||||||
|
//ProductCode = FlashInfo.ProductCode; // TODO: FIXME
|
||||||
|
ProductCode = "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1968,6 +2061,7 @@ namespace WPinternals
|
|||||||
LogFile.Log("WPinternals -ClearNV", LogType.ConsoleOnly);
|
LogFile.Log("WPinternals -ClearNV", LogType.ConsoleOnly);
|
||||||
LogFile.Log("WPinternals -ReadGPT", LogType.ConsoleOnly);
|
LogFile.Log("WPinternals -ReadGPT", LogType.ConsoleOnly);
|
||||||
LogFile.Log("WPinternals -BackupGPT <Path to xml-file>", LogType.ConsoleOnly);
|
LogFile.Log("WPinternals -BackupGPT <Path to xml-file>", LogType.ConsoleOnly);
|
||||||
|
LogFile.Log("WPinternals -ConvertGPT <Path to GPT-file> <Path to xml-file>", LogType.ConsoleOnly);
|
||||||
LogFile.Log("WPinternals -RestoreGPT <Path to xml-file>", LogType.ConsoleOnly);
|
LogFile.Log("WPinternals -RestoreGPT <Path to xml-file>", LogType.ConsoleOnly);
|
||||||
LogFile.Log("WPinternals -MergeGPT <Path to input-xml-file> <Path to input-xml-file>", LogType.ConsoleOnly);
|
LogFile.Log("WPinternals -MergeGPT <Path to input-xml-file> <Path to input-xml-file>", LogType.ConsoleOnly);
|
||||||
LogFile.Log(" <Optional: Path to output-xml-file>", LogType.ConsoleOnly);
|
LogFile.Log(" <Optional: Path to output-xml-file>", LogType.ConsoleOnly);
|
||||||
@@ -68,7 +68,7 @@ namespace DiscUtils.Internal
|
|||||||
result.Add(func(sVal));
|
result.Add(func(sVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ToArray();
|
return [.. result];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -31,15 +31,15 @@ namespace DiscUtils.Fat
|
|||||||
private const byte SpaceByte = 0x20;
|
private const byte SpaceByte = 0x20;
|
||||||
|
|
||||||
public static readonly FileName SelfEntryName =
|
public static readonly FileName SelfEntryName =
|
||||||
new(new byte[] { 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 0);
|
new([0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20], 0);
|
||||||
|
|
||||||
public static readonly FileName ParentEntryName =
|
public static readonly FileName ParentEntryName =
|
||||||
new(new byte[] { 0x2E, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 0);
|
new([0x2E, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20], 0);
|
||||||
|
|
||||||
public static readonly FileName Null =
|
public static readonly FileName Null =
|
||||||
new(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0);
|
new([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], 0);
|
||||||
|
|
||||||
private static readonly byte[] InvalidBytes = { 0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C };
|
private static readonly byte[] InvalidBytes = [0x22, 0x2A, 0x2B, 0x2C, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x5B, 0x5C, 0x5D, 0x7C];
|
||||||
|
|
||||||
private readonly byte[] _raw;
|
private readonly byte[] _raw;
|
||||||
|
|
||||||
@@ -33,10 +33,10 @@ namespace DiscUtils.Fat
|
|||||||
{
|
{
|
||||||
if (FatFileSystem.Detect(stream))
|
if (FatFileSystem.Detect(stream))
|
||||||
{
|
{
|
||||||
return new FileSystemInfo[] { new VfsFileSystemInfo("FAT", "Microsoft FAT", Open) };
|
return [new VfsFileSystemInfo("FAT", "Microsoft FAT", Open)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return System.Array.Empty<FileSystemInfo>();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiscFileSystem Open(Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters)
|
private DiscFileSystem Open(Stream stream, VolumeInfo volumeInfo, FileSystemParameters parameters)
|
||||||
@@ -80,22 +80,22 @@ namespace DiscUtils.Fat
|
|||||||
{
|
{
|
||||||
// see http://home.teleport.com/~brainy/lfn.htm
|
// see http://home.teleport.com/~brainy/lfn.htm
|
||||||
// NOTE: we assume ordinals are ok here.
|
// NOTE: we assume ordinals are ok here.
|
||||||
char[] chars = new char[13];
|
char[] chars =
|
||||||
chars[0] = (char)((256 * buffer[2]) + buffer[1]);
|
[
|
||||||
chars[1] = (char)((256 * buffer[4]) + buffer[3]);
|
(char)((256 * buffer[2]) + buffer[1]),
|
||||||
chars[2] = (char)((256 * buffer[6]) + buffer[5]);
|
(char)((256 * buffer[4]) + buffer[3]),
|
||||||
chars[3] = (char)((256 * buffer[8]) + buffer[7]);
|
(char)((256 * buffer[6]) + buffer[5]),
|
||||||
chars[4] = (char)((256 * buffer[10]) + buffer[9]);
|
(char)((256 * buffer[8]) + buffer[7]),
|
||||||
|
(char)((256 * buffer[10]) + buffer[9]),
|
||||||
chars[5] = (char)((256 * buffer[15]) + buffer[14]);
|
(char)((256 * buffer[15]) + buffer[14]),
|
||||||
chars[6] = (char)((256 * buffer[17]) + buffer[16]);
|
(char)((256 * buffer[17]) + buffer[16]),
|
||||||
chars[7] = (char)((256 * buffer[19]) + buffer[18]);
|
(char)((256 * buffer[19]) + buffer[18]),
|
||||||
chars[8] = (char)((256 * buffer[21]) + buffer[20]);
|
(char)((256 * buffer[21]) + buffer[20]),
|
||||||
chars[9] = (char)((256 * buffer[23]) + buffer[22]);
|
(char)((256 * buffer[23]) + buffer[22]),
|
||||||
chars[10] = (char)((256 * buffer[25]) + buffer[24]);
|
(char)((256 * buffer[25]) + buffer[24]),
|
||||||
|
(char)((256 * buffer[29]) + buffer[28]),
|
||||||
chars[11] = (char)((256 * buffer[29]) + buffer[28]);
|
(char)((256 * buffer[31]) + buffer[30]),
|
||||||
chars[12] = (char)((256 * buffer[31]) + buffer[30]);
|
];
|
||||||
string chunk = new(chars);
|
string chunk = new(chars);
|
||||||
int zero = chunk.IndexOf('\0');
|
int zero = chunk.IndexOf('\0');
|
||||||
return zero >= 0 ? chunk.Substring(0, zero) : chunk;
|
return zero >= 0 ? chunk.Substring(0, zero) : chunk;
|
||||||
@@ -201,7 +201,7 @@ namespace DiscUtils.Fat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dirs.ToArray();
|
return [.. dirs];
|
||||||
}
|
}
|
||||||
|
|
||||||
public DirectoryEntry[] GetFiles()
|
public DirectoryEntry[] GetFiles()
|
||||||
@@ -215,7 +215,7 @@ namespace DiscUtils.Fat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return files.ToArray();
|
return [.. files];
|
||||||
}
|
}
|
||||||
|
|
||||||
public DirectoryEntry GetEntry(long id)
|
public DirectoryEntry GetEntry(long id)
|
||||||
@@ -1258,7 +1258,7 @@ namespace DiscUtils.Fat
|
|||||||
dirs.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
dirs.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return dirs.ToArray();
|
return [.. dirs];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1275,7 +1275,7 @@ namespace DiscUtils.Fat
|
|||||||
|
|
||||||
List<string> dirs = new();
|
List<string> dirs = new();
|
||||||
DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false);
|
DoSearch(dirs, path, re, searchOption == SearchOption.AllDirectories, true, false);
|
||||||
return dirs.ToArray();
|
return [.. dirs];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1294,7 +1294,7 @@ namespace DiscUtils.Fat
|
|||||||
files.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
files.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return files.ToArray();
|
return [.. files];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1311,7 +1311,7 @@ namespace DiscUtils.Fat
|
|||||||
|
|
||||||
List<string> results = new();
|
List<string> results = new();
|
||||||
DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true);
|
DoSearch(results, path, re, searchOption == SearchOption.AllDirectories, false, true);
|
||||||
return results.ToArray();
|
return [.. results];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1330,7 +1330,7 @@ namespace DiscUtils.Fat
|
|||||||
result.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
result.Add(Utilities.CombinePaths(path, dirEntry.Name.GetDisplayName(FatOptions.FileNameEncoding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ToArray();
|
return [.. result];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1356,7 +1356,7 @@ namespace DiscUtils.Fat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.ToArray();
|
return [.. result];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1915,9 +1915,7 @@ namespace DiscUtils.Fat
|
|||||||
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, "The directory '{0}' was not found", path));
|
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, "The directory '{0}' was not found", path));
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryEntry[] entries = dir.Entries;
|
foreach (DirectoryEntry de in dir.Entries)
|
||||||
|
|
||||||
foreach (DirectoryEntry de in entries)
|
|
||||||
{
|
{
|
||||||
bool isDir = (de.Attributes & FatAttributes.Directory) != 0;
|
bool isDir = (de.Attributes & FatAttributes.Directory) != 0;
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -316,13 +316,19 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
filename = System.IO.Path.GetFileName(Text);
|
filename = System.IO.Path.GetFileName(Text);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
string directory = "";
|
string directory = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
directory = System.IO.Path.GetDirectoryName(Text);
|
directory = System.IO.Path.GetDirectoryName(Text);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
FormattedText formatted;
|
FormattedText formatted;
|
||||||
bool widthOK = false;
|
bool widthOK = false;
|
||||||
bool changedWidth = false;
|
bool changedWidth = false;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -28,6 +28,7 @@ using System.Globalization;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -658,7 +659,7 @@ namespace WPinternals
|
|||||||
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString(), LogType.FileAndConsole);
|
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString(), LogType.FileAndConsole);
|
||||||
Log("Copyright Heathcliff74 / wpinternals.net", LogType.FileAndConsole);
|
Log("Copyright Heathcliff74", LogType.FileAndConsole);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void BeginAction(string Action)
|
internal static void BeginAction(string Action)
|
||||||
@@ -673,7 +674,7 @@ namespace WPinternals
|
|||||||
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
Assembly.GetExecutingAssembly().GetName().Version.Minor.ToString() + "." +
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
Assembly.GetExecutingAssembly().GetName().Version.Build.ToString() + "." +
|
||||||
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString());
|
Assembly.GetExecutingAssembly().GetName().Version.Revision.ToString());
|
||||||
LogBuilder.AppendLine("Copyright Heathcliff74 / wpinternals.net");
|
LogBuilder.AppendLine("Copyright Heathcliff74");
|
||||||
LogBuilder.AppendLine("Action: " + Action);
|
LogBuilder.AppendLine("Action: " + Action);
|
||||||
if (App.Config.RegistrationName != null)
|
if (App.Config.RegistrationName != null)
|
||||||
LogBuilder.AppendLine("Name: " + App.Config.RegistrationName);
|
LogBuilder.AppendLine("Name: " + App.Config.RegistrationName);
|
||||||
@@ -924,7 +925,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
if (proxy?.CheckAccess() == false)
|
if (proxy?.CheckAccess() == false)
|
||||||
{
|
{
|
||||||
proxy.BeginInvoke(new Action<object, EventHandler>(CallHandler), new object[] { sender, eventHandler });
|
proxy.BeginInvoke(new Action<object, EventHandler>(CallHandler), [sender, eventHandler]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1890,7 +1891,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
internal static Version GetFileVersion(byte[] PEfile)
|
internal static Version GetFileVersion(byte[] PEfile)
|
||||||
{
|
{
|
||||||
byte[] version = GetResource(PEfile, new int[] { (int)ResourceType.RT_VERSION, 1, 1033 });
|
byte[] version = GetResource(PEfile, [(int)ResourceType.RT_VERSION, 1, 1033]);
|
||||||
|
|
||||||
// RT_VERSION format:
|
// RT_VERSION format:
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
||||||
@@ -1906,7 +1907,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
internal static Version GetProductVersion(byte[] PEfile)
|
internal static Version GetProductVersion(byte[] PEfile)
|
||||||
{
|
{
|
||||||
byte[] version = GetResource(PEfile, new int[] { (int)ResourceType.RT_VERSION, 1, 1033 });
|
byte[] version = GetResource(PEfile, [(int)ResourceType.RT_VERSION, 1, 1033]);
|
||||||
|
|
||||||
// RT_VERSION format:
|
// RT_VERSION format:
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx
|
||||||
@@ -1940,7 +1941,8 @@ namespace WPinternals
|
|||||||
|
|
||||||
internal static void Upload(string FileName, Stream FileStream)
|
internal static void Upload(string FileName, Stream FileStream)
|
||||||
{
|
{
|
||||||
Upload(new Uri(@"https://www.wpinternals.net/upload.php", UriKind.Absolute), "uploadedfile", FileName, FileStream);
|
//TODO: Fix
|
||||||
|
//Upload(new Uri(@"https://www.wpinternals.net/upload.php", UriKind.Absolute), "uploadedfile", FileName, FileStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Upload(Uri Address, string InputName, string FileName, Stream FileStream)
|
private static void Upload(Uri Address, string InputName, string FileName, Stream FileStream)
|
||||||
@@ -2221,8 +2223,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double width = Math.Max(allowedSpace * (Percentage / totalPercentage), 0);
|
_element.Width = (double)Math.Max(allowedSpace * (Percentage / totalPercentage), 0);
|
||||||
_element.Width = width;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -332,7 +332,7 @@ namespace WPinternals
|
|||||||
return (UInt16)(0x10000 - Checksum);
|
return (UInt16)(0x10000 - Checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly UInt32[] CRC32Table = new UInt32[] {
|
private static readonly UInt32[] CRC32Table = [
|
||||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
|
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
|
||||||
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
|
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
|
||||||
@@ -376,7 +376,7 @@ namespace WPinternals
|
|||||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
|
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
|
||||||
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||||
};
|
];
|
||||||
|
|
||||||
internal static UInt32 CRC32(byte[] Input, UInt32 Offset, UInt32 Length)
|
internal static UInt32 CRC32(byte[] Input, UInt32 Offset, UInt32 Length)
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -84,7 +84,7 @@ namespace WPinternals
|
|||||||
// Read Store Header
|
// Read Store Header
|
||||||
byte[] ShortStoreHeader = new byte[248];
|
byte[] ShortStoreHeader = new byte[248];
|
||||||
FFUFile.Read(ShortStoreHeader, 0, 248);
|
FFUFile.Read(ShortStoreHeader, 0, 248);
|
||||||
PlatformID = ByteOperations.ReadAsciiString(ShortStoreHeader, 0x0C, 192).TrimEnd(new char[] { (char)0, ' ' });
|
PlatformID = ByteOperations.ReadAsciiString(ShortStoreHeader, 0x0C, 192).TrimEnd([(char)0, ' ']);
|
||||||
int WriteDescriptorCount = ByteOperations.ReadInt32(ShortStoreHeader, 208);
|
int WriteDescriptorCount = ByteOperations.ReadInt32(ShortStoreHeader, 208);
|
||||||
UInt32 WriteDescriptorLength = ByteOperations.ReadUInt32(ShortStoreHeader, 212);
|
UInt32 WriteDescriptorLength = ByteOperations.ReadUInt32(ShortStoreHeader, 212);
|
||||||
UInt32 ValidateDescriptorLength = ByteOperations.ReadUInt32(ShortStoreHeader, 220);
|
UInt32 ValidateDescriptorLength = ByteOperations.ReadUInt32(ShortStoreHeader, 220);
|
||||||
@@ -455,8 +455,8 @@ namespace WPinternals
|
|||||||
if (Offset != null)
|
if (Offset != null)
|
||||||
{
|
{
|
||||||
uint Start = (uint)Offset + 10;
|
uint Start = (uint)Offset + 10;
|
||||||
uint Length = (uint)ByteOperations.FindPattern(Data, Start, 0x100, new byte[] { 0x00 }, null, null) - Start;
|
uint Length = (uint)ByteOperations.FindPattern(Data, Start, 0x100, [0x00], null, null) - Start;
|
||||||
uint? Offset0D = ByteOperations.FindPattern(Data, Start, 0x100, new byte[] { 0x0D }, null, null);
|
uint? Offset0D = ByteOperations.FindPattern(Data, Start, 0x100, [0x0D], null, null);
|
||||||
if ((Offset0D != null) && (Offset0D < (Start + Length)))
|
if ((Offset0D != null) && (Offset0D < (Start + Length)))
|
||||||
{
|
{
|
||||||
Length = (uint)Offset0D - Start;
|
Length = (uint)Offset0D - Start;
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal enum FlashAppType
|
||||||
|
{
|
||||||
|
BootManager = 1,
|
||||||
|
FlashApp = 2,
|
||||||
|
PhoneInfoApp = 3
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class FlashVersion
|
||||||
|
{
|
||||||
|
public int ApplicationMajor;
|
||||||
|
public int ApplicationMinor;
|
||||||
|
public int ProtocolMajor;
|
||||||
|
public int ProtocolMinor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -74,7 +74,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
while (PartitionOffset < (TableOffset + TableSize))
|
while (PartitionOffset < (TableOffset + TableSize))
|
||||||
{
|
{
|
||||||
string Name = ByteOperations.ReadUnicodeString(GPTBuffer, PartitionOffset + 0x38, 0x48).TrimEnd(new char[] { (char)0, ' ' });
|
string Name = ByteOperations.ReadUnicodeString(GPTBuffer, PartitionOffset + 0x38, 0x48).TrimEnd([(char)0, ' ']);
|
||||||
if (Name.Length == 0)
|
if (Name.Length == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -275,7 +275,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NewPartition.LastSector == 0)
|
if (NewPartition.LastSector == 0)
|
||||||
@@ -471,7 +474,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
DecompressedStream.Close();
|
DecompressedStream.Close();
|
||||||
|
|
||||||
UInt64 MaxPartitionSizeInSectors = OldPartition.SizeInSectors;
|
UInt64 MaxPartitionSizeInSectors = OldPartition.SizeInSectors;
|
||||||
@@ -521,7 +527,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
StreamLengthInSectors = (ulong)DecompressedStream.Length / 0x200;
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
DecompressedStream.Close();
|
DecompressedStream.Close();
|
||||||
if (NewPartition.SizeInSectors != StreamLengthInSectors)
|
if (NewPartition.SizeInSectors != StreamLengthInSectors)
|
||||||
{
|
{
|
||||||
@@ -545,7 +554,7 @@ namespace WPinternals
|
|||||||
internal void WritePartitions(string Path)
|
internal void WritePartitions(string Path)
|
||||||
{
|
{
|
||||||
string DirPath = System.IO.Path.GetDirectoryName(Path);
|
string DirPath = System.IO.Path.GetDirectoryName(Path);
|
||||||
if (!Directory.Exists(DirPath))
|
if (!string.IsNullOrEmpty(DirPath) && !Directory.Exists(DirPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(DirPath);
|
Directory.CreateDirectory(DirPath);
|
||||||
}
|
}
|
||||||
@@ -559,6 +568,15 @@ namespace WPinternals
|
|||||||
FileWriter.Close();
|
FileWriter.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void WritePartitions(Stream Stream)
|
||||||
|
{
|
||||||
|
XmlSerializer x = new(typeof(GPT), "");
|
||||||
|
|
||||||
|
XmlSerializerNamespaces ns = new();
|
||||||
|
ns.Add("", "");
|
||||||
|
x.Serialize(Stream, this, ns);
|
||||||
|
}
|
||||||
|
|
||||||
internal static GPT ReadPartitions(string Path)
|
internal static GPT ReadPartitions(string Path)
|
||||||
{
|
{
|
||||||
XmlSerializer x = new(typeof(GPT), "");
|
XmlSerializer x = new(typeof(GPT), "");
|
||||||
@@ -570,8 +588,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
// This is necessary, because the partitions and backup-partitions can exchange.
|
// This is necessary, because the partitions and backup-partitions can exchange.
|
||||||
// This may cause the startsector to be higher than the maximum allowed sector for flashing with a Lumia V1 programmer (hardcoded in programmer)
|
// This may cause the startsector to be higher than the maximum allowed sector for flashing with a Lumia V1 programmer (hardcoded in programmer)
|
||||||
List<string> RevisePartitions = new(new string[] { "SBL1", "SBL2", "SBL3", "UEFI", "TZ", "RPM", "WINSECAPP" });
|
foreach (string RevisePartitionName in (List<string>)(new(new string[] { "SBL1", "SBL2", "SBL3", "UEFI", "TZ", "RPM", "WINSECAPP" })))
|
||||||
foreach (string RevisePartitionName in RevisePartitions)
|
|
||||||
{
|
{
|
||||||
Partition RevisePartition = GetPartition(RevisePartitionName);
|
Partition RevisePartition = GetPartition(RevisePartitionName);
|
||||||
Partition ReviseBackupPartition = GetPartition("BACKUP_" + RevisePartitionName);
|
Partition ReviseBackupPartition = GetPartition("BACKUP_" + RevisePartitionName);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -110,9 +110,9 @@ namespace WPinternals
|
|||||||
if (DictionarySize != 0)
|
if (DictionarySize != 0)
|
||||||
{
|
{
|
||||||
Encoder.SetCoderProperties(
|
Encoder.SetCoderProperties(
|
||||||
new CoderPropID[8] {CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits,
|
[CoderPropID.DictionarySize, CoderPropID.PosStateBits, CoderPropID.LitContextBits,
|
||||||
CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker},
|
CoderPropID.LitPosBits, CoderPropID.Algorithm, CoderPropID.NumFastBytes, CoderPropID.MatchFinder, CoderPropID.EndMarker],
|
||||||
new object[8] { DictionarySize, PosStateBits, LitContextBits, LitPosBits, Algorithm, NumFastBytes, MatchFinder, EndMarker });
|
[DictionarySize, PosStateBits, LitContextBits, LitPosBits, Algorithm, NumFastBytes, MatchFinder, EndMarker]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Encoder.WriteCoderProperties(stream);
|
Encoder.WriteCoderProperties(stream);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -158,7 +158,7 @@ namespace WPinternals
|
|||||||
return FfuUrl;
|
return FfuUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string SearchENOSW(string ProductType, string PhoneFirmwareRevision)
|
internal static (string SecureWIMUrl, string DPLUrl) SearchENOSW(string ProductType, string PhoneFirmwareRevision)
|
||||||
{
|
{
|
||||||
if (ProductType?.Length == 0)
|
if (ProductType?.Length == 0)
|
||||||
{
|
{
|
||||||
@@ -170,7 +170,7 @@ namespace WPinternals
|
|||||||
ProductType = ProductType.ToUpper();
|
ProductType = ProductType.ToUpper();
|
||||||
if (ProductType.StartsWith("RM") && !ProductType.StartsWith("RM-"))
|
if (ProductType.StartsWith("RM") && !ProductType.StartsWith("RM-"))
|
||||||
{
|
{
|
||||||
ProductType = "RM-" + ProductType[2..];
|
ProductType = $"RM-{ProductType[2..]}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +182,7 @@ namespace WPinternals
|
|||||||
packageClass = "Public",
|
packageClass = "Public",
|
||||||
manufacturerHardwareModel = ProductType
|
manufacturerHardwareModel = ProductType
|
||||||
};
|
};
|
||||||
|
|
||||||
DiscoveryParameters DiscoveryParams = new()
|
DiscoveryParameters DiscoveryParams = new()
|
||||||
{
|
{
|
||||||
query = DiscoveryQueryParams
|
query = DiscoveryQueryParams
|
||||||
@@ -212,10 +213,10 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
|
|
||||||
SoftwarePackage Package = null;
|
SoftwarePackage Package = null;
|
||||||
using (MemoryStream JsonStream2 = new(Encoding.UTF8.GetBytes(JsonResultString)))
|
using MemoryStream JsonResultStream = new(Encoding.UTF8.GetBytes(JsonResultString));
|
||||||
{
|
DataContractJsonSerializer SoftwarePackagesJsonSerializer = new(typeof(SoftwarePackages));
|
||||||
DataContractJsonSerializer Serializer2 = new(typeof(SoftwarePackages));
|
SoftwarePackages SoftwarePackages = (SoftwarePackages)SoftwarePackagesJsonSerializer.ReadObject(JsonResultStream);
|
||||||
SoftwarePackages SoftwarePackages = (SoftwarePackages)Serializer2.ReadObject(JsonStream2);
|
|
||||||
if (SoftwarePackages != null)
|
if (SoftwarePackages != null)
|
||||||
{
|
{
|
||||||
foreach (SoftwarePackage pkg in SoftwarePackages.softwarePackages)
|
foreach (SoftwarePackage pkg in SoftwarePackages.softwarePackages)
|
||||||
@@ -223,48 +224,46 @@ namespace WPinternals
|
|||||||
Package = SoftwarePackages.softwarePackages.FirstOrDefault();
|
Package = SoftwarePackages.softwarePackages.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (Package == null)
|
if (Package == null)
|
||||||
{
|
{
|
||||||
throw new WPinternalsException("ENOSW package not found", "No ENOSW package has been found in the remote software repository for the requested model.");
|
throw new WPinternalsException("ENOSW package not found", "No ENOSW package has been found in the remote software repository for the requested model.");
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftwareFile FileInfo = Package.files.First(f => f.fileName.EndsWith(".secwim", StringComparison.OrdinalIgnoreCase));
|
SoftwareFile SecureWimSoftwareFile = Package.files.First(f => f.fileName.EndsWith(".secwim", StringComparison.OrdinalIgnoreCase));
|
||||||
|
SoftwareFile DPLSoftwareFile = Package.files.First(f => f.fileName.EndsWith(".dpl", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
SoftwareFile DPLF = Package.files.First(f => f.fileName.EndsWith(".dpl", StringComparison.OrdinalIgnoreCase));
|
Uri DPLFileUrlUri = new($"https://api.swrepository.com/rest-api/discovery/fileurl/1/{Package.id}/{DPLSoftwareFile.fileName}");
|
||||||
Uri DPLUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + DPLF.fileName);
|
|
||||||
Task<string> GetDPLTask = HttpClient.GetStringAsync(DPLUri);
|
Task<string> GetDPLTask = HttpClient.GetStringAsync(DPLFileUrlUri);
|
||||||
GetDPLTask.Wait();
|
GetDPLTask.Wait();
|
||||||
string DPLString = GetDPLTask.Result;
|
|
||||||
|
|
||||||
string DPLUrl = "";
|
string DPLFileUrlResultContent = GetDPLTask.Result;
|
||||||
FileUrlResult FileUrlDPL = null;
|
FileUrlResult DPLFileUrlResult = null;
|
||||||
using (MemoryStream JsonStream3 = new(Encoding.UTF8.GetBytes(DPLString)))
|
using MemoryStream DPLFileUrlResultStream = new(Encoding.UTF8.GetBytes(DPLFileUrlResultContent));
|
||||||
|
DataContractJsonSerializer DPLFileUrlResultSerializer = new(typeof(FileUrlResult));
|
||||||
|
DPLFileUrlResult = (FileUrlResult)DPLFileUrlResultSerializer.ReadObject(DPLFileUrlResultStream);
|
||||||
|
|
||||||
|
string DPLFileUrl = "";
|
||||||
|
|
||||||
|
if (DPLFileUrlResult != null)
|
||||||
{
|
{
|
||||||
DataContractJsonSerializer Serializer3 = new(typeof(FileUrlResult));
|
DPLFileUrl = DPLFileUrlResult.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net");
|
||||||
FileUrlDPL = (FileUrlResult)Serializer3.ReadObject(JsonStream3);
|
|
||||||
if (FileUrlDPL != null)
|
|
||||||
{
|
|
||||||
DPLUrl = FileUrlDPL.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DPLUrl?.Length == 0)
|
if (DPLFileUrl?.Length == 0)
|
||||||
{
|
{
|
||||||
throw new WPinternalsException("DPL not found", "No DPL has been found in the remote software repository for the requested model.");
|
throw new WPinternalsException("DPL not found", "No DPL has been found in the remote software repository for the requested model.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Task<string> GetDPLStrTask = HttpClient.GetStringAsync(DPLUrl);
|
Task<string> GetDPLStrTask = HttpClient.GetStringAsync(DPLFileUrl);
|
||||||
GetDPLStrTask.Wait();
|
GetDPLStrTask.Wait();
|
||||||
string DPLStrString = GetDPLStrTask.Result;
|
string DPLStrString = GetDPLStrTask.Result;
|
||||||
|
|
||||||
DPL.Package dpl;
|
DPL.Package dpl;
|
||||||
XmlSerializer serializer = new(typeof(DPL.Package));
|
XmlSerializer serializer = new(typeof(DPL.Package));
|
||||||
using (StringReader reader = new(DPLStrString.Replace("ft:", "").Replace("dpl:", "").Replace("typedes:", "")))
|
using StringReader reader = new(DPLStrString.Replace("ft:", "").Replace("dpl:", "").Replace("typedes:", ""));
|
||||||
{
|
|
||||||
dpl = (DPL.Package)serializer.Deserialize(reader);
|
dpl = (DPL.Package)serializer.Deserialize(reader);
|
||||||
}
|
|
||||||
|
|
||||||
foreach (DPL.File file in dpl.Content.Files.File)
|
foreach (DPL.File file in dpl.Content.Files.File)
|
||||||
{
|
{
|
||||||
@@ -274,30 +273,30 @@ namespace WPinternals
|
|||||||
|
|
||||||
if (IsFirmwareBetween(PhoneFirmwareRevision, range.From, range.To))
|
if (IsFirmwareBetween(PhoneFirmwareRevision, range.From, range.To))
|
||||||
{
|
{
|
||||||
FileInfo = Package.files.First(f => f.fileName.EndsWith(name, StringComparison.OrdinalIgnoreCase));
|
SecureWimSoftwareFile = Package.files.First(f => f.fileName.EndsWith(name, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri FileInfoUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + FileInfo.fileName);
|
Uri FileInfoUri = new("https://api.swrepository.com/rest-api/discovery/fileurl/1/" + Package.id + "/" + SecureWimSoftwareFile.fileName);
|
||||||
Task<string> GetFileInfoTask = HttpClient.GetStringAsync(FileInfoUri);
|
Task<string> GetFileInfoTask = HttpClient.GetStringAsync(FileInfoUri);
|
||||||
GetFileInfoTask.Wait();
|
GetFileInfoTask.Wait();
|
||||||
string FileInfoString = GetFileInfoTask.Result;
|
string FileInfoString = GetFileInfoTask.Result;
|
||||||
|
|
||||||
string ENOSWUrl = "";
|
string ENOSWFileUrl = "";
|
||||||
|
|
||||||
FileUrlResult FileUrl = null;
|
FileUrlResult FileUrl = null;
|
||||||
using (MemoryStream JsonStream3 = new(Encoding.UTF8.GetBytes(FileInfoString)))
|
|
||||||
{
|
using MemoryStream JsonStream4 = new(Encoding.UTF8.GetBytes(FileInfoString));
|
||||||
DataContractJsonSerializer Serializer3 = new(typeof(FileUrlResult));
|
DataContractJsonSerializer Serializer4 = new(typeof(FileUrlResult));
|
||||||
FileUrl = (FileUrlResult)Serializer3.ReadObject(JsonStream3);
|
FileUrl = (FileUrlResult)Serializer4.ReadObject(JsonStream4);
|
||||||
if (FileUrl != null)
|
if (FileUrl != null)
|
||||||
{
|
{
|
||||||
ENOSWUrl = FileUrl.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net");
|
ENOSWFileUrl = FileUrl.url.Replace("sr.azureedge.net", "softwarerepo.blob.core.windows.net");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClient.Dispose();
|
HttpClient.Dispose();
|
||||||
|
|
||||||
return ENOSWUrl;
|
return (ENOSWFileUrl, DPLFileUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsFirmwareBetween(string PhoneFirmwareRevision, string Limit1, string Limit2)
|
private static bool IsFirmwareBetween(string PhoneFirmwareRevision, string Limit1, string Limit2)
|
||||||
@@ -386,7 +385,7 @@ namespace WPinternals
|
|||||||
Result.Add(Src);
|
Result.Add(Src);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.ToArray();
|
return [.. Result];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -41,8 +41,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ManagementObjectCollection coll = new ManagementObjectSearcher("select * from Win32_LogicalDisk").Get();
|
foreach (ManagementObject logical in new ManagementObjectSearcher("select * from Win32_LogicalDisk").Get())
|
||||||
foreach (ManagementObject logical in coll)
|
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Print(logical["Name"].ToString());
|
System.Diagnostics.Debug.Print(logical["Name"].ToString());
|
||||||
|
|
||||||
@@ -74,7 +73,10 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AttachQualcommSerial(string DevicePath)
|
internal void AttachQualcommSerial(string DevicePath)
|
||||||
@@ -112,15 +114,18 @@ namespace WPinternals
|
|||||||
SerialDevice.EncodeCommands = false;
|
SerialDevice.EncodeCommands = false;
|
||||||
|
|
||||||
// This will succeed on new models
|
// This will succeed on new models
|
||||||
SerialDevice.SendData(new byte[] { 0x7, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0 });
|
SerialDevice.SendData([0x7, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0]);
|
||||||
|
|
||||||
// This will succeed on old models
|
// This will succeed on old models
|
||||||
SerialDevice.SendData(new byte[] { 0x7E, 0xA, 0x0, 0x0, 0xB6, 0xB5, 0x7E });
|
SerialDevice.SendData([0x7E, 0xA, 0x0, 0x0, 0xB6, 0xB5, 0x7E]);
|
||||||
|
|
||||||
SerialDevice.Close();
|
SerialDevice.Close();
|
||||||
SerialDevice.Dispose();
|
SerialDevice.Dispose();
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -40,7 +40,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
Device = new USBDevice(DevicePath);
|
Device = new USBDevice(DevicePath);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JsonElement? ExecuteJsonMethodAsJsonToken(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
private JsonElement? ExecuteJsonMethodAsJsonToken(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
||||||
@@ -173,6 +176,11 @@ namespace WPinternals
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Token.Value.ValueKind == JsonValueKind.String)
|
||||||
|
{
|
||||||
|
return Token.Value.GetString().Equals("true", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
return Token.Value.GetBoolean();
|
return Token.Value.GetBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +343,10 @@ namespace WPinternals
|
|||||||
Result = new byte[OutputLength];
|
Result = new byte[OutputLength];
|
||||||
System.Buffer.BlockCopy(Buffer, 0, Result, 0, OutputLength);
|
System.Buffer.BlockCopy(Buffer, 0, Result, 0, OutputLength);
|
||||||
}
|
}
|
||||||
catch { } // Reboot command looses connection
|
catch (Exception ex) // Reboot command looses connection
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -363,7 +374,10 @@ namespace WPinternals
|
|||||||
pipe.Reset();
|
pipe.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -40,14 +40,14 @@ namespace WPinternals
|
|||||||
|
|
||||||
internal PatchEngine(string PatchDefinitionsXmlString)
|
internal PatchEngine(string PatchDefinitionsXmlString)
|
||||||
{
|
{
|
||||||
XmlSerializer x = new(PatchDefinitions.GetType(), null, Array.Empty<Type>(), new XmlRootAttribute("PatchDefinitions"), "");
|
XmlSerializer x = new(PatchDefinitions.GetType(), null, [], new XmlRootAttribute("PatchDefinitions"), "");
|
||||||
MemoryStream s = new(System.Text.Encoding.ASCII.GetBytes(PatchDefinitionsXmlString));
|
MemoryStream s = new(System.Text.Encoding.ASCII.GetBytes(PatchDefinitionsXmlString));
|
||||||
PatchDefinitions = (List<PatchDefinition>)x.Deserialize(s);
|
PatchDefinitions = (List<PatchDefinition>)x.Deserialize(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void WriteDefinitions(string FilePath)
|
internal void WriteDefinitions(string FilePath)
|
||||||
{
|
{
|
||||||
XmlSerializer x = new(PatchDefinitions.GetType(), null, Array.Empty<Type>(), new XmlRootAttribute("PatchDefinitions"), "");
|
XmlSerializer x = new(PatchDefinitions.GetType(), null, [], new XmlRootAttribute("PatchDefinitions"), "");
|
||||||
|
|
||||||
XmlSerializerNamespaces ns = new();
|
XmlSerializerNamespaces ns = new();
|
||||||
ns.Add("", "");
|
ns.Add("", "");
|
||||||
@@ -58,7 +58,7 @@ namespace WPinternals
|
|||||||
FileWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
FileWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||||
FileWriter.WriteLine("");
|
FileWriter.WriteLine("");
|
||||||
FileWriter.WriteLine("<!--");
|
FileWriter.WriteLine("<!--");
|
||||||
FileWriter.WriteLine("Copyright(c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda");
|
FileWriter.WriteLine("Copyright(c) 2018, Rene Lergner - @Heathcliff74xda");
|
||||||
FileWriter.WriteLine("");
|
FileWriter.WriteLine("");
|
||||||
FileWriter.WriteLine("Permission is hereby granted, free of charge, to any person obtaining a");
|
FileWriter.WriteLine("Permission is hereby granted, free of charge, to any person obtaining a");
|
||||||
FileWriter.WriteLine("copy of this software and associated documentation files(the \"Software\"),");
|
FileWriter.WriteLine("copy of this software and associated documentation files(the \"Software\"),");
|
||||||
@@ -94,7 +94,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_TargetPath = value.TrimEnd(new char[] { '\\' });
|
_TargetPath = value.TrimEnd(['\\']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +365,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_RelativePath = value.TrimStart(new char[] { '\\' }).TrimEnd(new char[] { '\\' });
|
_RelativePath = value.TrimStart(['\\']).TrimEnd(['\\']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +377,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_TargetPath = value.TrimEnd(new char[] { '\\' });
|
_TargetPath = value.TrimEnd(['\\']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,7 +515,7 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_Path = value.TrimStart(new char[] { '\\' });
|
_Path = value.TrimStart(['\\']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class CommonPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte VersionMajor;
|
||||||
|
public byte VersionMinor;
|
||||||
|
public byte ProtocolVersionMajor;
|
||||||
|
public byte ProtocolVersionMinor;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
LogFile.Log($"App: {VersionMajor}.{VersionMinor}", Type);
|
||||||
|
LogFile.Log($"Protocol: {ProtocolVersionMajor}.{ProtocolVersionMinor}", Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaBootManagerPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte FlashAppVersionMajor;
|
||||||
|
public byte FlashAppVersionMinor;
|
||||||
|
public byte FlashAppProtocolVersionMajor;
|
||||||
|
public byte FlashAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
public byte BootManagerVersionMajor;
|
||||||
|
public byte BootManagerVersionMinor;
|
||||||
|
public byte BootManagerProtocolVersionMajor;
|
||||||
|
public byte BootManagerProtocolVersionMinor;
|
||||||
|
|
||||||
|
public UInt32 TransferSize;
|
||||||
|
public bool MmosOverUsbSupported;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.BootManager:
|
||||||
|
LogFile.Log($"Bootmanager: {BootManagerVersionMajor}.{BootManagerVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Bootmanager protocol: {BootManagerProtocolVersionMajor}.{BootManagerProtocolVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaFlashAppPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public string Firmware; // Extended info
|
||||||
|
public byte[] RKH; // Extended info
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte FlashAppVersionMajor;
|
||||||
|
public byte FlashAppVersionMinor;
|
||||||
|
public byte FlashAppProtocolVersionMajor;
|
||||||
|
public byte FlashAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
public UInt32 TransferSize;
|
||||||
|
public bool MmosOverUsbSupported;
|
||||||
|
public UInt32 SdCardSizeInSectors;
|
||||||
|
public UInt32 WriteBufferSize;
|
||||||
|
public UInt32 EmmcSizeInSectors;
|
||||||
|
public string PlatformID;
|
||||||
|
public UInt16 SecureFfuSupportedProtocolMask;
|
||||||
|
public bool AsyncSupport;
|
||||||
|
|
||||||
|
public bool PlatformSecureBootEnabled;
|
||||||
|
public bool SecureFfuEnabled;
|
||||||
|
public bool JtagDisabled;
|
||||||
|
public bool RdcPresent;
|
||||||
|
public bool Authenticated;
|
||||||
|
public bool UefiSecureBootEnabled;
|
||||||
|
public bool SecondaryHardwareKeyPresent;
|
||||||
|
|
||||||
|
public bool IsBootloaderSecure;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
if (State == PhoneInfoState.Extended)
|
||||||
|
{
|
||||||
|
if (RKH != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Root key hash: {Converter.ConvertHexToString(RKH, "")}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Firmware?.Length > 0)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Firmware version: {Firmware}", Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.FlashApp:
|
||||||
|
LogFile.Log($"Flash app: {FlashAppVersionMajor}.{FlashAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Flash protocol: {FlashAppProtocolVersionMajor}.{FlashAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogFile.Log($"SecureBoot: {((!PlatformSecureBootEnabled || !UefiSecureBootEnabled) ? "Disabled" : "Enabled")} (Platform Secure Boot: {(PlatformSecureBootEnabled ? "Enabled" : "Disabled")}, UEFI Secure Boot: {(UefiSecureBootEnabled ? "Enabled" : "Disabled")})", Type);
|
||||||
|
|
||||||
|
if ((Type == LogType.ConsoleOnly) || (Type == LogType.FileAndConsole))
|
||||||
|
{
|
||||||
|
LogFile.Log($"Flash app security: {(!IsBootloaderSecure ? "Disabled" : "Enabled")}", LogType.ConsoleOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Type == LogType.FileOnly) || (Type == LogType.FileAndConsole))
|
||||||
|
{
|
||||||
|
LogFile.Log($"Flash app security: {(!IsBootloaderSecure ? "Disabled" : "Enabled")} (FFU security: {(SecureFfuEnabled ? "Enabled" : "Disabled")}, RDC: {(RdcPresent ? "Present" : "Not found")}, Authenticated: {(Authenticated ? "True" : "False")})", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogFile.Log($"JTAG: {(JtagDisabled ? "Disabled" : "Enabled")}", Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaPhoneInfoAppPhoneInfo
|
||||||
|
{
|
||||||
|
public PhoneInfoState State = PhoneInfoState.Empty;
|
||||||
|
|
||||||
|
public string Type; // Extended info
|
||||||
|
public string ProductCode; // Extended info
|
||||||
|
public string Imei; // Extended info
|
||||||
|
|
||||||
|
public FlashAppType App;
|
||||||
|
|
||||||
|
public byte PhoneInfoAppVersionMajor;
|
||||||
|
public byte PhoneInfoAppVersionMinor;
|
||||||
|
public byte PhoneInfoAppProtocolVersionMajor;
|
||||||
|
public byte PhoneInfoAppProtocolVersionMinor;
|
||||||
|
|
||||||
|
internal void Log(LogType Type)
|
||||||
|
{
|
||||||
|
if (State == PhoneInfoState.Extended)
|
||||||
|
{
|
||||||
|
if (this.Type != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Phone type: {this.Type}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProductCode != null)
|
||||||
|
{
|
||||||
|
LogFile.Log($"Product code: {ProductCode}", Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type != LogType.ConsoleOnly && (Imei != null))
|
||||||
|
{
|
||||||
|
LogFile.Log($"IMEI: {Imei}", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (App)
|
||||||
|
{
|
||||||
|
case FlashAppType.PhoneInfoApp:
|
||||||
|
LogFile.Log($"Phone info app: {PhoneInfoAppVersionMajor}.{PhoneInfoAppVersionMinor}", Type);
|
||||||
|
LogFile.Log($"Phone info protocol: {PhoneInfoAppProtocolVersionMajor}.{PhoneInfoAppProtocolVersionMinor}", Type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal enum PhoneInfoState
|
||||||
|
{
|
||||||
|
Empty,
|
||||||
|
Basic,
|
||||||
|
Extended
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -37,7 +37,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Serial.SendCommand(new byte[] { 0x06 }, new byte[] { 0x02 });
|
Serial.SendCommand([0x06], [0x02]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -61,7 +61,7 @@ namespace WPinternals
|
|||||||
CurrentLength = Remaining >= 0x100 ? 0x100 : (UInt32)Remaining;
|
CurrentLength = Remaining >= 0x100 ? 0x100 : (UInt32)Remaining;
|
||||||
|
|
||||||
CurrentLength = (UInt32)Data.Read(Buffer, 7, (int)CurrentLength);
|
CurrentLength = (UInt32)Data.Read(Buffer, 7, (int)CurrentLength);
|
||||||
Serial.SendCommand(Buffer, new byte[] { 0x02 });
|
Serial.SendCommand(Buffer, [0x02]);
|
||||||
|
|
||||||
CurrentAddress += CurrentLength;
|
CurrentAddress += CurrentLength;
|
||||||
Remaining -= CurrentLength;
|
Remaining -= CurrentLength;
|
||||||
@@ -100,7 +100,7 @@ namespace WPinternals
|
|||||||
System.Buffer.BlockCopy(BitConverter.GetBytes((UInt16)CurrentLength).Reverse().ToArray(), 0, CurrentBytes, 5, 2); // Length is in Big Endian
|
System.Buffer.BlockCopy(BitConverter.GetBytes((UInt16)CurrentLength).Reverse().ToArray(), 0, CurrentBytes, 5, 2); // Length is in Big Endian
|
||||||
System.Buffer.BlockCopy(Data, (int)CurrentOffset, CurrentBytes, 7, (int)CurrentLength);
|
System.Buffer.BlockCopy(Data, (int)CurrentOffset, CurrentBytes, 7, (int)CurrentLength);
|
||||||
|
|
||||||
Serial.SendCommand(CurrentBytes, new byte[] { 0x02 });
|
Serial.SendCommand(CurrentBytes, [0x02]);
|
||||||
|
|
||||||
CurrentAddress += CurrentLength;
|
CurrentAddress += CurrentLength;
|
||||||
CurrentOffset += CurrentLength;
|
CurrentOffset += CurrentLength;
|
||||||
@@ -113,25 +113,25 @@ namespace WPinternals
|
|||||||
byte[] Buffer = new byte[5];
|
byte[] Buffer = new byte[5];
|
||||||
Buffer[0] = 0x05;
|
Buffer[0] = 0x05;
|
||||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Address).Reverse().ToArray(), 0, Buffer, 1, 4); // Address is in Big Endian
|
System.Buffer.BlockCopy(BitConverter.GetBytes(Address).Reverse().ToArray(), 0, Buffer, 1, 4); // Address is in Big Endian
|
||||||
Serial.SendCommand(Buffer, new byte[] { 0x02 });
|
Serial.SendCommand(Buffer, [0x02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset interface. Interface becomes unresponsive.
|
// Reset interface. Interface becomes unresponsive.
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
Serial.SendCommand(new byte[] { 0x0A }, new byte[] { 0x02 });
|
Serial.SendCommand([0x0A], [0x02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This also resets interface. This does not actually reboot the phone. The interface becomes unresponsive.
|
// This also resets interface. This does not actually reboot the phone. The interface becomes unresponsive.
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
Serial.SendCommand(new byte[] { 0x0E }, new byte[] { 0x02 });
|
Serial.SendCommand([0x0E], [0x02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This command only works on 9008 interface.
|
// This command only works on 9008 interface.
|
||||||
public byte[] GetRKH()
|
public byte[] GetRKH()
|
||||||
{
|
{
|
||||||
byte[] Response = Serial.SendCommand(new byte[] { 0x18 }, new byte[] { 0x18, 0x01, 0x00 });
|
byte[] Response = Serial.SendCommand([0x18], [0x18, 0x01, 0x00]);
|
||||||
byte[] Result = new byte[0x20];
|
byte[] Result = new byte[0x20];
|
||||||
Buffer.BlockCopy(Response, 3, Result, 0, 0x20);
|
Buffer.BlockCopy(Response, 3, Result, 0, 0x20);
|
||||||
return Result;
|
return Result;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -28,165 +28,15 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace WPinternals
|
namespace WPinternals
|
||||||
{
|
{
|
||||||
internal enum SaharaMode : uint
|
internal class QualcommFirehose
|
||||||
{
|
|
||||||
ImageTransferPending = 0x00,
|
|
||||||
ImagetransferComplete = 0x01,
|
|
||||||
MemoryDebug = 0x02,
|
|
||||||
Command = 0x03
|
|
||||||
}
|
|
||||||
|
|
||||||
internal delegate void ReadyHandler();
|
|
||||||
|
|
||||||
internal class QualcommSahara
|
|
||||||
{
|
{
|
||||||
private readonly QualcommSerial Serial;
|
private readonly QualcommSerial Serial;
|
||||||
|
|
||||||
public QualcommSahara(QualcommSerial Serial)
|
public QualcommFirehose(QualcommSerial Serial)
|
||||||
{
|
{
|
||||||
Serial.EncodeCommands = false;
|
|
||||||
Serial.DecodeResponses = false;
|
|
||||||
this.Serial = Serial;
|
this.Serial = Serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SendImage(string Path)
|
|
||||||
{
|
|
||||||
bool Result = true;
|
|
||||||
|
|
||||||
LogFile.Log("Sending programmer: " + Path, LogType.FileOnly);
|
|
||||||
|
|
||||||
int Step = 0;
|
|
||||||
UInt32 Offset = 0;
|
|
||||||
UInt32 Length = 0;
|
|
||||||
|
|
||||||
byte[] ImageBuffer = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Step = 1;
|
|
||||||
byte[] Hello = Serial.GetResponse(new byte[] { 0x01, 0x00, 0x00, 0x00 });
|
|
||||||
|
|
||||||
// Incoming Hello packet:
|
|
||||||
// 00000001 = Hello command id
|
|
||||||
// xxxxxxxx = Length
|
|
||||||
// xxxxxxxx = Protocol version
|
|
||||||
// xxxxxxxx = Supported version
|
|
||||||
// xxxxxxxx = Max packet length
|
|
||||||
// xxxxxxxx = Expected mode
|
|
||||||
// 6 dwords reserved space
|
|
||||||
LogFile.Log("Protocol: 0x" + ByteOperations.ReadUInt32(Hello, 0x08).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("Supported: 0x" + ByteOperations.ReadUInt32(Hello, 0x0C).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
|
|
||||||
|
|
||||||
// Packet:
|
|
||||||
// 00000002 = Hello response command id
|
|
||||||
// 00000030 = Length
|
|
||||||
// 00000002 = Protocol version
|
|
||||||
// 00000001 = Supported version
|
|
||||||
// 00000000 = Status OK
|
|
||||||
// 00000000 = Mode
|
|
||||||
// rest is reserved space
|
|
||||||
Step = 2;
|
|
||||||
byte[] HelloResponse = new byte[] {
|
|
||||||
0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
Serial.SendData(HelloResponse);
|
|
||||||
|
|
||||||
Step = 3;
|
|
||||||
using FileStream FileStream = new(Path, FileMode.Open, FileAccess.Read);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
Step = 4;
|
|
||||||
byte[] ReadDataRequest = Serial.GetResponse(null);
|
|
||||||
UInt32 ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
|
|
||||||
if (ResponseID == 4)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ResponseID != 3)
|
|
||||||
{
|
|
||||||
Step = 5;
|
|
||||||
throw new BadConnectionException();
|
|
||||||
}
|
|
||||||
|
|
||||||
Offset = ByteOperations.ReadUInt32(ReadDataRequest, 0x0C);
|
|
||||||
Length = ByteOperations.ReadUInt32(ReadDataRequest, 0x10);
|
|
||||||
if ((ImageBuffer == null) || (ImageBuffer.Length != Length))
|
|
||||||
{
|
|
||||||
ImageBuffer = new byte[Length];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FileStream.Position != Offset)
|
|
||||||
{
|
|
||||||
FileStream.Seek(Offset, SeekOrigin.Begin);
|
|
||||||
}
|
|
||||||
|
|
||||||
Step = 6;
|
|
||||||
FileStream.Read(ImageBuffer, 0, (int)Length);
|
|
||||||
|
|
||||||
Step = 7;
|
|
||||||
Serial.SendData(ImageBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception Ex)
|
|
||||||
{
|
|
||||||
LogFile.LogException(Ex, LogType.FileAndConsole, Step.ToString() + " 0x" + Offset.ToString("X8") + " 0x" + Length.ToString("X8"));
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Result)
|
|
||||||
{
|
|
||||||
LogFile.Log("Programmer loaded into phone memory", LogType.FileOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Handshake()
|
|
||||||
{
|
|
||||||
bool Result = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] Hello = Serial.GetResponse(new byte[] { 0x01, 0x00, 0x00, 0x00 });
|
|
||||||
|
|
||||||
// Incoming Hello packet:
|
|
||||||
// 00000001 = Hello command id
|
|
||||||
// xxxxxxxx = Length
|
|
||||||
// xxxxxxxx = Protocol version
|
|
||||||
// xxxxxxxx = Supported version
|
|
||||||
// xxxxxxxx = Max packet length
|
|
||||||
// xxxxxxxx = Expected mode
|
|
||||||
// 6 dwords reserved space
|
|
||||||
LogFile.Log("Protocol: 0x" + ByteOperations.ReadUInt32(Hello, 0x08).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("Supported: 0x" + ByteOperations.ReadUInt32(Hello, 0x0C).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
|
|
||||||
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
|
|
||||||
|
|
||||||
byte[] HelloResponse = new byte[] {
|
|
||||||
0x02, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
byte[] Ready = Serial.SendCommand(HelloResponse, new byte[] { 0x03, 0x00, 0x00, 0x00 });
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetSahara()
|
|
||||||
{
|
|
||||||
Serial.SendCommand(new byte[] { 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }, new byte[] { 0x08, 0x00, 0x00, 0x00 });
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ConnectToProgrammer(byte[] PacketFromPcToProgrammer)
|
public bool ConnectToProgrammer(byte[] PacketFromPcToProgrammer)
|
||||||
{
|
{
|
||||||
// Behaviour of old firehose:
|
// Behaviour of old firehose:
|
||||||
@@ -251,7 +101,10 @@ namespace WPinternals
|
|||||||
LogFile.Log("Programmer failed to authenticate Digital Signature", LogType.FileOnly);
|
LogFile.Log("Programmer failed to authenticate Digital Signature", LogType.FileOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (!HandshakeCompleted && (HelloSendCount < 6));
|
while (!HandshakeCompleted && (HelloSendCount < 6));
|
||||||
|
|
||||||
@@ -280,16 +133,8 @@ namespace WPinternals
|
|||||||
return HandshakeCompleted;
|
return HandshakeCompleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> Reset(string ProgrammerPath)
|
public async Task<bool> Reset()
|
||||||
{
|
{
|
||||||
bool SendImageResult = await Task.Run(() => SendImage(ProgrammerPath));
|
|
||||||
if (!SendImageResult)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Run(() => StartProgrammer());
|
|
||||||
|
|
||||||
bool Connected = await Task.Run(() => ConnectToProgrammerInTestMode());
|
bool Connected = await Task.Run(() => ConnectToProgrammerInTestMode());
|
||||||
if (!Connected)
|
if (!Connected)
|
||||||
{
|
{
|
||||||
@@ -317,59 +162,12 @@ namespace WPinternals
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwitchMode(SaharaMode Mode)
|
public bool SendEdPayload(string ProgrammerPath, string PayloadPath)
|
||||||
{
|
|
||||||
byte[] SwitchModeCommand = new byte[] { 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
ByteOperations.WriteUInt32(SwitchModeCommand, 8, (UInt32)Mode);
|
|
||||||
byte[] ResponsePattern = null;
|
|
||||||
switch (Mode)
|
|
||||||
{
|
|
||||||
case SaharaMode.ImageTransferPending:
|
|
||||||
ResponsePattern = new byte[] { 0x04, 0x00, 0x00, 0x00 };
|
|
||||||
break;
|
|
||||||
case SaharaMode.MemoryDebug:
|
|
||||||
ResponsePattern = new byte[] { 0x09, 0x00, 0x00, 0x00 };
|
|
||||||
break;
|
|
||||||
case SaharaMode.Command:
|
|
||||||
ResponsePattern = new byte[] { 0x0B, 0x00, 0x00, 0x00 };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Serial.SendCommand(SwitchModeCommand, ResponsePattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StartProgrammer()
|
|
||||||
{
|
|
||||||
LogFile.Log("Starting programmer", LogType.FileAndConsole);
|
|
||||||
byte[] DoneCommand = new byte[] { 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 };
|
|
||||||
bool Started = false;
|
|
||||||
int count = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] DoneResponse = Serial.SendCommand(DoneCommand, new byte[] { 0x06, 0x00, 0x00, 0x00 });
|
|
||||||
Started = true;
|
|
||||||
}
|
|
||||||
catch (BadConnectionException)
|
|
||||||
{
|
|
||||||
LogFile.Log("Problem while starting programmer. Attempting again.", LogType.FileAndConsole);
|
|
||||||
}
|
|
||||||
} while (!Started && count < 3);
|
|
||||||
if (count >= 3 && !Started)
|
|
||||||
{
|
|
||||||
LogFile.Log("Maximum number of attempts to start the programmer exceeded.", LogType.FileAndConsole);
|
|
||||||
throw new BadConnectionException();
|
|
||||||
}
|
|
||||||
LogFile.Log("Programmer being launched on phone", LogType.FileOnly);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<bool> SendEdPayload(string ProgrammerPath, string PayloadPath)
|
|
||||||
{
|
{
|
||||||
// First, let's read the Emergency Download payload header and verify its validity
|
// First, let's read the Emergency Download payload header and verify its validity
|
||||||
FileStream PayloadStream = File.OpenRead(PayloadPath);
|
FileStream PayloadStream = File.OpenRead(PayloadPath);
|
||||||
|
|
||||||
byte[] ValidReferencePayloadHeader = new byte[] { 0x45, 0x6D, 0x65, 0x72, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x20, 0x50, 0x61, 0x79, 0x6C, 0x6F, 0x61, 0x64 };
|
byte[] ValidReferencePayloadHeader = [0x45, 0x6D, 0x65, 0x72, 0x67, 0x65, 0x6E, 0x63, 0x79, 0x20, 0x50, 0x61, 0x79, 0x6C, 0x6F, 0x61, 0x64];
|
||||||
|
|
||||||
byte[] PayloadHeader = new byte[17];
|
byte[] PayloadHeader = new byte[17];
|
||||||
PayloadStream.Read(PayloadHeader, 0, 17);
|
PayloadStream.Read(PayloadHeader, 0, 17);
|
||||||
@@ -405,16 +203,6 @@ namespace WPinternals
|
|||||||
LogFile.Log("Version: " + version, LogType.FileAndConsole);
|
LogFile.Log("Version: " + version, LogType.FileAndConsole);
|
||||||
LogFile.Log("Info: " + Info, LogType.FileAndConsole);
|
LogFile.Log("Info: " + Info, LogType.FileAndConsole);
|
||||||
|
|
||||||
// Send the emergency programmer to the phone
|
|
||||||
bool SendImageResult = await Task.Run(() => SendImage(ProgrammerPath));
|
|
||||||
if (!SendImageResult)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the emergency programmer on the phone
|
|
||||||
await Task.Run(() => StartProgrammer());
|
|
||||||
|
|
||||||
// Wait a few seconds before sending commands
|
// Wait a few seconds before sending commands
|
||||||
LogFile.Log("Waiting...", LogType.FileAndConsole);
|
LogFile.Log("Waiting...", LogType.FileAndConsole);
|
||||||
Thread.Sleep(2000);
|
Thread.Sleep(2000);
|
||||||
@@ -434,7 +222,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
LogFile.Log(ProgrammerCommand, LogType.FileAndConsole);
|
LogFile.Log(ProgrammerCommand, LogType.FileAndConsole);
|
||||||
|
|
||||||
byte[] PacketFromPcToProgrammer = Array.Empty<byte>();
|
byte[] PacketFromPcToProgrammer = [];
|
||||||
byte[] temp = new byte[0x200];
|
byte[] temp = new byte[0x200];
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@@ -453,7 +241,7 @@ namespace WPinternals
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketFromPcToProgrammer = PacketFromPcToProgrammer.Concat(temp).ToArray();
|
PacketFromPcToProgrammer = [.. PacketFromPcToProgrammer, .. temp];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ExpectingReplyFromProgrammer = false;
|
bool ExpectingReplyFromProgrammer = false;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -45,41 +45,37 @@ namespace WPinternals
|
|||||||
|
|
||||||
public void Hello()
|
public void Hello()
|
||||||
{
|
{
|
||||||
byte[] Command = new byte[]
|
byte[] Command =
|
||||||
{
|
[
|
||||||
0x01, // Hello command
|
0x01, // Hello command
|
||||||
0x51, 0x43, 0x4F, 0x4D, 0x20, 0x66, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, // "QCOM fast download protocol host"
|
0x51, 0x43, 0x4F, 0x4D, 0x20, 0x66, 0x61, 0x73, 0x74, 0x20, 0x64, 0x6F, 0x77, 0x6E, 0x6C, 0x6F, // "QCOM fast download protocol host"
|
||||||
0x61, 0x64, 0x20, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x20, 0x68, 0x6F, 0x73, 0x74,
|
0x61, 0x64, 0x20, 0x70, 0x72, 0x6F, 0x74, 0x6F, 0x63, 0x6F, 0x6C, 0x20, 0x68, 0x6F, 0x73, 0x74,
|
||||||
0x02,
|
0x02,
|
||||||
0x02, // Protocol version - Must be at least 0x02
|
0x02, // Protocol version - Must be at least 0x02
|
||||||
0x01
|
0x01
|
||||||
};
|
];
|
||||||
|
|
||||||
Serial.SendCommand(Command, new byte[] { 0x02 });
|
Serial.SendCommand(Command, [0x02]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSecurityMode(byte Mode)
|
public void SetSecurityMode(byte Mode)
|
||||||
{
|
{
|
||||||
byte[] Command = new byte[2];
|
byte[] Command = [0x17, Mode];
|
||||||
Command[0] = 0x17;
|
|
||||||
Command[1] = Mode;
|
|
||||||
|
|
||||||
Serial.SendCommand(Command, new byte[] { 0x18 });
|
Serial.SendCommand(Command, [0x18]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use PartitionID 0x21
|
// Use PartitionID 0x21
|
||||||
public void OpenPartition(byte PartitionID)
|
public void OpenPartition(byte PartitionID)
|
||||||
{
|
{
|
||||||
byte[] Command = new byte[2];
|
byte[] Command = [0x1B, PartitionID];
|
||||||
Command[0] = 0x1B;
|
|
||||||
Command[1] = PartitionID;
|
|
||||||
|
|
||||||
Serial.SendCommand(Command, new byte[] { 0x1C });
|
Serial.SendCommand(Command, [0x1C]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClosePartition()
|
public void ClosePartition()
|
||||||
{
|
{
|
||||||
Serial.SendCommand(new byte[] { 0x15 }, new byte[] { 0x16 });
|
Serial.SendCommand([0x15], [0x16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Flash(UInt32 StartInBytes, Stream Data, UInt32 LengthInBytes = UInt32.MaxValue)
|
public void Flash(UInt32 StartInBytes, Stream Data, UInt32 LengthInBytes = UInt32.MaxValue)
|
||||||
@@ -222,7 +218,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
public void Reboot()
|
public void Reboot()
|
||||||
{
|
{
|
||||||
Serial.SendCommand(new byte[] { 0x0B }, new byte[] { 0x0C });
|
Serial.SendCommand([0x0B], [0x0C]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -33,8 +33,7 @@ namespace WPinternals
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IEnumerable<string> FilePaths = Directory.EnumerateFiles(Path);
|
foreach (string FilePath in Directory.EnumerateFiles(Path))
|
||||||
foreach (string FilePath in FilePaths)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -70,10 +69,16 @@ namespace WPinternals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -90,6 +95,11 @@ namespace WPinternals
|
|||||||
|
|
||||||
foreach (string Line in Lines)
|
foreach (string Line in Lines)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(Line))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (Line[0] != ':')
|
if (Line[0] != ':')
|
||||||
{
|
{
|
||||||
throw new BadImageFormatException();
|
throw new BadImageFormatException();
|
||||||
@@ -117,7 +127,10 @@ namespace WPinternals
|
|||||||
Result = new byte[BufferSize];
|
Result = new byte[BufferSize];
|
||||||
System.Buffer.BlockCopy(Buffer, 0, Result, 0, BufferSize);
|
System.Buffer.BlockCopy(Buffer, 0, Result, 0, BufferSize);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
@@ -52,15 +53,15 @@ namespace WPinternals
|
|||||||
internal QualcommPartition(byte[] Binary, uint Offset = 0)
|
internal QualcommPartition(byte[] Binary, uint Offset = 0)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
System.Diagnostics.Debug.Print("Loader: " + Converter.ConvertHexToString(new SHA256Managed().ComputeHash(Binary, 0, Binary.Length), ""));
|
System.Diagnostics.Debug.Print("Loader: " + Converter.ConvertHexToString(SHA256.HashData(Binary.AsSpan(0, Binary.Length)), ""));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
this.Binary = Binary;
|
this.Binary = Binary;
|
||||||
|
|
||||||
byte[] LongHeaderPattern = new byte[] { 0xD1, 0xDC, 0x4B, 0x84, 0x34, 0x10, 0xD7, 0x73, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
byte[] LongHeaderPattern = [0xD1, 0xDC, 0x4B, 0x84, 0x34, 0x10, 0xD7, 0x73, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
|
||||||
byte[] LongHeaderMask = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
byte[] LongHeaderMask = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||||
|
|
||||||
if (ByteOperations.FindPattern(Binary, Offset, 4, new byte[] { 0x7F, 0x45, 0x4C, 0x46 }, new byte[] { 0x00, 0x00, 0x00, 0x00 }, null) == 0)
|
if (ByteOperations.FindPattern(Binary, Offset, 4, [0x7F, 0x45, 0x4C, 0x46], [0x00, 0x00, 0x00, 0x00], null) == 0)
|
||||||
{
|
{
|
||||||
// This is an ELF image
|
// This is an ELF image
|
||||||
// First program header is a reference to the elf-header
|
// First program header is a reference to the elf-header
|
||||||
@@ -128,46 +129,59 @@ namespace WPinternals
|
|||||||
CertificatesSize = ByteOperations.ReadUInt32(Binary, HeaderOffset + 0X1C);
|
CertificatesSize = ByteOperations.ReadUInt32(Binary, HeaderOffset + 0X1C);
|
||||||
CertificatesOffset = CertificatesAddress - ImageAddress + ImageOffset;
|
CertificatesOffset = CertificatesAddress - ImageAddress + ImageOffset;
|
||||||
|
|
||||||
uint CurrentCertificateOffset = CertificatesOffset;
|
using MemoryStream fileStream = new(Binary);
|
||||||
uint CertificateSize = 0;
|
using BinaryReader reader = new(fileStream);
|
||||||
while (CurrentCertificateOffset < (CertificatesOffset + CertificatesSize))
|
|
||||||
{
|
|
||||||
if ((Binary[CurrentCertificateOffset] == 0x30) && (Binary[CurrentCertificateOffset + 1] == 0x82))
|
|
||||||
{
|
|
||||||
CertificateSize = (uint)(Binary[CurrentCertificateOffset + 2] * 0x100) + Binary[CurrentCertificateOffset + 3] + 4; // Big endian!
|
|
||||||
|
|
||||||
if ((CurrentCertificateOffset + CertificateSize) == (CertificatesOffset + CertificatesSize))
|
List<byte[]> Signatures = [];
|
||||||
{
|
uint LastOffset = 0;
|
||||||
// This is the last certificate. So this is the root key.
|
|
||||||
RootKeyHash = new SHA256Managed().ComputeHash(Binary, (int)CurrentCertificateOffset, (int)CertificateSize);
|
|
||||||
|
|
||||||
#if DEBUG
|
for (uint i = 0; i < fileStream.Length - 6; i++)
|
||||||
System.Diagnostics.Debug.Print("RKH: " + Converter.ConvertHexToString(RootKeyHash, ""));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#if DEBUG
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Print("Cert: " + Converter.ConvertHexToString(new SHA256Managed().ComputeHash(Binary, (int)CurrentCertificateOffset, (int)CertificateSize), ""));
|
fileStream.Seek(i, SeekOrigin.Begin);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
CurrentCertificateOffset += CertificateSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((RootKeyHash == null) && (CurrentCertificateOffset > CertificatesOffset))
|
|
||||||
{
|
|
||||||
CurrentCertificateOffset -= CertificateSize;
|
|
||||||
|
|
||||||
// This is the last certificate. So this is the root key.
|
ushort offset0 = reader.ReadUInt16();
|
||||||
RootKeyHash = new SHA256Managed().ComputeHash(Binary, (int)CurrentCertificateOffset, (int)CertificateSize);
|
short offset1 = (short)((reader.ReadByte() << 8) | reader.ReadByte());
|
||||||
|
ushort offset2 = reader.ReadUInt16();
|
||||||
|
|
||||||
#if DEBUG
|
if (offset0 == 0x8230 && offset1 >= 0 && offset2 == 0x8230)
|
||||||
System.Diagnostics.Debug.Print("RKH: " + Converter.ConvertHexToString(RootKeyHash, ""));
|
{
|
||||||
#endif
|
uint CertificateSize = (uint)offset1 + 4; // Header Size is 4
|
||||||
}
|
|
||||||
|
bool IsCertificatePartOfExistingChain = LastOffset == 0 || LastOffset == i;
|
||||||
|
if (!IsCertificatePartOfExistingChain)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LastOffset = i + CertificateSize;
|
||||||
|
|
||||||
|
fileStream.Seek(i, SeekOrigin.Begin);
|
||||||
|
Signatures.Add(reader.ReadBytes((int)CertificateSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Signatures.Count > 0)
|
||||||
|
{
|
||||||
|
byte[] RootCertificate = Signatures[^1];
|
||||||
|
|
||||||
|
for (int i = 0; i < Signatures.Count; i++)
|
||||||
|
{
|
||||||
|
if (i + 1 != Signatures.Count)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
System.Diagnostics.Debug.Print("Cert: " + Converter.ConvertHexToString(SHA256.HashData(Signatures[i]), ""));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is the last certificate. So this is the root key.
|
||||||
|
RootKeyHash = SHA256.HashData(Signatures[i]);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
System.Diagnostics.Debug.Print("RKH: " + Converter.ConvertHexToString(RootKeyHash, ""));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,361 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal delegate void ReadyHandler();
|
||||||
|
|
||||||
|
internal class QualcommSahara
|
||||||
|
{
|
||||||
|
private readonly QualcommSerial Serial;
|
||||||
|
|
||||||
|
public QualcommSahara(QualcommSerial Serial)
|
||||||
|
{
|
||||||
|
Serial.EncodeCommands = false;
|
||||||
|
Serial.DecodeResponses = false;
|
||||||
|
this.Serial = Serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildCommandPacket(QualcommSaharaCommand SaharaCommand, byte[] CommandBuffer = null)
|
||||||
|
{
|
||||||
|
UInt32 CommandID = (uint)SaharaCommand;
|
||||||
|
UInt32 CommandBufferLength = 0;
|
||||||
|
if (CommandBuffer != null)
|
||||||
|
{
|
||||||
|
CommandBufferLength = (UInt32)CommandBuffer.Length;
|
||||||
|
}
|
||||||
|
UInt32 Length = 0x8u + CommandBufferLength;
|
||||||
|
|
||||||
|
byte[] Packet = new byte[Length];
|
||||||
|
ByteOperations.WriteUInt32(Packet, 0x00, CommandID);
|
||||||
|
ByteOperations.WriteUInt32(Packet, 0x04, Length);
|
||||||
|
|
||||||
|
if (CommandBuffer != null && CommandBufferLength != 0)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(CommandBuffer, 0, Packet, 0x08, CommandBuffer.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildHelloResponsePacket(QualcommSaharaMode SaharaMode, UInt32 ProtocolVersion = 2, UInt32 SupportedVersion = 1, UInt32 MaxPacketLength = 0 /* 0: Status OK */)
|
||||||
|
{
|
||||||
|
UInt32 Mode = (uint)SaharaMode;
|
||||||
|
|
||||||
|
// Hello packet:
|
||||||
|
// xxxxxxxx = Protocol version
|
||||||
|
// xxxxxxxx = Supported version
|
||||||
|
// xxxxxxxx = Max packet length
|
||||||
|
// xxxxxxxx = Expected mode
|
||||||
|
// 6 dwords reserved space
|
||||||
|
byte[] Hello = new byte[0x28];
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x00, ProtocolVersion);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x04, SupportedVersion);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x08, MaxPacketLength);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x0C, Mode);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x10, 0);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x14, 0);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x18, 0);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x1C, 0);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x20, 0);
|
||||||
|
ByteOperations.WriteUInt32(Hello, 0x24, 0);
|
||||||
|
|
||||||
|
return BuildCommandPacket(QualcommSaharaCommand.HelloResponse, Hello);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildExecuteRequestPacket(UInt32 RequestID)
|
||||||
|
{
|
||||||
|
byte[] Execute = new byte[0x04];
|
||||||
|
ByteOperations.WriteUInt32(Execute, 0x00, RequestID);
|
||||||
|
return BuildCommandPacket(QualcommSaharaCommand.ExecuteRequest, Execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] BuildExecuteDataPacket(UInt32 RequestID)
|
||||||
|
{
|
||||||
|
byte[] Execute = new byte[0x04];
|
||||||
|
ByteOperations.WriteUInt32(Execute, 0x00, RequestID);
|
||||||
|
return BuildCommandPacket(QualcommSaharaCommand.ExecuteData, Execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[][] GetRKHs()
|
||||||
|
{
|
||||||
|
Serial.SendData(BuildExecuteRequestPacket(0x3));
|
||||||
|
|
||||||
|
byte[] ReadDataRequest = Serial.GetResponse(null);
|
||||||
|
UInt32 ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
|
||||||
|
|
||||||
|
if (ResponseID != 0xE)
|
||||||
|
{
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint RKHLength = ByteOperations.ReadUInt32(ReadDataRequest, 0x0C);
|
||||||
|
|
||||||
|
Serial.SendData(BuildExecuteDataPacket(0x3));
|
||||||
|
|
||||||
|
byte[] Response = Serial.GetResponse(null, Length: (int)RKHLength);
|
||||||
|
|
||||||
|
List<byte[]> RootKeyHashes = new();
|
||||||
|
for (int i = 0; i < RKHLength / 0x20; i++)
|
||||||
|
{
|
||||||
|
RootKeyHashes.Add(Response[(i * 0x20)..((i + 1) * 0x20)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [.. RootKeyHashes];
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetRKH()
|
||||||
|
{
|
||||||
|
int Step = 0;
|
||||||
|
UInt32 Offset = 0;
|
||||||
|
UInt32 Length = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Step = 1;
|
||||||
|
byte[] Hello = Serial.GetResponse([0x01, 0x00, 0x00, 0x00]);
|
||||||
|
|
||||||
|
// Incoming Hello packet:
|
||||||
|
// 00000001 = Hello command id
|
||||||
|
// xxxxxxxx = Length
|
||||||
|
// xxxxxxxx = Protocol version
|
||||||
|
// xxxxxxxx = Supported version
|
||||||
|
// xxxxxxxx = Max packet length
|
||||||
|
// xxxxxxxx = Expected mode
|
||||||
|
// 6 dwords reserved space
|
||||||
|
LogFile.Log("Protocol: 0x" + ByteOperations.ReadUInt32(Hello, 0x08).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Supported: 0x" + ByteOperations.ReadUInt32(Hello, 0x0C).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
|
||||||
|
|
||||||
|
Step = 2;
|
||||||
|
byte[] HelloResponse = BuildHelloResponsePacket(QualcommSaharaMode.Command);
|
||||||
|
Serial.SendData(HelloResponse);
|
||||||
|
|
||||||
|
Step = 3;
|
||||||
|
byte[] ReadDataRequest = Serial.GetResponse(null);
|
||||||
|
UInt32 ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
|
||||||
|
|
||||||
|
if (ResponseID != 0xB)
|
||||||
|
{
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Step = 4;
|
||||||
|
byte[][] RKHs = GetRKHs();
|
||||||
|
return RKHs[0];
|
||||||
|
}
|
||||||
|
catch (Exception Ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(Ex, LogType.FileAndConsole, Step.ToString() + " 0x" + Offset.ToString("X8") + " 0x" + Length.ToString("X8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SendImage(string Path)
|
||||||
|
{
|
||||||
|
bool Result = true;
|
||||||
|
|
||||||
|
LogFile.Log("Sending programmer: " + Path, LogType.FileOnly);
|
||||||
|
|
||||||
|
int Step = 0;
|
||||||
|
UInt32 Offset = 0;
|
||||||
|
UInt32 Length = 0;
|
||||||
|
|
||||||
|
byte[] ImageBuffer = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Step = 1;
|
||||||
|
byte[] Hello = Serial.GetResponse([0x01, 0x00, 0x00, 0x00]);
|
||||||
|
|
||||||
|
// Incoming Hello packet:
|
||||||
|
// 00000001 = Hello command id
|
||||||
|
// xxxxxxxx = Length
|
||||||
|
// xxxxxxxx = Protocol version
|
||||||
|
// xxxxxxxx = Supported version
|
||||||
|
// xxxxxxxx = Max packet length
|
||||||
|
// xxxxxxxx = Expected mode
|
||||||
|
// 6 dwords reserved space
|
||||||
|
LogFile.Log("Protocol: 0x" + ByteOperations.ReadUInt32(Hello, 0x08).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Supported: 0x" + ByteOperations.ReadUInt32(Hello, 0x0C).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
|
||||||
|
|
||||||
|
Step = 2;
|
||||||
|
byte[] HelloResponse = BuildHelloResponsePacket(QualcommSaharaMode.ImageTransferPending);
|
||||||
|
Serial.SendData(HelloResponse);
|
||||||
|
|
||||||
|
Step = 3;
|
||||||
|
using FileStream FileStream = new(Path, FileMode.Open, FileAccess.Read);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Step = 4;
|
||||||
|
byte[] ReadDataRequest = Serial.GetResponse(null);
|
||||||
|
UInt32 ResponseID = ByteOperations.ReadUInt32(ReadDataRequest, 0);
|
||||||
|
if (ResponseID == 4)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ResponseID != 3)
|
||||||
|
{
|
||||||
|
Step = 5;
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = ByteOperations.ReadUInt32(ReadDataRequest, 0x0C);
|
||||||
|
Length = ByteOperations.ReadUInt32(ReadDataRequest, 0x10);
|
||||||
|
if ((ImageBuffer == null) || (ImageBuffer.Length != Length))
|
||||||
|
{
|
||||||
|
ImageBuffer = new byte[Length];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileStream.Position != Offset)
|
||||||
|
{
|
||||||
|
FileStream.Seek(Offset, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
Step = 6;
|
||||||
|
FileStream.Read(ImageBuffer, 0, (int)Length);
|
||||||
|
|
||||||
|
Step = 7;
|
||||||
|
Serial.SendData(ImageBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception Ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(Ex, LogType.FileAndConsole, Step.ToString() + " 0x" + Offset.ToString("X8") + " 0x" + Length.ToString("X8"));
|
||||||
|
Result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result)
|
||||||
|
{
|
||||||
|
LogFile.Log("Programmer loaded into phone memory", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Handshake()
|
||||||
|
{
|
||||||
|
bool Result = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] Hello = Serial.GetResponse([0x01, 0x00, 0x00, 0x00]);
|
||||||
|
|
||||||
|
// Incoming Hello packet:
|
||||||
|
// 00000001 = Hello command id
|
||||||
|
// xxxxxxxx = Length
|
||||||
|
// xxxxxxxx = Protocol version
|
||||||
|
// xxxxxxxx = Supported version
|
||||||
|
// xxxxxxxx = Max packet length
|
||||||
|
// xxxxxxxx = Expected mode
|
||||||
|
// 6 dwords reserved space
|
||||||
|
LogFile.Log("Protocol: 0x" + ByteOperations.ReadUInt32(Hello, 0x08).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Supported: 0x" + ByteOperations.ReadUInt32(Hello, 0x0C).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("MaxLength: 0x" + ByteOperations.ReadUInt32(Hello, 0x10).ToString("X8"), LogType.FileOnly);
|
||||||
|
LogFile.Log("Mode: 0x" + ByteOperations.ReadUInt32(Hello, 0x14).ToString("X8"), LogType.FileOnly);
|
||||||
|
|
||||||
|
byte[] HelloResponse = BuildHelloResponsePacket(QualcommSaharaMode.ImageTransferPending);
|
||||||
|
|
||||||
|
byte[] Ready = Serial.SendCommand(HelloResponse, [0x03, 0x00, 0x00, 0x00]);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetSahara()
|
||||||
|
{
|
||||||
|
Serial.SendCommand(BuildCommandPacket(QualcommSaharaCommand.ResetRequest), [0x08, 0x00, 0x00, 0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SwitchMode(QualcommSaharaMode Mode)
|
||||||
|
{
|
||||||
|
byte[] SwitchMode = new byte[0x04];
|
||||||
|
ByteOperations.WriteUInt32(SwitchMode, 0x00, (UInt32)Mode);
|
||||||
|
byte[] SwitchModeCommand = BuildCommandPacket(QualcommSaharaCommand.SwitchMode, SwitchMode);
|
||||||
|
|
||||||
|
byte[] ResponsePattern = null;
|
||||||
|
switch (Mode)
|
||||||
|
{
|
||||||
|
case QualcommSaharaMode.ImageTransferPending:
|
||||||
|
ResponsePattern = [0x04, 0x00, 0x00, 0x00];
|
||||||
|
break;
|
||||||
|
case QualcommSaharaMode.MemoryDebug:
|
||||||
|
ResponsePattern = [0x09, 0x00, 0x00, 0x00];
|
||||||
|
break;
|
||||||
|
case QualcommSaharaMode.Command:
|
||||||
|
ResponsePattern = [0x0B, 0x00, 0x00, 0x00];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Serial.SendCommand(SwitchModeCommand, ResponsePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartProgrammer()
|
||||||
|
{
|
||||||
|
LogFile.Log("Starting programmer", LogType.FileAndConsole);
|
||||||
|
byte[] DoneCommand = BuildCommandPacket(QualcommSaharaCommand.DoneRequest);
|
||||||
|
bool Started = false;
|
||||||
|
int count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] DoneResponse = Serial.SendCommand(DoneCommand, [0x06, 0x00, 0x00, 0x00]);
|
||||||
|
Started = true;
|
||||||
|
}
|
||||||
|
catch (BadConnectionException)
|
||||||
|
{
|
||||||
|
LogFile.Log("Problem while starting programmer. Attempting again.", LogType.FileAndConsole);
|
||||||
|
}
|
||||||
|
} while (!Started && count < 3);
|
||||||
|
if (count >= 3 && !Started)
|
||||||
|
{
|
||||||
|
LogFile.Log("Maximum number of attempts to start the programmer exceeded.", LogType.FileAndConsole);
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
LogFile.Log("Programmer being launched on phone", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> LoadProgrammer(string ProgrammerPath)
|
||||||
|
{
|
||||||
|
bool SendImageResult = await Task.Run(() => SendImage(ProgrammerPath));
|
||||||
|
if (!SendImageResult)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Run(() => StartProgrammer());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal enum QualcommSaharaCommand : uint
|
||||||
|
{
|
||||||
|
HelloRequest = 0x01,
|
||||||
|
HelloResponse = 0x02,
|
||||||
|
ReadData = 0x03,
|
||||||
|
EndTransfer = 0x04,
|
||||||
|
DoneRequest = 0x05,
|
||||||
|
DoneResponse = 0x06,
|
||||||
|
ResetRequest = 0x07,
|
||||||
|
ResetResponse = 0x08,
|
||||||
|
MemoryDebug = 0x09,
|
||||||
|
MemoryRead = 0x0A,
|
||||||
|
CommandReady = 0x0B,
|
||||||
|
SwitchMode = 0x0C,
|
||||||
|
ExecuteRequest = 0x0D,
|
||||||
|
ExecuteResponse = 0x0E,
|
||||||
|
ExecuteData = 0x0F,
|
||||||
|
MemoryDebug64 = 0x10,
|
||||||
|
MemoryRead64 = 0x11,
|
||||||
|
MemoryReadData64 = 0x12,
|
||||||
|
ResetStateMachineIdentifier = 0x13
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal enum QualcommSaharaMode : uint
|
||||||
|
{
|
||||||
|
ImageTransferPending = 0x00,
|
||||||
|
ImagetransferComplete = 0x01,
|
||||||
|
MemoryDebug = 0x02,
|
||||||
|
Command = 0x03
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -38,7 +38,7 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
CRC16 = new CRC16(0x1189, 0xFFFF, 0xFFFF);
|
CRC16 = new CRC16(0x1189, 0xFFFF, 0xFFFF);
|
||||||
|
|
||||||
string[] DevicePathElements = DevicePath.Split(new char[] { '#' });
|
string[] DevicePathElements = DevicePath.Split(['#']);
|
||||||
if (string.Equals(DevicePathElements[3], "{86E0D1E0-8089-11D0-9CE4-08003E301F73}", StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(DevicePathElements[3], "{86E0D1E0-8089-11D0-9CE4-08003E301F73}", StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
string PortName = (string)Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\" + DevicePathElements[1] + @"\" + DevicePathElements[2] + @"\Device Parameters", "PortName", null);
|
string PortName = (string)Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\" + DevicePathElements[1] + @"\" + DevicePathElements[2] + @"\Device Parameters", "PortName", null);
|
||||||
@@ -58,7 +58,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
this.USBDevice = new USBDevice(DevicePath);
|
this.USBDevice = new USBDevice(DevicePath);
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,10 +87,10 @@ namespace WPinternals
|
|||||||
return GetResponse(ResponsePattern);
|
return GetResponse(ResponsePattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal byte[] GetResponse(byte[] ResponsePattern)
|
internal byte[] GetResponse(byte[] ResponsePattern, int Length = 0x2000)
|
||||||
{
|
{
|
||||||
byte[] ResponseBuffer = new byte[0x2000];
|
byte[] ResponseBuffer = new byte[Length];
|
||||||
int Length = 0;
|
Length = 0;
|
||||||
bool IsIncomplete = false;
|
bool IsIncomplete = false;
|
||||||
|
|
||||||
do
|
do
|
||||||
@@ -146,7 +149,10 @@ namespace WPinternals
|
|||||||
{
|
{
|
||||||
IsIncomplete = true;
|
IsIncomplete = true;
|
||||||
}
|
}
|
||||||
catch { } // Will be rethrown as BadConnectionException
|
catch (Exception ex) // Will be rethrown as BadConnectionException
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (IsIncomplete);
|
while (IsIncomplete);
|
||||||
|
|
||||||
@@ -323,7 +329,7 @@ namespace WPinternals
|
|||||||
public class CRC16
|
public class CRC16
|
||||||
{
|
{
|
||||||
private readonly UInt16[] ChecksumTable =
|
private readonly UInt16[] ChecksumTable =
|
||||||
new UInt16[] {
|
[
|
||||||
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||||
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
||||||
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
||||||
@@ -356,7 +362,7 @@ namespace WPinternals
|
|||||||
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
||||||
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
||||||
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||||
};
|
];
|
||||||
|
|
||||||
private readonly UInt16 Seed, FinalXor;
|
private readonly UInt16 Seed, FinalXor;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -29,11 +29,11 @@ namespace WPinternals
|
|||||||
internal byte[] GenerateExtraSector(byte[] PartitionHeader)
|
internal byte[] GenerateExtraSector(byte[] PartitionHeader)
|
||||||
{
|
{
|
||||||
UInt32? Offset = ByteOperations.FindPattern(Binary,
|
UInt32? Offset = ByteOperations.FindPattern(Binary,
|
||||||
new byte[] {
|
[
|
||||||
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
}, null, null);
|
], null, null);
|
||||||
if (Offset == null)
|
if (Offset == null)
|
||||||
{
|
{
|
||||||
throw new BadImageFormatException();
|
throw new BadImageFormatException();
|
||||||
@@ -43,12 +43,12 @@ namespace WPinternals
|
|||||||
|
|
||||||
byte[] FoundPattern = new byte[0x10];
|
byte[] FoundPattern = new byte[0x10];
|
||||||
Offset = ByteOperations.FindPattern(Binary,
|
Offset = ByteOperations.FindPattern(Binary,
|
||||||
new byte[] {
|
[
|
||||||
0x04, 0x00, 0x9F, 0xE5, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF
|
0x04, 0x00, 0x9F, 0xE5, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
},
|
],
|
||||||
new byte[] {
|
[
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
|
||||||
},
|
],
|
||||||
FoundPattern);
|
FoundPattern);
|
||||||
if (Offset == null)
|
if (Offset == null)
|
||||||
{
|
{
|
||||||
@@ -59,14 +59,14 @@ namespace WPinternals
|
|||||||
UInt32 GlobalIsSecurityEnabledAddress = SharedMemoryAddress + 0x28;
|
UInt32 GlobalIsSecurityEnabledAddress = SharedMemoryAddress + 0x28;
|
||||||
|
|
||||||
Offset = ByteOperations.FindPattern(Binary,
|
Offset = ByteOperations.FindPattern(Binary,
|
||||||
new byte[] {
|
[
|
||||||
0x01, 0xFF, 0xA0, 0xE3, 0xFF, 0xFF, 0xA0, 0xE1, 0x1C, 0xD0, 0x8D, 0xE2, 0xF0, 0x4F, 0xBD, 0xE8,
|
0x01, 0xFF, 0xA0, 0xE3, 0xFF, 0xFF, 0xA0, 0xE1, 0x1C, 0xD0, 0x8D, 0xE2, 0xF0, 0x4F, 0xBD, 0xE8,
|
||||||
0x1E, 0xFF, 0x2F, 0xE1
|
0x1E, 0xFF, 0x2F, 0xE1
|
||||||
},
|
],
|
||||||
new byte[] {
|
[
|
||||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00
|
0x00, 0x00, 0x00, 0x00
|
||||||
},
|
],
|
||||||
null);
|
null);
|
||||||
if (Offset == null)
|
if (Offset == null)
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ namespace WPinternals
|
|||||||
byte[] Sector = new byte[0x200];
|
byte[] Sector = new byte[0x200];
|
||||||
Array.Clear(Sector, 0, 0x200);
|
Array.Clear(Sector, 0, 0x200);
|
||||||
|
|
||||||
byte[] Content = new byte[] {
|
byte[] Content = [
|
||||||
0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0xBD, 0x02, 0x00,
|
0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0xBD, 0x02, 0x00,
|
||||||
0xD8, 0x01, 0x00, 0x00, 0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0xD8, 0x01, 0x00, 0x00, 0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xE3, 0x3C, 0x10, 0x9F, 0xE5,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xE3, 0x3C, 0x10, 0x9F, 0xE5,
|
||||||
@@ -88,11 +88,11 @@ namespace WPinternals
|
|||||||
0x04, 0x10, 0x81, 0xE2, 0x03, 0x00, 0x50, 0xE1, 0xF9, 0xFF, 0xFF, 0xBA, 0x14, 0xF0, 0x9F, 0xE5,
|
0x04, 0x10, 0x81, 0xE2, 0x03, 0x00, 0x50, 0xE1, 0xF9, 0xFF, 0xFF, 0xBA, 0x14, 0xF0, 0x9F, 0xE5,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x90, 0xBF, 0x02, 0x00, 0xD0, 0xBF, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x90, 0xBF, 0x02, 0x00, 0xD0, 0xBF, 0x02, 0x00,
|
||||||
0xA0, 0xBD, 0x02, 0x00, 0xA0, 0xBE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
|
0xA0, 0xBD, 0x02, 0x00, 0xA0, 0xBE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
];
|
||||||
|
|
||||||
byte[] PartitionTypeGuid = new byte[] {
|
byte[] PartitionTypeGuid = [
|
||||||
0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74
|
0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74
|
||||||
};
|
];
|
||||||
|
|
||||||
Buffer.BlockCopy(Content, 0, Sector, 0, Content.Length);
|
Buffer.BlockCopy(Content, 0, Sector, 0, Content.Length);
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -35,12 +35,12 @@ namespace WPinternals
|
|||||||
internal byte[] Patch()
|
internal byte[] Patch()
|
||||||
{
|
{
|
||||||
UInt32? PatchOffset = ByteOperations.FindPattern(Binary,
|
UInt32? PatchOffset = ByteOperations.FindPattern(Binary,
|
||||||
new byte[] {
|
[
|
||||||
0xFF, 0xFF, 0xFF, 0xE3, 0x01, 0x0E, 0x42, 0xE3, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1
|
0xFF, 0xFF, 0xFF, 0xE3, 0x01, 0x0E, 0x42, 0xE3, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1
|
||||||
},
|
],
|
||||||
new byte[] {
|
[
|
||||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
},
|
],
|
||||||
null);
|
null);
|
||||||
|
|
||||||
if (PatchOffset == null)
|
if (PatchOffset == null)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -45,13 +45,16 @@ namespace WPinternals
|
|||||||
Binary = FFUFile.GetPartition("SBL3");
|
Binary = FFUFile.GetPartition("SBL3");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
// If not succeeded, then try to parse it as raw image
|
// If not succeeded, then try to parse it as raw image
|
||||||
if (Binary == null)
|
if (Binary == null)
|
||||||
{
|
{
|
||||||
byte[] SBL3Pattern = new byte[] { 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF };
|
byte[] SBL3Pattern = [0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF];
|
||||||
byte[] SBL3Mask = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
|
byte[] SBL3Mask = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF];
|
||||||
|
|
||||||
UInt32? Offset = ByteOperations.FindPatternInFile(FileName, SBL3Pattern, SBL3Mask, out byte[] SBL3Header);
|
UInt32? Offset = ByteOperations.FindPatternInFile(FileName, SBL3Pattern, SBL3Mask, out byte[] SBL3Header);
|
||||||
|
|
||||||
@@ -72,7 +75,7 @@ namespace WPinternals
|
|||||||
internal byte[] Patch()
|
internal byte[] Patch()
|
||||||
{
|
{
|
||||||
UInt32? PatchOffset = ByteOperations.FindPattern(Binary,
|
UInt32? PatchOffset = ByteOperations.FindPattern(Binary,
|
||||||
new byte[] { 0x04, 0x00, 0x9F, 0xE5, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1 },
|
[0x04, 0x00, 0x9F, 0xE5, 0x28, 0x00, 0xD0, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1],
|
||||||
null, null);
|
null, null);
|
||||||
|
|
||||||
if (PatchOffset == null)
|
if (PatchOffset == null)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
// Copyright (c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -256,7 +256,7 @@ namespace WPinternals
|
|||||||
// but the sections that are used in Windows Phone EFI's all have a header of 4 bytes.
|
// but the sections that are used in Windows Phone EFI's all have a header of 4 bytes.
|
||||||
if (SectionType == 0x15)
|
if (SectionType == 0x15)
|
||||||
{
|
{
|
||||||
CurrentEFI.Name = ByteOperations.ReadUnicodeString(DecompressedImage, DecompressedSectionHeaderOffset + 0x04, SectionSize - 0x04).TrimEnd(new char[] { (char)0, ' ' });
|
CurrentEFI.Name = ByteOperations.ReadUnicodeString(DecompressedImage, DecompressedSectionHeaderOffset + 0x04, SectionSize - 0x04).TrimEnd([(char)0, ' ']);
|
||||||
}
|
}
|
||||||
else if ((SectionType == 0x10) || (SectionType == 0x19))
|
else if ((SectionType == 0x10) || (SectionType == 0x19))
|
||||||
{
|
{
|
||||||
@@ -599,8 +599,8 @@ namespace WPinternals
|
|||||||
ClearEfiChecksum(SecurityDxe);
|
ClearEfiChecksum(SecurityDxe);
|
||||||
|
|
||||||
UInt32? PatchOffset = ByteOperations.FindPattern(SecurityDxe,
|
UInt32? PatchOffset = ByteOperations.FindPattern(SecurityDxe,
|
||||||
new byte[] { 0xF0, 0x41, 0x2D, 0xE9, 0xFF, 0xFF, 0xB0, 0xE1, 0x28, 0xD0, 0x4D, 0xE2, 0xFF, 0xFF, 0xA0, 0xE1, 0x00, 0x00, 0xFF, 0x13, 0x20, 0xFF, 0xA0, 0xE3 },
|
[0xF0, 0x41, 0x2D, 0xE9, 0xFF, 0xFF, 0xB0, 0xE1, 0x28, 0xD0, 0x4D, 0xE2, 0xFF, 0xFF, 0xA0, 0xE1, 0x00, 0x00, 0xFF, 0x13, 0x20, 0xFF, 0xA0, 0xE3],
|
||||||
new byte[] { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00 },
|
[0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00],
|
||||||
null);
|
null);
|
||||||
|
|
||||||
if (PatchOffset == null)
|
if (PatchOffset == null)
|
||||||
@@ -616,8 +616,8 @@ namespace WPinternals
|
|||||||
ClearEfiChecksum(SecurityServicesDxe);
|
ClearEfiChecksum(SecurityServicesDxe);
|
||||||
|
|
||||||
PatchOffset = ByteOperations.FindPattern(SecurityServicesDxe,
|
PatchOffset = ByteOperations.FindPattern(SecurityServicesDxe,
|
||||||
new byte[] { 0x10, 0xFF, 0xFF, 0xE5, 0x80, 0xFF, 0x10, 0xE3, 0xFF, 0xFF, 0xFF, 0x0A },
|
[0x10, 0xFF, 0xFF, 0xE5, 0x80, 0xFF, 0x10, 0xE3, 0xFF, 0xFF, 0xFF, 0x0A],
|
||||||
new byte[] { 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00 },
|
[0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00],
|
||||||
null);
|
null);
|
||||||
|
|
||||||
if (PatchOffset == null)
|
if (PatchOffset == null)
|
||||||
@@ -628,8 +628,8 @@ namespace WPinternals
|
|||||||
ByteOperations.WriteUInt8(SecurityServicesDxe, (UInt32)PatchOffset + 0x0B, 0xEA);
|
ByteOperations.WriteUInt8(SecurityServicesDxe, (UInt32)PatchOffset + 0x0B, 0xEA);
|
||||||
|
|
||||||
PatchOffset = ByteOperations.FindPattern(SecurityServicesDxe,
|
PatchOffset = ByteOperations.FindPattern(SecurityServicesDxe,
|
||||||
new byte[] { 0x11, 0xFF, 0xFF, 0xE5, 0x40, 0xFF, 0x10, 0xE3, 0xFF, 0xFF, 0xFF, 0x0A },
|
[0x11, 0xFF, 0xFF, 0xE5, 0x40, 0xFF, 0x10, 0xE3, 0xFF, 0xFF, 0xFF, 0x0A],
|
||||||
new byte[] { 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00 },
|
[0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00],
|
||||||
null);
|
null);
|
||||||
|
|
||||||
if (PatchOffset == null)
|
if (PatchOffset == null)
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaBootManagerAppModel : NokiaFlashModel
|
||||||
|
{
|
||||||
|
internal readonly LumiaBootManagerPhoneInfo BootManagerInfo = new();
|
||||||
|
|
||||||
|
internal enum SecureBootKeyType : byte
|
||||||
|
{
|
||||||
|
Retail = 0,
|
||||||
|
Engineering = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not valid commands
|
||||||
|
//
|
||||||
|
/* NOK */
|
||||||
|
private const string Signature = "NOK";
|
||||||
|
/* NOKX */
|
||||||
|
private const string ExtendedMessageSignature = $"{Signature}X";
|
||||||
|
/* NOKXB */
|
||||||
|
private const string LumiaBootManagerExtendedMessageSignature = $"{ExtendedMessageSignature}B";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normal commands
|
||||||
|
//
|
||||||
|
/* NOKA */
|
||||||
|
private const string ContinueBootSignature = $"{Signature}A";
|
||||||
|
/* NOKB */
|
||||||
|
private const string RPMBSignature = $"{Signature}B";
|
||||||
|
/* NOKC */
|
||||||
|
private const string BatteryStatusSignature = $"{Signature}C";
|
||||||
|
/* NOKD */
|
||||||
|
private const string DisableTimeoutsSignature = $"{Signature}D";
|
||||||
|
/* NOKI */
|
||||||
|
private const string HelloSignature = $"{Signature}I";
|
||||||
|
/* NOKM */
|
||||||
|
private const string RebootToMassStorageSignature = $"{Signature}M";
|
||||||
|
/* NOKP */
|
||||||
|
private const string RebootToPhoneInfoAppSignature = $"{Signature}P";
|
||||||
|
/* NOKR */
|
||||||
|
private const string RebootSignature = $"{Signature}R";
|
||||||
|
/* NOKS */
|
||||||
|
private const string RebootToFlashAppSignature = $"{Signature}S";
|
||||||
|
/* NOKT */
|
||||||
|
private const string GetGPTSignature = $"{Signature}T";
|
||||||
|
/* NOKV */
|
||||||
|
private const string InfoQuerySignature = $"{Signature}V";
|
||||||
|
/* NOKW */
|
||||||
|
private const string WriteBootFlagFileSignature = $"{Signature}W";
|
||||||
|
/* NOKY */
|
||||||
|
private const string MMOSStartCommandSignature = $"{Signature}Y";
|
||||||
|
/* NOKZ */
|
||||||
|
private const string ShutdownSignature = $"{Signature}Z";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lumia Boot Manager extended commands
|
||||||
|
//
|
||||||
|
/* NOKXBD */
|
||||||
|
private const string PlatformSecureBootEnableSignature = $"{LumiaBootManagerExtendedMessageSignature}D";
|
||||||
|
/* NOKXBH */
|
||||||
|
private const string WriteRootCertificateHashSignature = $"{LumiaBootManagerExtendedMessageSignature}H";
|
||||||
|
/* NOKXBK */
|
||||||
|
private const string UEFIKeysProvisionSignature = $"{LumiaBootManagerExtendedMessageSignature}K";
|
||||||
|
/* NOKXBR */
|
||||||
|
private const string ReadManufacturingStateSignature = $"{LumiaBootManagerExtendedMessageSignature}R";
|
||||||
|
/* NOKXBU */
|
||||||
|
private const string FlushVariablesSignature = $"{LumiaBootManagerExtendedMessageSignature}U";
|
||||||
|
/* NOKXBW */
|
||||||
|
private const string WriteManufacturingStateSignature = $"{LumiaBootManagerExtendedMessageSignature}W";
|
||||||
|
|
||||||
|
public LumiaBootManagerAppModel(string DevicePath) : base(DevicePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ContinueBoot()
|
||||||
|
{
|
||||||
|
LogFile.Log("Continue boot...");
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, ContinueBootSignature);
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LumiaBootManagerPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
bool PhoneInfoLogged = BootManagerInfo.State != PhoneInfoState.Empty;
|
||||||
|
ReadPhoneInfoBootManager();
|
||||||
|
|
||||||
|
LumiaBootManagerPhoneInfo Result = BootManagerInfo;
|
||||||
|
|
||||||
|
if (!PhoneInfoLogged)
|
||||||
|
{
|
||||||
|
Result.Log(LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LumiaBootManagerPhoneInfo ReadPhoneInfoBootManager()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
LumiaBootManagerPhoneInfo Result = BootManagerInfo;
|
||||||
|
|
||||||
|
if (Result.State == PhoneInfoState.Empty)
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
|
||||||
|
switch (Result.App)
|
||||||
|
{
|
||||||
|
case FlashAppType.BootManager:
|
||||||
|
Result.BootManagerProtocolVersionMajor = Response[6];
|
||||||
|
Result.BootManagerProtocolVersionMinor = Response[7];
|
||||||
|
Result.BootManagerVersionMajor = Response[8];
|
||||||
|
Result.BootManagerVersionMinor = Response[9];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SubblockCount = Response[10];
|
||||||
|
int SubblockOffset = 11;
|
||||||
|
|
||||||
|
for (int i = 0; i < SubblockCount; i++)
|
||||||
|
{
|
||||||
|
byte SubblockID = Response[SubblockOffset + 0x00];
|
||||||
|
|
||||||
|
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||||
|
|
||||||
|
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||||
|
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||||
|
byte SubblockVersion;
|
||||||
|
switch (SubblockID)
|
||||||
|
{
|
||||||
|
case 0x01:
|
||||||
|
Result.TransferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
Result.FlashAppProtocolVersionMajor = Response[SubblockPayloadOffset + 0x00];
|
||||||
|
Result.FlashAppProtocolVersionMinor = Response[SubblockPayloadOffset + 0x01];
|
||||||
|
Result.FlashAppVersionMajor = Response[SubblockPayloadOffset + 0x02];
|
||||||
|
Result.FlashAppVersionMinor = Response[SubblockPayloadOffset + 0x03];
|
||||||
|
break;
|
||||||
|
case 0x1F:
|
||||||
|
Result.MmosOverUsbSupported = Response[SubblockPayloadOffset] == 1;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
// CRC header info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubblockOffset += SubblockLength + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.State = PhoneInfoState.Basic;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal GPT ReadGPT()
|
||||||
|
{
|
||||||
|
// If this function is used with a locked BootMgr v1,
|
||||||
|
// then the mode-switching should be done outside this function,
|
||||||
|
// because the context-switches that are used here are not supported on BootMgr v1.
|
||||||
|
|
||||||
|
// Only works in BootLoader-mode or on unlocked bootloaders in Flash-mode!!
|
||||||
|
|
||||||
|
byte[] Request = new byte[0x04];
|
||||||
|
const string Header = GetGPTSignature;
|
||||||
|
|
||||||
|
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||||
|
|
||||||
|
byte[] Buffer = ExecuteRawMethod(Request);
|
||||||
|
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Unable to read GPT!");
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] GPTBuffer = new byte[Buffer.Length - 0x208];
|
||||||
|
System.Buffer.BlockCopy(Buffer, 0x208, GPTBuffer, 0, 0x4200);
|
||||||
|
|
||||||
|
return new GPT(GPTBuffer); // NOKT message header and MBR are ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
internal byte[] GetGptChunk(UInt32 Size) // TODO!
|
||||||
|
{
|
||||||
|
// This function is also used to generate a dummy chunk to flash for testing.
|
||||||
|
// The dummy chunk will contain the GPT, so it can be flashed to the first sectors for testing.
|
||||||
|
byte[] GPTChunk = new byte[Size];
|
||||||
|
|
||||||
|
byte[] Request = new byte[0x04];
|
||||||
|
const string Header = "NOKT";
|
||||||
|
|
||||||
|
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||||
|
|
||||||
|
byte[] Buffer = ExecuteRawMethod(Request);
|
||||||
|
if ((Buffer == null) || (Buffer.Length < 0x4408))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Unable to read GPT!");
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Buffer[6] << 8) + Buffer[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("ReadGPT: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
System.Buffer.BlockCopy(Buffer, 8, GPTChunk, 0, 0x4400);
|
||||||
|
|
||||||
|
return GPTChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ProvisionSecureBootKeys(SecureBootKeyType KeyType) // Only for Flashmode, not BootManager mode.
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[8];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, UEFIKeysProvisionSignature);
|
||||||
|
Request[6] = 0; // Options
|
||||||
|
Request[7] = (byte)KeyType;
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
UInt32 Status = ByteOperations.ReadUInt32(Response, 6);
|
||||||
|
if (Status != 0)
|
||||||
|
{
|
||||||
|
ThrowFlashError((int)Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowFlashError(int ErrorCode)
|
||||||
|
{
|
||||||
|
string SubMessage = ErrorCode switch
|
||||||
|
{
|
||||||
|
0x0008 => "Unsupported protocol / Invalid options",
|
||||||
|
0x000F => "Invalid sub block count",
|
||||||
|
0x0010 => "Invalid sub block length",
|
||||||
|
0x0012 => "Authentication required",
|
||||||
|
0x000E => "Invalid sub block type",
|
||||||
|
0x0013 => "Failed async message",
|
||||||
|
0x1000 => "Invalid header type",
|
||||||
|
0x1001 => "FFU header contain unknown extra data",
|
||||||
|
0x0001 => "Couldn't allocate memory",
|
||||||
|
0x1106 => "Security header validation failed",
|
||||||
|
0x1105 => "Invalid hash table size",
|
||||||
|
0x1104 => "Invalid catalog size",
|
||||||
|
0x1103 => "Invalid chunk size",
|
||||||
|
0x1102 => "Unsupported algorithm",
|
||||||
|
0x1101 => "Invalid struct size",
|
||||||
|
0x1100 => "Invalid signature",
|
||||||
|
0x1202 => "Invalid struct size",
|
||||||
|
0x1203 => "Unsupported algorithm",
|
||||||
|
0x1204 => "Invalid chunk size",
|
||||||
|
0x1005 => "Data not aligned correctly",
|
||||||
|
0x0009 => "Locate protocol failed",
|
||||||
|
0x1003 => "Hash mismatch",
|
||||||
|
0x1006 => "Couldn't find hash from security header for index",
|
||||||
|
0x1004 => "Security header import missing / All FFU headers have not been imported",
|
||||||
|
0x1304 => "Invalid platform ID",
|
||||||
|
0x1307 => "Invalid write descriptor info",
|
||||||
|
0x1306 => "Invalid write descriptor info",
|
||||||
|
0x1305 => "Invalid block size",
|
||||||
|
0x1303 => "Unsupported FFU version",
|
||||||
|
0x1302 => "Unsupported struct version",
|
||||||
|
0x1301 => "Invalid update type",
|
||||||
|
0x100B => "Too much payload data, all data has already been written",
|
||||||
|
0x1008 => "Internal error",
|
||||||
|
0x1007 => "Payload data does not contain all data",
|
||||||
|
0x0004 => "Flash write failed",
|
||||||
|
0x000D => "Flash verify failed",
|
||||||
|
0x0002 => "Flash read failed",
|
||||||
|
_ => "Unknown error",
|
||||||
|
};
|
||||||
|
WPinternalsException Ex = new("Flash failed!");
|
||||||
|
Ex.SubMessage = "Error 0x" + ErrorCode.ToString("X4") + ": " + SubMessage;
|
||||||
|
|
||||||
|
throw Ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
const string Header = ShutdownSignature;
|
||||||
|
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||||
|
ExecuteRawMethod(Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ResetPhone()
|
||||||
|
{
|
||||||
|
LogFile.Log("Rebooting phone", LogType.FileAndConsole);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, RebootSignature);
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
LogFile.Log("Sending reset-request failed", LogType.FileOnly);
|
||||||
|
LogFile.Log("Assuming automatic reset already in progress", LogType.FileOnly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ResetPhoneToFlashMode()
|
||||||
|
{
|
||||||
|
LumiaBootManagerPhoneInfo info = ReadPhoneInfoBootManager();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
||||||
|
|
||||||
|
// This only works when the phone is in BootMgr mode. If it is already in FlashApp, it will not reboot. It only makes the phone unresponsive.
|
||||||
|
LogFile.Log("Rebooting phone to Flash mode...");
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, RebootToFlashAppSignature);
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
info.App = FlashAppType.FlashApp;
|
||||||
|
|
||||||
|
RaiseInterfaceChanged(PhoneInterfaces.Lumia_Flash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SwitchToPhoneInfoAppContextLegacy()
|
||||||
|
{
|
||||||
|
LumiaBootManagerPhoneInfo info = ReadPhoneInfoBootManager();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, RebootToPhoneInfoAppSignature);
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
info.App = FlashAppType.PhoneInfoApp;
|
||||||
|
|
||||||
|
RaiseInterfaceChanged(PhoneInterfaces.Lumia_PhoneInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void RebootToFlashApp()
|
||||||
|
{
|
||||||
|
LumiaBootManagerPhoneInfo info = ReadPhoneInfoBootManager();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.BootManagerVersionMajor >= 2;
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, RebootToFlashAppSignature); // This will let the phone charge
|
||||||
|
ExecuteRawVoidMethod(Request); // On phone with bootloader Spec A this triggers a reboot, so DisableRebootTimeOut() cannot be called immediately.
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
info.App = FlashAppType.FlashApp;
|
||||||
|
|
||||||
|
RaiseInterfaceChanged(PhoneInterfaces.Lumia_Flash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class LumiaPhoneInfoAppModel : NokiaFlashModel
|
||||||
|
{
|
||||||
|
internal readonly LumiaPhoneInfoAppPhoneInfo PhoneInfoAppInfo = new();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not valid commands
|
||||||
|
//
|
||||||
|
/* NOK */
|
||||||
|
private const string Signature = "NOK";
|
||||||
|
/* NOKX */
|
||||||
|
private const string ExtendedMessageSignature = $"{Signature}X";
|
||||||
|
/* NOKXP */
|
||||||
|
private const string PhoneInfoAppExtendedMessageSignature = $"{ExtendedMessageSignature}P";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normal commands
|
||||||
|
//
|
||||||
|
/* NOKA */
|
||||||
|
private const string ContinueBootSignature = $"{Signature}A";
|
||||||
|
/* NOKD */
|
||||||
|
private const string DisableTimeoutsSignature = $"{Signature}D";
|
||||||
|
/* NOKH */
|
||||||
|
private const string GetPhoneInfoSignature = $"{Signature}H";
|
||||||
|
/* NOKI */
|
||||||
|
private const string HelloSignature = $"{Signature}I";
|
||||||
|
/* NOKV */
|
||||||
|
private const string InfoQuerySignature = $"{Signature}V";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Phone Info App extended commands
|
||||||
|
//
|
||||||
|
/* NOKXPH */
|
||||||
|
private const string GetVariableSignature = $"{PhoneInfoAppExtendedMessageSignature}H";
|
||||||
|
|
||||||
|
public LumiaPhoneInfoAppModel(string DevicePath) : base(DevicePath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ContinueBoot()
|
||||||
|
{
|
||||||
|
LogFile.Log("Continue boot...");
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, ContinueBootSignature);
|
||||||
|
ExecuteRawVoidMethod(Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string GetPhoneInfo()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
if (PhoneInfoAppInfo.PhoneInfoAppVersionMajor >= 2)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, GetPhoneInfoSignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Length = BigEndian.ToUInt16(Response, 0x04);
|
||||||
|
|
||||||
|
string PhoneInfoData = ByteOperations.ReadAsciiString(Response, 0x8, Length);
|
||||||
|
|
||||||
|
return PhoneInfoData;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LumiaPhoneInfoAppPhoneInfo ReadPhoneInfo(bool ExtendedInfo = true)
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
bool PhoneInfoLogged = PhoneInfoAppInfo.State != PhoneInfoState.Empty;
|
||||||
|
ReadPhoneInfoPhoneInfoApp();
|
||||||
|
|
||||||
|
LumiaPhoneInfoAppPhoneInfo Result = PhoneInfoAppInfo;
|
||||||
|
|
||||||
|
if (ExtendedInfo && (Result.State == PhoneInfoState.Basic))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Result.PhoneInfoAppProtocolVersionMajor >= 2)
|
||||||
|
{
|
||||||
|
Result.Type = ReadPhoneInfoVariable("TYPE");
|
||||||
|
Result.ProductCode = ReadPhoneInfoVariable("CTR");
|
||||||
|
Result.Imei = ReadPhoneInfoVariable("IMEI");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Version: 1.1.1.3
|
||||||
|
* TYPE: RM-885
|
||||||
|
* BTR: 059R0M0
|
||||||
|
* LPSN: ...
|
||||||
|
* HWID: 1000
|
||||||
|
* CTR: 059S4B1
|
||||||
|
* MC: 0205354
|
||||||
|
* IMEI: ...
|
||||||
|
*/
|
||||||
|
string PhoneInfoData = GetPhoneInfo();
|
||||||
|
if (!string.IsNullOrEmpty(PhoneInfoData))
|
||||||
|
{
|
||||||
|
string[] Variables = PhoneInfoData.Split("\n");
|
||||||
|
Dictionary<string, string> FormattedVariables = [];
|
||||||
|
foreach (string Variable in Variables)
|
||||||
|
{
|
||||||
|
if (!Variable.Contains(":"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormattedVariables.Add(Variable.Split(":")[0].Trim(), Variable.Split(":")[1].Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.Type = FormattedVariables["TYPE"];
|
||||||
|
Result.ProductCode = FormattedVariables["CTR"];
|
||||||
|
Result.Imei = FormattedVariables["IMEI"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFile.LogException(ex, LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.State = PhoneInfoState.Extended;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PhoneInfoLogged)
|
||||||
|
{
|
||||||
|
Result.Log(LogType.FileOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LumiaPhoneInfoAppPhoneInfo ReadPhoneInfoPhoneInfoApp()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
LumiaPhoneInfoAppPhoneInfo Result = PhoneInfoAppInfo;
|
||||||
|
|
||||||
|
if (Result.State == PhoneInfoState.Empty)
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
|
||||||
|
switch (Result.App)
|
||||||
|
{
|
||||||
|
case FlashAppType.PhoneInfoApp:
|
||||||
|
Result.PhoneInfoAppProtocolVersionMajor = Response[6];
|
||||||
|
Result.PhoneInfoAppProtocolVersionMinor = Response[7];
|
||||||
|
Result.PhoneInfoAppVersionMajor = Response[8];
|
||||||
|
Result.PhoneInfoAppVersionMinor = Response[9];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte SubblockCount = Response[10];
|
||||||
|
int SubblockOffset = 11;
|
||||||
|
|
||||||
|
for (int i = 0; i < SubblockCount; i++)
|
||||||
|
{
|
||||||
|
byte SubblockID = Response[SubblockOffset + 0x00];
|
||||||
|
|
||||||
|
LogFile.Log($"{Result.App} SubblockID: 0x{SubblockID:X}");
|
||||||
|
|
||||||
|
UInt16 SubblockLength = BigEndian.ToUInt16(Response, SubblockOffset + 0x01);
|
||||||
|
int SubblockPayloadOffset = SubblockOffset + 3;
|
||||||
|
byte SubblockVersion;
|
||||||
|
switch (SubblockID)
|
||||||
|
{
|
||||||
|
case 0x20:
|
||||||
|
// CRC header info
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SubblockOffset += SubblockLength + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.State = PhoneInfoState.Basic;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string ReadPhoneInfoVariable(string VariableName)
|
||||||
|
{
|
||||||
|
// This function assumes the phone is in Phone Info App context
|
||||||
|
|
||||||
|
byte[] Request = new byte[16];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, GetVariableSignature + VariableName + "\0"); // BTR or CTR, CTR is public ProductCode
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
UInt16 Length = BigEndian.ToUInt16(Response, 6);
|
||||||
|
return ByteOperations.ReadAsciiString(Response, 8, Length).Trim([' ', '\0']);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string ReadProductCode()
|
||||||
|
{
|
||||||
|
string Result = ReadPhoneInfoVariable("CTR");
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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;
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal delegate void InterfaceChangedHandler(PhoneInterfaces NewInterface, string DevicePath);
|
||||||
|
|
||||||
|
internal class NokiaFlashModel : NokiaPhoneModel
|
||||||
|
{
|
||||||
|
private string _devicePath;
|
||||||
|
|
||||||
|
private readonly CommonPhoneInfo CommonInfo = new();
|
||||||
|
|
||||||
|
internal event InterfaceChangedHandler InterfaceChanged = delegate { };
|
||||||
|
|
||||||
|
//
|
||||||
|
// Not valid commands
|
||||||
|
//
|
||||||
|
/* NOK */
|
||||||
|
private const string Signature = "NOK";
|
||||||
|
/* NOKX */
|
||||||
|
private const string ExtendedMessageSignature = $"{Signature}X";
|
||||||
|
/* NOKXC */
|
||||||
|
private const string CommonExtendedMessageSignature = $"{ExtendedMessageSignature}C";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Common extended commands
|
||||||
|
//
|
||||||
|
/* NOKXCB */
|
||||||
|
private const string SwitchModeSignature = $"{CommonExtendedMessageSignature}B";
|
||||||
|
/* NOKXCE */
|
||||||
|
private const string EchoSignature = $"{CommonExtendedMessageSignature}E";
|
||||||
|
|
||||||
|
public NokiaFlashModel(string DevicePath) : base(DevicePath)
|
||||||
|
{
|
||||||
|
_devicePath = DevicePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SwitchToBootManagerContext(bool DisableTimeOut = true)
|
||||||
|
{
|
||||||
|
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||||
|
|
||||||
|
byte[] Request = new byte[7];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}B");
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("SwitchToBootManagerContext: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
InterfaceChanged(PhoneInterfaces.Lumia_Bootloader, _devicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SwitchToPhoneInfoAppContext()
|
||||||
|
{
|
||||||
|
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||||
|
|
||||||
|
byte[] Request = new byte[7];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, SwitchModeSignature + "P");
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("SwitchToPhoneInfoAppContext: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
CommonInfo.App = FlashAppType.PhoneInfoApp;
|
||||||
|
|
||||||
|
InterfaceChanged(PhoneInterfaces.Lumia_PhoneInfo, _devicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SwitchToMmosContext()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[7];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}A");
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("SwitchToPhoneInfoAppContext: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SwitchToFlashAppContext()
|
||||||
|
{
|
||||||
|
CommonPhoneInfo info = ReadPhoneInfoCommon();
|
||||||
|
|
||||||
|
bool ModernFlashApp = info.VersionMajor >= 2;
|
||||||
|
|
||||||
|
byte[] Request = new byte[7];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, $"{SwitchModeSignature}F"); // This will stop charging the phone
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU")
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt16 Error = (UInt16)((Response[6] << 8) + Response[7]);
|
||||||
|
if (Error > 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("SwitchToFlashAppContext: Error 0x" + Error.ToString("X4"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ModernFlashApp)
|
||||||
|
{
|
||||||
|
DisableRebootTimeOut();
|
||||||
|
|
||||||
|
InterfaceChanged(PhoneInterfaces.Lumia_Flash, _devicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Normal commands
|
||||||
|
//
|
||||||
|
/* NOKD */
|
||||||
|
private const string DisableTimeoutsSignature = $"{Signature}D";
|
||||||
|
/* NOKI */
|
||||||
|
private const string HelloSignature = $"{Signature}I";
|
||||||
|
/* NOKV */
|
||||||
|
private const string InfoQuerySignature = $"{Signature}V";
|
||||||
|
|
||||||
|
internal FlashAppType GetFlashAppType()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response == null) || (ByteOperations.ReadAsciiString(Response, 0, 4) == "NOKU"))
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FlashAppType)Response[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal CommonPhoneInfo ReadPhoneInfoCommon()
|
||||||
|
{
|
||||||
|
// NOKH = Get Phone Info (IMEI and info from Product.dat) - Not available on some phones, like Lumia 640.
|
||||||
|
// NOKV = Info Query
|
||||||
|
|
||||||
|
CommonPhoneInfo Result = CommonInfo;
|
||||||
|
|
||||||
|
if (Result.State == PhoneInfoState.Empty)
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, InfoQuerySignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if ((Response != null) && (ByteOperations.ReadAsciiString(Response, 0, 4) != "NOKU"))
|
||||||
|
{
|
||||||
|
Result.App = (FlashAppType)Response[5];
|
||||||
|
Result.ProtocolVersionMajor = Response[6];
|
||||||
|
Result.ProtocolVersionMinor = Response[7];
|
||||||
|
Result.VersionMajor = Response[8];
|
||||||
|
Result.VersionMinor = Response[9];
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.State = PhoneInfoState.Basic;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableRebootTimeOut()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
const string Header = DisableTimeoutsSignature;
|
||||||
|
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||||
|
ExecuteRawMethod(Request);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Hello()
|
||||||
|
{
|
||||||
|
byte[] Request = new byte[4];
|
||||||
|
ByteOperations.WriteAsciiString(Request, 0, HelloSignature);
|
||||||
|
byte[] Response = ExecuteRawMethod(Request);
|
||||||
|
if (Response == null)
|
||||||
|
{
|
||||||
|
throw new BadConnectionException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ByteOperations.ReadAsciiString(Response, 0, 4) != HelloSignature)
|
||||||
|
{
|
||||||
|
throw new WPinternalsException("Bad response from phone!", "The phone did not answer properly to the Hello message sent.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void RaiseInterfaceChanged(PhoneInterfaces NewInterface)
|
||||||
|
{
|
||||||
|
InterfaceChanged(NewInterface, _devicePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 2018, Rene Lergner - @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.
|
||||||
|
|
||||||
|
namespace WPinternals
|
||||||
|
{
|
||||||
|
internal class UefiSecurityStatusResponse
|
||||||
|
{
|
||||||
|
public byte IsTestDevice;
|
||||||
|
public bool PlatformSecureBootStatus;
|
||||||
|
public bool SecureFfuEfuseStatus;
|
||||||
|
public bool DebugStatus;
|
||||||
|
public bool RdcStatus;
|
||||||
|
public bool AuthenticationStatus;
|
||||||
|
public bool UefiSecureBootStatus;
|
||||||
|
public bool CryptoHardwareKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Copyright(c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
Copyright(c) 2018, Rene Lergner - @Heathcliff74xda
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files(the "Software"),
|
copy of this software and associated documentation files(the "Software"),
|
||||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
@@ -10,7 +10,7 @@ using System.Windows;
|
|||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
[assembly: AssemblyProduct("WPinternals")]
|
[assembly: AssemblyProduct("WPinternals")]
|
||||||
[assembly: AssemblyCopyright("Copyright © 2018-2019")]
|
[assembly: AssemblyCopyright("Copyright © 2018-2023")]
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
@@ -47,5 +47,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("2.9.*")]
|
[assembly: AssemblyVersion("3.0.*")]
|
||||||
// [assembly: AssemblyFileVersion("1.0.0.0")]
|
// [assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||