mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-17 21:00:10 +10:00
Implement Qualcomm Sahara VIP and fix a few bugs
* Qualcomm Sahara VIP * Project Cleanup * Allow unlocking an already unlocked phone
This commit is contained in:
+11
-16
@@ -48,7 +48,7 @@ namespace WPinternals
|
||||
Array.Clear(ByteArray, (int)Offset, (int)MaxBufferLength);
|
||||
}
|
||||
|
||||
byte[] TextBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(Text);
|
||||
byte[] TextBytes = System.Text.Encoding.ASCII.GetBytes(Text);
|
||||
int WriteLength = TextBytes.Length;
|
||||
if (WriteLength > MaxBufferLength)
|
||||
{
|
||||
@@ -65,7 +65,7 @@ namespace WPinternals
|
||||
Array.Clear(ByteArray, (int)Offset, (int)MaxBufferLength);
|
||||
}
|
||||
|
||||
byte[] TextBytes = System.Text.UnicodeEncoding.Unicode.GetBytes(Text);
|
||||
byte[] TextBytes = System.Text.Encoding.Unicode.GetBytes(Text);
|
||||
int WriteLength = TextBytes.Length;
|
||||
if (WriteLength > MaxBufferLength)
|
||||
{
|
||||
@@ -82,7 +82,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteUInt32(byte[] ByteArray, UInt32 Offset, UInt32 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 4);
|
||||
}
|
||||
|
||||
internal static Int32 ReadInt32(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -92,7 +92,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteInt32(byte[] ByteArray, UInt32 Offset, Int32 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 4);
|
||||
}
|
||||
|
||||
internal static UInt16 ReadUInt16(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -102,7 +102,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteUInt16(byte[] ByteArray, UInt32 Offset, UInt16 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 2);
|
||||
}
|
||||
|
||||
internal static Int16 ReadInt16(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -112,7 +112,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteInt16(byte[] ByteArray, UInt32 Offset, Int16 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 2);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 2);
|
||||
}
|
||||
|
||||
internal static byte ReadUInt8(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -132,7 +132,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteUInt24(byte[] ByteArray, UInt32 Offset, UInt32 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 3);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 3);
|
||||
}
|
||||
|
||||
internal static UInt64 ReadUInt64(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -142,7 +142,7 @@ namespace WPinternals
|
||||
|
||||
internal static void WriteUInt64(byte[] ByteArray, UInt32 Offset, UInt64 Value)
|
||||
{
|
||||
System.Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 8);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Value), 0, ByteArray, (int)Offset, 8);
|
||||
}
|
||||
|
||||
internal static Guid ReadGuid(byte[] ByteArray, UInt32 Offset)
|
||||
@@ -241,12 +241,12 @@ namespace WPinternals
|
||||
|
||||
internal static UInt32? FindAscii(byte[] SourceBuffer, string Pattern)
|
||||
{
|
||||
return FindPattern(SourceBuffer, System.Text.ASCIIEncoding.ASCII.GetBytes(Pattern), null, null);
|
||||
return FindPattern(SourceBuffer, System.Text.Encoding.ASCII.GetBytes(Pattern), null, null);
|
||||
}
|
||||
|
||||
internal static UInt32? FindUnicode(byte[] SourceBuffer, string Pattern)
|
||||
{
|
||||
return FindPattern(SourceBuffer, System.Text.UnicodeEncoding.Unicode.GetBytes(Pattern), null, null);
|
||||
return FindPattern(SourceBuffer, System.Text.Encoding.Unicode.GetBytes(Pattern), null, null);
|
||||
}
|
||||
|
||||
internal static UInt32? FindUint(byte[] SourceBuffer, UInt32 Pattern)
|
||||
@@ -296,7 +296,7 @@ namespace WPinternals
|
||||
|
||||
if (OutPattern != null)
|
||||
{
|
||||
System.Buffer.BlockCopy(SourceBuffer, (int)SearchPosition, OutPattern, 0, Pattern.Length);
|
||||
Buffer.BlockCopy(SourceBuffer, (int)SearchPosition, OutPattern, 0, Pattern.Length);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -394,11 +394,6 @@ namespace WPinternals
|
||||
}
|
||||
crc = (uint)(crc ^ (-1));
|
||||
|
||||
if (crc < 0)
|
||||
{
|
||||
crc += (uint)4294967296;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-14
@@ -110,12 +110,9 @@ namespace WPinternals
|
||||
DiskAccessMethod = ByteOperations.ReadInt32(StoreHeader, (UInt32)(WriteDescriptorEntryOffset + 0x08 + (j * 0x08)));
|
||||
ChunkIndex = ByteOperations.ReadInt32(StoreHeader, (UInt32)(WriteDescriptorEntryOffset + 0x0C + (j * 0x08)));
|
||||
|
||||
if (DiskAccessMethod == 0) // 0 = From begin, 2 = From end. We ignore chunks at end of disk. These contain secondairy GPT.
|
||||
if (DiskAccessMethod == 0 && (ChunkIndex + ChunkCount - 1) > HighestChunkIndex) // 0 = From begin, 2 = From end. We ignore chunks at end of disk. These contain secondairy GPT.
|
||||
{
|
||||
if ((ChunkIndex + ChunkCount - 1) > HighestChunkIndex)
|
||||
{
|
||||
HighestChunkIndex = ChunkIndex + ChunkCount - 1;
|
||||
}
|
||||
HighestChunkIndex = ChunkIndex + ChunkCount - 1;
|
||||
}
|
||||
}
|
||||
WriteDescriptorEntryOffset += 8 + (LocationCount * 0x08);
|
||||
@@ -183,7 +180,7 @@ namespace WPinternals
|
||||
byte[] Signature = new byte[0x10];
|
||||
FFUFile.Read(Signature, 0, 0x10);
|
||||
|
||||
Result = (ByteOperations.ReadAsciiString(Signature, 0x04, 0x0C) == "SignedImage ");
|
||||
Result = ByteOperations.ReadAsciiString(Signature, 0x04, 0x0C) == "SignedImage ";
|
||||
|
||||
FFUFile.Close();
|
||||
|
||||
@@ -214,12 +211,9 @@ namespace WPinternals
|
||||
{
|
||||
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/2e67ca57-3556-4275-accd-58b7df30d424/unnecessary-filestreamseek-and-setting-filestreamposition-has-huge-effect-on-performance?forum=csharpgeneral
|
||||
|
||||
if (FFUFile != null)
|
||||
if (FFUFile != null && FFUFile.Position != Position)
|
||||
{
|
||||
if (FFUFile.Position != Position)
|
||||
{
|
||||
FFUFile.Seek(Position, SeekOrigin.Begin);
|
||||
}
|
||||
FFUFile.Seek(Position, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +233,7 @@ namespace WPinternals
|
||||
{
|
||||
if ((Size % ChunkSize) > 0)
|
||||
{
|
||||
return (UInt32)((Size / ChunkSize) * ChunkSize);
|
||||
return (UInt32)(Size / ChunkSize * ChunkSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -292,7 +286,7 @@ namespace WPinternals
|
||||
|
||||
internal byte[] GetPartition(string Name)
|
||||
{
|
||||
Partition Target = GPT.Partitions.Find(p => (string.Compare(p.Name, Name, true) == 0));
|
||||
Partition Target = GPT.Partitions.Find(p => string.Equals(p.Name, Name, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Target == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -318,7 +312,7 @@ namespace WPinternals
|
||||
|
||||
private void WritePartition(string Name, string FilePath, Action<int, TimeSpan?> ProgressUpdateCallback, ProgressUpdater UpdaterPerSector, bool Compress = false)
|
||||
{
|
||||
Partition Target = GPT.Partitions.Find(p => (string.Compare(p.Name, Name, true) == 0));
|
||||
Partition Target = GPT.Partitions.Find(p => string.Equals(p.Name, Name, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (Target == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
+15
-18
@@ -96,16 +96,16 @@ namespace WPinternals
|
||||
|
||||
internal Partition GetPartition(string Name)
|
||||
{
|
||||
return Partitions.Find(p => (string.Compare(p.Name, Name, true) == 0));
|
||||
return Partitions.Find(p => string.Equals(p.Name, Name, StringComparison.CurrentCultureIgnoreCase));
|
||||
}
|
||||
|
||||
// Magic!
|
||||
// SecureBoot hack for Bootloader Spec A starts here
|
||||
internal byte[] InsertHack()
|
||||
{
|
||||
Partition HackPartition = Partitions.Find(p => (p.Name == "HACK"));
|
||||
Partition SBL1 = Partitions.Find(p => (p.Name == "SBL1"));
|
||||
Partition SBL2 = Partitions.Find(p => (p.Name == "SBL2"));
|
||||
Partition HackPartition = Partitions.Find(p => p.Name == "HACK");
|
||||
Partition SBL1 = Partitions.Find(p => p.Name == "SBL1");
|
||||
Partition SBL2 = Partitions.Find(p => p.Name == "SBL2");
|
||||
|
||||
if ((SBL1 == null) || (SBL2 == null))
|
||||
{
|
||||
@@ -140,9 +140,9 @@ namespace WPinternals
|
||||
|
||||
internal byte[] RemoveHack()
|
||||
{
|
||||
Partition HackPartition = Partitions.Find(p => (p.Name == "HACK"));
|
||||
Partition SBL1 = Partitions.Find(p => (p.Name == "SBL1"));
|
||||
Partition SBL2 = Partitions.Find(p => (p.Name == "SBL2"));
|
||||
Partition HackPartition = Partitions.Find(p => p.Name == "HACK");
|
||||
Partition SBL1 = Partitions.Find(p => p.Name == "SBL1");
|
||||
Partition SBL2 = Partitions.Find(p => p.Name == "SBL2");
|
||||
|
||||
if ((SBL1 == null) || (SBL2 == null))
|
||||
{
|
||||
@@ -227,7 +227,7 @@ namespace WPinternals
|
||||
{
|
||||
foreach (Partition NewPartition in GptToMerge.Partitions)
|
||||
{
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => ((string.Compare(e.Name, NewPartition.Name, true) == 0) || (e.Name.StartsWith(NewPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")))));
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => string.Equals(e.Name, NewPartition.Name, StringComparison.CurrentCultureIgnoreCase) || e.Name.StartsWith(NewPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")));
|
||||
if (Entry == null)
|
||||
{
|
||||
// There is a partition entry in the xml, but this partition is not present in the archive.
|
||||
@@ -342,7 +342,7 @@ namespace WPinternals
|
||||
Partition OldPartition = SortedPartitions.ElementAt(i);
|
||||
|
||||
// Present in archive?
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => ((string.Compare(e.Name, OldPartition.Name, true) == 0) || (e.Name.StartsWith(OldPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")))));
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => string.Equals(e.Name, OldPartition.Name, StringComparison.CurrentCultureIgnoreCase) || e.Name.StartsWith(OldPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")));
|
||||
if (Entry != null)
|
||||
{
|
||||
// Not present in new GPT or present in GPT without FirstSector?
|
||||
@@ -378,7 +378,7 @@ namespace WPinternals
|
||||
foreach (Partition NewPartition in GptToMerge.Partitions)
|
||||
{
|
||||
// If the new partition is a dynamic partition, then skip it here. It will be added later.
|
||||
if (DynamicPartitions.Select(p => p.Name).Any(n => string.Compare(n, NewPartition.Name, true) == 0))
|
||||
if (DynamicPartitions.Select(p => p.Name).Any(n => string.Equals(n, NewPartition.Name, StringComparison.CurrentCultureIgnoreCase)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -448,13 +448,10 @@ namespace WPinternals
|
||||
|
||||
for (int i = this.Partitions.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (this.Partitions[i] != CurrentPartition)
|
||||
if (this.Partitions[i] != CurrentPartition && (CurrentPartition.FirstSector <= this.Partitions[i].LastSector) && (CurrentPartition.LastSector >= this.Partitions[i].FirstSector))
|
||||
{
|
||||
if ((CurrentPartition.FirstSector <= this.Partitions[i].LastSector) && (CurrentPartition.LastSector >= this.Partitions[i].FirstSector))
|
||||
{
|
||||
this.Partitions.RemoveAt(i);
|
||||
HasChanged = true;
|
||||
}
|
||||
this.Partitions.RemoveAt(i);
|
||||
HasChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,7 +462,7 @@ namespace WPinternals
|
||||
// Check if the sizes of the partitions in the archive do not exceed the size of the partition, as listed in the GPT.
|
||||
foreach (Partition OldPartition in this.Partitions)
|
||||
{
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => ((string.Compare(e.Name, OldPartition.Name, true) == 0) || (e.Name.StartsWith(OldPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")))));
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => string.Equals(e.Name, OldPartition.Name, StringComparison.CurrentCultureIgnoreCase) || e.Name.StartsWith(OldPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")));
|
||||
if (Entry != null)
|
||||
{
|
||||
DecompressedStream DecompressedStream = new(Entry.Open());
|
||||
@@ -517,7 +514,7 @@ namespace WPinternals
|
||||
NewPartition.FirstSector = FirstFreeSector;
|
||||
HasChanged = true;
|
||||
}
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => ((string.Compare(e.Name, NewPartition.Name, true) == 0) || (e.Name.StartsWith(NewPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")))));
|
||||
ZipArchiveEntry Entry = Archive.Entries.FirstOrDefault(e => string.Equals(e.Name, NewPartition.Name, StringComparison.CurrentCultureIgnoreCase) || e.Name.StartsWith(NewPartition.Name + ".", true, System.Globalization.CultureInfo.GetCultureInfo("en-US")));
|
||||
DecompressedStream DecompressedStream = new(Entry.Open());
|
||||
ulong StreamLengthInSectors = (ulong)Entry.Length / 0x200;
|
||||
try
|
||||
|
||||
+3
-3
@@ -246,15 +246,15 @@ namespace WPinternals
|
||||
BufferSize -= b.Length;
|
||||
Monitor.Pulse(BufferQueue);
|
||||
|
||||
BytesRead += (b.Length - BufferOffset);
|
||||
BytesRead += b.Length - BufferOffset;
|
||||
BufferOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(b, BufferOffset, buffer, offset + BytesRead, count - BytesRead);
|
||||
|
||||
BufferOffset += (count - BytesRead);
|
||||
BytesRead += (count - BytesRead);
|
||||
BufferOffset += count - BytesRead;
|
||||
BytesRead += count - BytesRead;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -51,23 +51,23 @@ namespace WPinternals
|
||||
{
|
||||
foreach (ManagementObject drive in partition.GetRelated("Win32_DiskDrive"))
|
||||
{
|
||||
if ((drive["PNPDeviceID"].ToString().Contains("VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.CurrentCulture)) ||
|
||||
(drive["PNPDeviceID"].ToString().Contains("VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.CurrentCulture)))
|
||||
if (drive["PNPDeviceID"].ToString().Contains("VEN_QUALCOMM&PROD_MMC_STORAGE", StringComparison.CurrentCulture) ||
|
||||
drive["PNPDeviceID"].ToString().Contains("VEN_MSFT&PROD_PHONE_MMC_STOR", StringComparison.CurrentCulture))
|
||||
{
|
||||
Label = (logical["VolumeName"] == null ? "" : logical["VolumeName"].ToString());
|
||||
if ((Drive == null) || (string.Compare(Label, "MainOS", true) == 0)) // Always prefer the MainOS drive-mapping
|
||||
Label = logical["VolumeName"] == null ? "" : logical["VolumeName"].ToString();
|
||||
if ((Drive == null) || string.Equals(Label, "MainOS", StringComparison.CurrentCultureIgnoreCase)) // Always prefer the MainOS drive-mapping
|
||||
{
|
||||
Drive = logical["Name"].ToString();
|
||||
PhysicalDrive = drive["DeviceID"].ToString();
|
||||
VolumeLabel = Label;
|
||||
}
|
||||
if (string.Compare(Label, "MainOS", true) == 0)
|
||||
if (string.Equals(Label, "MainOS", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (string.Compare(Label, "MainOS", true) == 0)
|
||||
if (string.Equals(Label, "MainOS", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -188,7 +188,7 @@ namespace WPinternals
|
||||
|
||||
internal bool IsVolumeOpen()
|
||||
{
|
||||
return (int)(hVolume) != -1;
|
||||
return (int)hVolume != -1;
|
||||
}
|
||||
|
||||
internal void CloseVolume()
|
||||
|
||||
@@ -212,12 +212,12 @@ namespace WPinternals
|
||||
internal const uint FILE_SHARE_DELETE = 0x00000004;
|
||||
internal const uint OPEN_EXISTING = 3;
|
||||
|
||||
internal const uint GENERIC_READ = (0x80000000);
|
||||
internal const uint GENERIC_WRITE = (0x40000000);
|
||||
internal const uint GENERIC_READ = 0x80000000;
|
||||
internal const uint GENERIC_WRITE = 0x40000000;
|
||||
|
||||
internal const uint FILE_FLAG_WRITE_THROUGH = 0x80000000;
|
||||
internal const uint FILE_FLAG_NO_BUFFERING = 0x20000000;
|
||||
internal const uint FILE_READ_ATTRIBUTES = (0x0080);
|
||||
internal const uint FILE_READ_ATTRIBUTES = 0x0080;
|
||||
internal const uint FILE_WRITE_ATTRIBUTES = 0x0100;
|
||||
internal const uint ERROR_INSUFFICIENT_BUFFER = 122;
|
||||
internal const uint FILE_BEGIN = 0;
|
||||
|
||||
+68
-67
@@ -33,6 +33,7 @@ namespace WPinternals
|
||||
ProtocolAsyncV3 = 16
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum FlashOptions : byte
|
||||
{
|
||||
SkipWrite = 1,
|
||||
@@ -57,8 +58,8 @@ namespace WPinternals
|
||||
byte[] Request = new byte[0x0B];
|
||||
const string Header = "NOKXFR";
|
||||
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Param), 0, Request, 7, Param.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Param), 0, Request, 7, Param.Length);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
if ((Response == null) || (Response.Length < 0x10))
|
||||
@@ -67,7 +68,7 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
byte[] Result = new byte[Response[0x10]];
|
||||
System.Buffer.BlockCopy(Response, 0x11, Result, 0, Response[0x10]);
|
||||
Buffer.BlockCopy(Response, 0x11, Result, 0, Response[0x10]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -79,7 +80,7 @@ namespace WPinternals
|
||||
return null;
|
||||
}
|
||||
|
||||
return System.Text.ASCIIEncoding.ASCII.GetString(Bytes).Trim(new char[] { '\0' });
|
||||
return System.Text.Encoding.ASCII.GetString(Bytes).Trim(new char[] { '\0' });
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -195,12 +196,12 @@ namespace WPinternals
|
||||
byte[] AsskMask = new byte[0x10] { 1, 0, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64 };
|
||||
byte[] Request = new byte[0xAC];
|
||||
const string Header = "NOKXFT";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Request[7] = 1;
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x18, 4), 0, Request, 0x08, 4); // Subblocktype = 0x18
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x9C, 4), 0, Request, 0x0C, 4); // Subblocklength = 0x9C
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x00, 4), 0, Request, 0x10, 4); // AsicIndex = 0x00
|
||||
System.Buffer.BlockCopy(AsskMask, 0, Request, 0x14, 0x10);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x18, 4), 0, Request, 0x08, 4); // Subblocktype = 0x18
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x9C, 4), 0, Request, 0x0C, 4); // Subblocklength = 0x9C
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x00, 4), 0, Request, 0x10, 4); // AsicIndex = 0x00
|
||||
Buffer.BlockCopy(AsskMask, 0, Request, 0x14, 0x10);
|
||||
byte[] TerminalResponse = ExecuteRawMethod(Request);
|
||||
if ((TerminalResponse?.Length > 0x20) && (BigEndian.ToUInt32(TerminalResponse, 0x14) == (TerminalResponse.Length - 0x18)) && (BitConverter.ToUInt32(TerminalResponse, 0x1C) == (TerminalResponse.Length - 0x20)))
|
||||
{
|
||||
@@ -219,14 +220,14 @@ namespace WPinternals
|
||||
byte[] Request = new byte[FfuHeader.Length + 0x20];
|
||||
|
||||
const string Header = "NOKXFS";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0001, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0001, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Request[0x08] = 0; // Progress = 0%
|
||||
Request[0x0B] = 1; // Subblock count = 1
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0000000B, 4), 0, Request, 0x0C, 4); // Subblock type for header = 0x0B
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length + 0x0C, 4), 0, Request, 0x10, 4); // Subblock length = length of header + 0x0C
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x00000000, 4), 0, Request, 0x14, 4); // Header type = 0
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length, 4), 0, Request, 0x18, 4); // Payload length = length of header
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0000000B, 4), 0, Request, 0x0C, 4); // Subblock type for header = 0x0B
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length + 0x0C, 4), 0, Request, 0x10, 4); // Subblock length = length of header + 0x0C
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x00000000, 4), 0, Request, 0x14, 4); // Header type = 0
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length, 4), 0, Request, 0x18, 4); // Payload length = length of header
|
||||
Request[0x1C] = Options; // Header options = 0
|
||||
|
||||
Buffer.BlockCopy(FfuHeader, 0, Request, 0x20, FfuHeader.Length);
|
||||
@@ -249,20 +250,20 @@ namespace WPinternals
|
||||
byte[] Request = new byte[FfuHeader.Length + 0x3C];
|
||||
|
||||
const string Header = "NOKXFS";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV2, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV2, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Request[0x08] = 0; // Progress = 0%
|
||||
Request[0x0B] = 1; // Subblock count = 1
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x00000021, 4), 0, Request, 0x0C, 4); // Subblock type for header v2 = 0x21
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length + 0x28, 4), 0, Request, 0x10, 4); // Subblock starts at 0x14, payload starts at 0x3C.
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x00000021, 4), 0, Request, 0x0C, 4); // Subblock type for header v2 = 0x21
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length + 0x28, 4), 0, Request, 0x10, 4); // Subblock starts at 0x14, payload starts at 0x3C.
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x00000000, 4), 0, Request, 0x14, 4); // Header type = 0
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(TotalHeaderLength, 4), 0, Request, 0x18, 4); // Payload length = length of header
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x00000000, 4), 0, Request, 0x14, 4); // Header type = 0
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(TotalHeaderLength, 4), 0, Request, 0x18, 4); // Payload length = length of header
|
||||
Request[0x1C] = Options; // Header options = 0
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(OffsetForThisPart, 4), 0, Request, 0x1D, 4);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length, 4), 0, Request, 0x21, 4);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(OffsetForThisPart, 4), 0, Request, 0x1D, 4);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuHeader.Length, 4), 0, Request, 0x21, 4);
|
||||
Request[0x25] = 0; // No Erase
|
||||
|
||||
Buffer.BlockCopy(FfuHeader, 0, Request, 0x3C, FfuHeader.Length);
|
||||
@@ -290,15 +291,15 @@ namespace WPinternals
|
||||
byte[] Request = new byte[FfuChunk.Length + 0x1C];
|
||||
|
||||
const string Header = "NOKXFS";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV1, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV1, 2), 0, Request, 0x06, 2); // Protocol version = 0x0001
|
||||
Request[0x08] = (byte)Progress; // Progress = 0% (0 - 100)
|
||||
Request[0x0B] = 1; // Subblock count = 1
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0000000C, 4), 0, Request, 0x0C, 4); // Subblock type for ChunkData = 0x0C
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x08, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0000000C, 4), 0, Request, 0x0C, 4); // Subblock type for ChunkData = 0x0C
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x08, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Request[0x18] = Options; // Data options = 0 (1 = verify)
|
||||
|
||||
Buffer.BlockCopy(FfuChunk, 0, Request, 0x1C, FfuChunk.Length);
|
||||
@@ -321,15 +322,15 @@ namespace WPinternals
|
||||
byte[] Request = new byte[FfuChunk.Length + 0x20];
|
||||
|
||||
const string Header = "NOKXFS";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV2, 2), 0, Request, 0x06, 2); // Protocol
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolSyncV2, 2), 0, Request, 0x06, 2); // Protocol
|
||||
Request[0x08] = (byte)Progress; // Progress = 0% (0 - 100)
|
||||
Request[0x0B] = 1; // Subblock count = 1
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0000001B, 4), 0, Request, 0x0C, 4); // Subblock type for Payload v2 = 0x1B
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x0C, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0000001B, 4), 0, Request, 0x0C, 4); // Subblock type for Payload v2 = 0x1B
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x0C, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Request[0x18] = Options; // Data options = 0 (1 = verify)
|
||||
|
||||
Buffer.BlockCopy(FfuChunk, 0, Request, 0x20, FfuChunk.Length);
|
||||
@@ -352,18 +353,18 @@ namespace WPinternals
|
||||
byte[] Request = new byte[FfuChunk.Length + 0x20];
|
||||
|
||||
const string Header = "NOKXFS";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolAsyncV3, 2), 0, Request, 0x06, 2); // Protocol
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes((int)FfuProtocol.ProtocolAsyncV3, 2), 0, Request, 0x06, 2); // Protocol
|
||||
Request[0x08] = (byte)Progress; // Progress = 0% (0 - 100)
|
||||
Request[0x0B] = 1; // Subblock count = 1
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0000001D, 4), 0, Request, 0x0C, 4); // Subblock type for Payload v2 = 0x1B
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x2C, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0000001D, 4), 0, Request, 0x0C, 4); // Subblock type for Payload v2 = 0x1B
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length + 0x2C, 4), 0, Request, 0x10, 4); // Subblock length = length of chunk + 0x08
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(FfuChunk.Length, 4), 0, Request, 0x14, 4); // Payload length = length of chunk
|
||||
Request[0x18] = Options; // Data options = 0 (1 = verify)
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(WriteDescriptorIndex, 4), 0, Request, 0x19, 4); // Payload length = length of chunk
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(CRC, 4), 0, Request, 0x1D, 4); // Payload length = length of chunk
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(WriteDescriptorIndex, 4), 0, Request, 0x19, 4); // Payload length = length of chunk
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(CRC, 4), 0, Request, 0x1D, 4); // Payload length = length of chunk
|
||||
|
||||
Buffer.BlockCopy(FfuChunk, 0, Request, 0x40, FfuChunk.Length);
|
||||
|
||||
@@ -387,11 +388,11 @@ namespace WPinternals
|
||||
{
|
||||
byte[] Request = new byte[84];
|
||||
const string Header = "NOKXFB";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Request[0x07] = 1; // Subblock count = 1
|
||||
Request[0x08] = 6; // Subblock ID = 6 = Create Partition Backup to RAM
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(73, 2), 0, Request, 0x09, 2); // Subblock length = Length of data in subblock including fillers (subblock-ID-field and subblock-length-field are not counted for the subblock-length)
|
||||
System.Text.UnicodeEncoding.Unicode.GetBytes(PartitionName);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(73, 2), 0, Request, 0x09, 2); // Subblock length = Length of data in subblock including fillers (subblock-ID-field and subblock-length-field are not counted for the subblock-length)
|
||||
System.Text.Encoding.Unicode.GetBytes(PartitionName);
|
||||
|
||||
byte[] PartitionBytes = System.Text.Encoding.Unicode.GetBytes(PartitionName);
|
||||
Buffer.BlockCopy(PartitionBytes, 0, Request, 0x0C, PartitionBytes.Length);
|
||||
@@ -415,18 +416,18 @@ namespace WPinternals
|
||||
{
|
||||
byte[] Request = new byte[MmosPart.Length + 0x20];
|
||||
const string Header = "NOKXFL";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Request[0x07] = 1; // Subblock count = 1
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(0x0000001E, 4), 0, Request, 0x08, 4); // Subblock ID = Load MMOS Binary = 0x1E
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(MmosPart.Length + 0x10, 4), 0, Request, 0x0C, 4); // Subblock length = Payload-length + 0x10
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(TotalLength, 4), 0, Request, 0x10, 4);
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(Offset, 4), 0, Request, 0x14, 4);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(0x0000001E, 4), 0, Request, 0x08, 4); // Subblock ID = Load MMOS Binary = 0x1E
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(MmosPart.Length + 0x10, 4), 0, Request, 0x0C, 4); // Subblock length = Payload-length + 0x10
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(TotalLength, 4), 0, Request, 0x10, 4);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(Offset, 4), 0, Request, 0x14, 4);
|
||||
if (SkipMmosSupportCheck)
|
||||
{
|
||||
Request[0x18] = 1;
|
||||
}
|
||||
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(MmosPart.Length, 4), 0, Request, 0x1C, 4);
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(MmosPart.Length, 4), 0, Request, 0x1C, 4);
|
||||
Buffer.BlockCopy(MmosPart, 0, Request, 0x20, MmosPart.Length);
|
||||
|
||||
byte[] Response = ExecuteRawMethod(Request);
|
||||
@@ -521,7 +522,7 @@ namespace WPinternals
|
||||
|
||||
UInt64 CombinedFFUHeaderSize = FFU.HeaderSize;
|
||||
byte[] FfuHeader = new byte[CombinedFFUHeaderSize];
|
||||
using (FileStream FfuFile = new(FFU.Path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||
using (FileStream FfuFile = new(FFU.Path, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
FfuFile.Read(FfuHeader, 0, (int)CombinedFFUHeaderSize);
|
||||
SendFfuHeaderV1(FfuHeader, Options);
|
||||
@@ -597,7 +598,7 @@ namespace WPinternals
|
||||
|
||||
uint totalcounts = (uint)Math.Truncate((decimal)length / maximumbuffersize);
|
||||
|
||||
using (FileStream MMOSFile = new(MMOSPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||
using (FileStream MMOSFile = new(MMOSPath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
for (int i = 1; i <= (uint)Math.Truncate((decimal)length / maximumbuffersize); i++)
|
||||
{
|
||||
@@ -633,10 +634,10 @@ namespace WPinternals
|
||||
byte[] Request = new byte[Data.Length + 0x40];
|
||||
|
||||
const string Header = "NOKF";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Request[0x05] = 0; // Device type = 0
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(StartSector, 4), 0, Request, 0x0B, 4); // Start sector
|
||||
System.Buffer.BlockCopy(BigEndian.GetBytes(Data.Length / 0x200, 4), 0, Request, 0x0F, 4); // Sector count
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(StartSector, 4), 0, Request, 0x0B, 4); // Start sector
|
||||
Buffer.BlockCopy(BigEndian.GetBytes(Data.Length / 0x200, 4), 0, Request, 0x0F, 4); // Sector count
|
||||
Request[0x13] = (byte)Progress; // Progress (0 - 100)
|
||||
Request[0x18] = 0; // Do Verify
|
||||
Request[0x19] = 0; // Is Test
|
||||
@@ -650,7 +651,7 @@ namespace WPinternals
|
||||
{
|
||||
byte[] Request = new byte[4];
|
||||
const string Header = "NOKD";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
ExecuteRawMethod(Request);
|
||||
}
|
||||
|
||||
@@ -658,7 +659,7 @@ namespace WPinternals
|
||||
{
|
||||
byte[] Request = new byte[4];
|
||||
const string Header = "NOKZ";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
ExecuteRawMethod(Request);
|
||||
}
|
||||
|
||||
@@ -690,7 +691,7 @@ namespace WPinternals
|
||||
|
||||
PhoneInfo Info = ReadPhoneInfo(ExtendedInfo: false);
|
||||
FlashAppType OriginalAppType = Info.App;
|
||||
bool Switch = ((Info.App != FlashAppType.BootManager) && Info.IsBootloaderSecure);
|
||||
bool Switch = (Info.App != FlashAppType.BootManager) && Info.IsBootloaderSecure;
|
||||
if (Switch)
|
||||
{
|
||||
SwitchToBootManagerContext();
|
||||
@@ -871,7 +872,7 @@ namespace WPinternals
|
||||
|
||||
byte[] Request = new byte[0x50];
|
||||
const string Header = "NOKXFP";
|
||||
System.Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Buffer.BlockCopy(System.Text.Encoding.ASCII.GetBytes(Header), 0, Request, 0, Header.Length);
|
||||
Request[0x06] = 1; // Protocol version must be 1
|
||||
Request[0x07] = 0; // Device type = 0
|
||||
|
||||
@@ -950,7 +951,7 @@ namespace WPinternals
|
||||
Result.TransferSize = BigEndian.ToUInt32(Response, SubblockPayloadOffset);
|
||||
break;
|
||||
case 0x1F:
|
||||
Result.MmosOverUsbSupported = (Response[SubblockPayloadOffset] == 1);
|
||||
Result.MmosOverUsbSupported = Response[SubblockPayloadOffset] == 1;
|
||||
break;
|
||||
case 0x04:
|
||||
if (Result.App == FlashAppType.BootManager)
|
||||
@@ -975,17 +976,17 @@ namespace WPinternals
|
||||
Result.PlatformID = ByteOperations.ReadAsciiString(Response, (uint)SubblockPayloadOffset, SubblockLength).Trim(new char[] { ' ', '\0' });
|
||||
break;
|
||||
case 0x0D:
|
||||
Result.AsyncSupport = (Response[SubblockPayloadOffset + 1] == 1);
|
||||
Result.AsyncSupport = Response[SubblockPayloadOffset + 1] == 1;
|
||||
break;
|
||||
case 0x0F:
|
||||
SubblockVersion = Response[SubblockPayloadOffset]; // 0x03
|
||||
Result.PlatformSecureBootEnabled = (Response[SubblockPayloadOffset + 0x01] == 0x01);
|
||||
Result.SecureFfuEnabled = (Response[SubblockPayloadOffset + 0x02] == 0x01);
|
||||
Result.JtagDisabled = (Response[SubblockPayloadOffset + 0x03] == 0x01);
|
||||
Result.RdcPresent = (Response[SubblockPayloadOffset + 0x04] == 0x01);
|
||||
Result.Authenticated = ((Response[SubblockPayloadOffset + 0x05] == 0x01) || (Response[SubblockPayloadOffset + 0x05] == 0x02));
|
||||
Result.UefiSecureBootEnabled = (Response[SubblockPayloadOffset + 0x06] == 0x01);
|
||||
Result.SecondaryHardwareKeyPresent = (Response[SubblockPayloadOffset + 0x07] == 0x01);
|
||||
Result.PlatformSecureBootEnabled = Response[SubblockPayloadOffset + 0x01] == 0x01;
|
||||
Result.SecureFfuEnabled = Response[SubblockPayloadOffset + 0x02] == 0x01;
|
||||
Result.JtagDisabled = Response[SubblockPayloadOffset + 0x03] == 0x01;
|
||||
Result.RdcPresent = Response[SubblockPayloadOffset + 0x04] == 0x01;
|
||||
Result.Authenticated = (Response[SubblockPayloadOffset + 0x05] == 0x01) || (Response[SubblockPayloadOffset + 0x05] == 0x02);
|
||||
Result.UefiSecureBootEnabled = Response[SubblockPayloadOffset + 0x06] == 0x01;
|
||||
Result.SecondaryHardwareKeyPresent = Response[SubblockPayloadOffset + 0x07] == 0x01;
|
||||
break;
|
||||
case 0x10:
|
||||
SubblockVersion = Response[SubblockPayloadOffset]; // 0x01
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace WPinternals
|
||||
Length = Device.InputPipe.Read(Buffer);
|
||||
}
|
||||
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.ASCIIEncoding.ASCII.GetString(Buffer, 0, Length));
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.Encoding.ASCII.GetString(Buffer, 0, Length));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -298,7 +298,7 @@ namespace WPinternals
|
||||
{
|
||||
Length = Device.InputPipe.EndRead(AsyncResultRead);
|
||||
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.ASCIIEncoding.ASCII.GetString(Buffer, 0, Length));
|
||||
JsonDocument ResultMessage = JsonDocument.Parse(System.Text.Encoding.ASCII.GetString(Buffer, 0, Length));
|
||||
|
||||
JsonElement? ResultToken = ResultMessage.RootElement.GetProperty("result");
|
||||
if ((ResultToken == null) || (ResultElement == null))
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace WPinternals
|
||||
LogFile.Log("Attempt patch: " + PatchDefinition);
|
||||
|
||||
// Find a matching TargetVersion
|
||||
PatchDefinition Definition = PatchDefinitions.Single(d => string.Compare(d.Name, PatchDefinition, true) == 0);
|
||||
PatchDefinition Definition = PatchDefinitions.Single(d => string.Equals(d.Name, PatchDefinition, StringComparison.CurrentCultureIgnoreCase));
|
||||
TargetVersion MatchedVersion = null;
|
||||
int VersionIndex = 0;
|
||||
foreach (TargetVersion CurrentVersion in Definition.TargetVersions)
|
||||
@@ -146,7 +146,7 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
// Lookup file
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Compare(f.FilePath, TargetPath, true) == 0);
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Equals(f.FilePath, TargetPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (CurrentFile == null)
|
||||
{
|
||||
CurrentFile = (TargetImage != null) && (!TargetPath.Contains(':'))
|
||||
@@ -196,7 +196,7 @@ namespace WPinternals
|
||||
|
||||
foreach (TargetFile CurrentTargetFile in MatchedVersion.TargetFiles)
|
||||
{
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Compare(f.FilePath, Path.Combine(TargetPath + "\\", CurrentTargetFile.Path), true) == 0);
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Equals(f.FilePath, Path.Combine(TargetPath + "\\", CurrentTargetFile.Path), StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (!StructuralComparisons.StructuralEqualityComparer.Equals(CurrentFile.Hash, CurrentTargetFile.HashPatched))
|
||||
{
|
||||
@@ -242,7 +242,7 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
// Find a matching TargetVersion
|
||||
PatchDefinition Definition = PatchDefinitions.Single(d => string.Compare(d.Name, PatchDefinition, true) == 0);
|
||||
PatchDefinition Definition = PatchDefinitions.Single(d => string.Equals(d.Name, PatchDefinition, StringComparison.CurrentCultureIgnoreCase));
|
||||
TargetVersion MatchedVersion = null;
|
||||
foreach (TargetVersion CurrentVersion in Definition.TargetVersions)
|
||||
{
|
||||
@@ -266,7 +266,7 @@ namespace WPinternals
|
||||
}
|
||||
|
||||
// Lookup file
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Compare(f.FilePath, TargetPath, true) == 0);
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Equals(f.FilePath, TargetPath, StringComparison.CurrentCultureIgnoreCase));
|
||||
if (CurrentFile == null)
|
||||
{
|
||||
CurrentFile = new FilePatcher(TargetPath);
|
||||
@@ -306,7 +306,7 @@ namespace WPinternals
|
||||
{
|
||||
foreach (TargetFile CurrentTargetFile in MatchedVersion.TargetFiles)
|
||||
{
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Compare(f.FilePath, Path.Combine(TargetPath, CurrentTargetFile.Path), true) == 0);
|
||||
FilePatcher CurrentFile = LoadedFiles.SingleOrDefault(f => string.Equals(f.FilePath, Path.Combine(TargetPath, CurrentTargetFile.Path), StringComparison.CurrentCultureIgnoreCase));
|
||||
|
||||
if (!StructuralComparisons.StructuralEqualityComparer.Equals(CurrentFile.Hash, CurrentTargetFile.HashOriginal))
|
||||
{
|
||||
|
||||
+14
-23
@@ -186,16 +186,13 @@ namespace WPinternals
|
||||
{
|
||||
lock (syncRoot)
|
||||
{
|
||||
if (processHandle.IsInvalid)
|
||||
{
|
||||
if (!NativeMethods.OpenProcessToken(
|
||||
if (processHandle.IsInvalid && !NativeMethods.OpenProcessToken(
|
||||
NativeMethods.GetCurrentProcess(),
|
||||
TokenAccessLevels.Duplicate,
|
||||
ref processHandle))
|
||||
{
|
||||
cachingError = Marshal.GetLastWin32Error();
|
||||
success = false;
|
||||
}
|
||||
{
|
||||
cachingError = Marshal.GetLastWin32Error();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,15 +234,12 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (!NativeMethods.SetThreadToken(
|
||||
if (success && !NativeMethods.SetThreadToken(
|
||||
IntPtr.Zero,
|
||||
this.threadHandle))
|
||||
{
|
||||
error = Marshal.GetLastWin32Error();
|
||||
success = false;
|
||||
}
|
||||
{
|
||||
error = Marshal.GetLastWin32Error();
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
@@ -424,7 +418,7 @@ namespace WPinternals
|
||||
NativeMethods.TOKEN_PRIVILEGE newState = new();
|
||||
newState.PrivilegeCount = 1;
|
||||
newState.Privilege.Luid = this.luid;
|
||||
newState.Privilege.Attributes = (this.initialState ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED);
|
||||
newState.Privilege.Attributes = this.initialState ? NativeMethods.SE_PRIVILEGE_ENABLED : NativeMethods.SE_PRIVILEGE_DISABLED;
|
||||
|
||||
NativeMethods.TOKEN_PRIVILEGE previousState = new();
|
||||
uint previousSize = 0;
|
||||
@@ -578,11 +572,11 @@ namespace WPinternals
|
||||
{
|
||||
// This is the initial state that revert will have to go back to
|
||||
|
||||
this.initialState = ((previousState.Privilege.Attributes & NativeMethods.SE_PRIVILEGE_ENABLED) != 0);
|
||||
this.initialState = (previousState.Privilege.Attributes & NativeMethods.SE_PRIVILEGE_ENABLED) != 0;
|
||||
|
||||
// Remember whether state has changed at all
|
||||
|
||||
this.stateWasChanged = (this.initialState != enable);
|
||||
this.stateWasChanged = this.initialState != enable;
|
||||
|
||||
// If we had to impersonate, or if the privilege state changed we'll need to revert
|
||||
|
||||
@@ -630,13 +624,10 @@ namespace WPinternals
|
||||
this.initialState = false;
|
||||
this.needToRevert = false;
|
||||
|
||||
if (this.tlsContents != null)
|
||||
if (this.tlsContents?.DecrementReferenceCount() == 0)
|
||||
{
|
||||
if (this.tlsContents.DecrementReferenceCount() == 0)
|
||||
{
|
||||
this.tlsContents = null;
|
||||
Thread.SetData(tlsSlot, null);
|
||||
}
|
||||
this.tlsContents = null;
|
||||
Thread.SetData(tlsSlot, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace WPinternals
|
||||
|
||||
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 });
|
||||
|
||||
CurrentAddress += CurrentLength;
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace WPinternals
|
||||
// We expect the user to know what he is doing in such case and we will ignore checks
|
||||
if (!StructuralComparisons.StructuralEqualityComparer.Equals(RootKeyHash, new byte[RootKeyHash.Length]))
|
||||
{
|
||||
if ((StructuralComparisons.StructuralEqualityComparer.Equals(Loader.RootKeyHash, RootKeyHash))
|
||||
if (StructuralComparisons.StructuralEqualityComparer.Equals(Loader.RootKeyHash, RootKeyHash)
|
||||
&& (ByteOperations.FindUnicode(Loader.Binary, "QHSUSB_ARMPRG") != null)) // To detect that this is a loader, and not SBL1 or something. V1 loaders are QHSUSB_ARMPRG. V2 loaders are QHSUSB__BULK. Only V1 supported for now, because V2 only accepts signed payload.
|
||||
{
|
||||
Result.Add(Loader);
|
||||
|
||||
+269
-16
@@ -19,6 +19,11 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WPinternals
|
||||
@@ -90,7 +95,7 @@ namespace WPinternals
|
||||
Serial.SendData(HelloResponse);
|
||||
|
||||
Step = 3;
|
||||
using System.IO.FileStream FileStream = new(Path, System.IO.FileMode.Open, System.IO.FileAccess.Read);
|
||||
using FileStream FileStream = new(Path, FileMode.Open, FileAccess.Read);
|
||||
while (true)
|
||||
{
|
||||
Step = 4;
|
||||
@@ -116,7 +121,7 @@ namespace WPinternals
|
||||
|
||||
if (FileStream.Position != Offset)
|
||||
{
|
||||
FileStream.Seek(Offset, System.IO.SeekOrigin.Begin);
|
||||
FileStream.Seek(Offset, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
Step = 6;
|
||||
@@ -182,7 +187,7 @@ namespace WPinternals
|
||||
Serial.SendCommand(new byte[] { 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 }, new byte[] { 0x08, 0x00, 0x00, 0x00 });
|
||||
}
|
||||
|
||||
public bool ConnectToProgrammerInTestMode()
|
||||
public bool ConnectToProgrammer(byte[] PacketFromPcToProgrammer)
|
||||
{
|
||||
// Behaviour of old firehose:
|
||||
// Takes about 20 ms to be started.
|
||||
@@ -198,12 +203,6 @@ namespace WPinternals
|
||||
// When sending succeeds, an answer should be incoming immediately to complete the handshake.
|
||||
// When an incoming Hello was received, the phone still expects to receive another Hello.
|
||||
|
||||
byte[] HelloPacketFromPcToProgrammer = new byte[0x20C];
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0, 0x57503730);
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0x28, 0x57503730);
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0x208, 0x57503730);
|
||||
ByteOperations.WriteUInt16(HelloPacketFromPcToProgrammer, 0x48, 0x4445);
|
||||
|
||||
int HelloSendCount = 0;
|
||||
bool HandshakeCompleted = false;
|
||||
string Incoming;
|
||||
@@ -214,7 +213,7 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
LogFile.Log("Send Hello to programmer (" + HelloSendCount.ToString() + ")", LogType.FileOnly);
|
||||
Serial.SendData(HelloPacketFromPcToProgrammer);
|
||||
Serial.SendData(PacketFromPcToProgrammer);
|
||||
LogFile.Log("Hello packet accepted", LogType.FileOnly);
|
||||
}
|
||||
catch
|
||||
@@ -225,29 +224,50 @@ namespace WPinternals
|
||||
try
|
||||
{
|
||||
Serial.SetTimeOut(500);
|
||||
Incoming = System.Text.Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
Incoming = Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
LogFile.Log("In: " + Incoming, LogType.FileOnly);
|
||||
Serial.SetTimeOut(200);
|
||||
if (Incoming.Contains("Chip serial num"))
|
||||
{
|
||||
Incoming = System.Text.Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
Incoming = Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
LogFile.Log("In: " + Incoming, LogType.FileOnly);
|
||||
LogFile.Log("Incoming Hello-packets received", LogType.FileOnly);
|
||||
}
|
||||
|
||||
while (Incoming.IndexOf("response value") < 0)
|
||||
{
|
||||
Incoming = System.Text.Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
Incoming = Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
LogFile.Log("In: " + Incoming, LogType.FileOnly);
|
||||
}
|
||||
|
||||
LogFile.Log("Incoming Hello-response received", LogType.FileOnly);
|
||||
HandshakeCompleted = true;
|
||||
|
||||
if (!Incoming.Contains("Failed to authenticate Digital Signature."))
|
||||
{
|
||||
HandshakeCompleted = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Programmer failed to authenticate Digital Signature", LogType.FileOnly);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
while (!HandshakeCompleted && (HelloSendCount < 6));
|
||||
|
||||
return HandshakeCompleted;
|
||||
}
|
||||
|
||||
public bool ConnectToProgrammerInTestMode()
|
||||
{
|
||||
byte[] HelloPacketFromPcToProgrammer = new byte[0x20C];
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0, 0x57503730);
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0x28, 0x57503730);
|
||||
ByteOperations.WriteUInt32(HelloPacketFromPcToProgrammer, 0x208, 0x57503730);
|
||||
ByteOperations.WriteUInt16(HelloPacketFromPcToProgrammer, 0x48, 0x4445);
|
||||
|
||||
bool HandshakeCompleted = ConnectToProgrammer(HelloPacketFromPcToProgrammer);
|
||||
|
||||
if (HandshakeCompleted)
|
||||
{
|
||||
LogFile.Log("Handshake completed with programmer in testmode", LogType.FileOnly);
|
||||
@@ -279,12 +299,12 @@ namespace WPinternals
|
||||
LogFile.Log("Rebooting phone", LogType.FileAndConsole);
|
||||
const string Command03 = "<?xml version=\"1.0\" ?><data><power value=\"reset\"/></data>";
|
||||
LogFile.Log("Out: " + Command03, LogType.FileOnly);
|
||||
Serial.SendData(System.Text.Encoding.ASCII.GetBytes(Command03));
|
||||
Serial.SendData(Encoding.ASCII.GetBytes(Command03));
|
||||
|
||||
string Incoming;
|
||||
do
|
||||
{
|
||||
Incoming = System.Text.Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
Incoming = Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
LogFile.Log("In: " + Incoming, LogType.FileOnly);
|
||||
}
|
||||
while (Incoming.IndexOf("response value") < 0);
|
||||
@@ -343,5 +363,238 @@ namespace WPinternals
|
||||
}
|
||||
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
|
||||
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[] PayloadHeader = new byte[17];
|
||||
PayloadStream.Read(PayloadHeader, 0, 17);
|
||||
|
||||
bool IsValidEdPayloadImage = StructuralComparisons.StructuralEqualityComparer.Equals(PayloadHeader, ValidReferencePayloadHeader);
|
||||
if (!IsValidEdPayloadImage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now let's read the information block
|
||||
PayloadStream.Seek(0x64, SeekOrigin.Begin);
|
||||
byte[] PayloadInformationBlock = new byte[0x64];
|
||||
|
||||
PayloadStream.Read(PayloadInformationBlock, 0, 0x64);
|
||||
string buildtime = Encoding.ASCII.GetString(PayloadInformationBlock).Trim('\0');
|
||||
|
||||
PayloadStream.Read(PayloadInformationBlock, 0, 0x64);
|
||||
string builddate = Encoding.ASCII.GetString(PayloadInformationBlock).Trim('\0');
|
||||
|
||||
PayloadStream.Read(PayloadInformationBlock, 0, 0x64);
|
||||
string version = Encoding.ASCII.GetString(PayloadInformationBlock).Trim('\0');
|
||||
|
||||
PayloadInformationBlock = new byte[0x670];
|
||||
PayloadStream.Read(PayloadInformationBlock, 0, 0x670);
|
||||
string Info = Encoding.ASCII.GetString(PayloadInformationBlock).Trim('\0');
|
||||
|
||||
// Print some information about the payload
|
||||
LogFile.Log("Emerency flasher version 0.1", LogType.FileAndConsole);
|
||||
LogFile.Log("Programmer information:", LogType.FileAndConsole);
|
||||
LogFile.Log("Build time: " + buildtime, LogType.FileAndConsole);
|
||||
LogFile.Log("Build date: " + builddate, LogType.FileAndConsole);
|
||||
LogFile.Log("Version: " + version, 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
|
||||
LogFile.Log("Waiting...", LogType.FileAndConsole);
|
||||
Thread.Sleep(2000);
|
||||
LogFile.Log("Waiting...OK", LogType.FileAndConsole);
|
||||
|
||||
bool Terminated = false;
|
||||
bool Connected = false;
|
||||
bool ProgrammerRawMode = false;
|
||||
|
||||
string Incoming;
|
||||
|
||||
while (!Terminated)
|
||||
{
|
||||
PayloadInformationBlock = new byte[0x200];
|
||||
PayloadStream.Read(PayloadInformationBlock, 0, 0x200);
|
||||
string ProgrammerCommand = Encoding.ASCII.GetString(PayloadInformationBlock.Skip(0xC).ToArray()).Trim('\0');
|
||||
|
||||
LogFile.Log(ProgrammerCommand, LogType.FileAndConsole);
|
||||
|
||||
byte[] PacketFromPcToProgrammer = Array.Empty<byte>();
|
||||
byte[] temp = new byte[0x200];
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (PayloadStream.Position == PayloadStream.Length)
|
||||
{
|
||||
Terminated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
PayloadStream.Read(temp, 0, 0x200);
|
||||
|
||||
if (temp[12] == 77 && temp[13] == 83 && temp[14] == 71 && temp[15] == 95)
|
||||
{
|
||||
PayloadStream.Seek(-0x200, SeekOrigin.Current);
|
||||
break;
|
||||
}
|
||||
|
||||
PacketFromPcToProgrammer = PacketFromPcToProgrammer.Concat(temp).ToArray();
|
||||
}
|
||||
|
||||
bool ExpectingReplyFromProgrammer = false;
|
||||
|
||||
if (ProgrammerCommand.Contains("XML"))
|
||||
{
|
||||
string Outgoing = Encoding.ASCII.GetString(PacketFromPcToProgrammer).Trim('\0');
|
||||
PacketFromPcToProgrammer = Encoding.ASCII.GetBytes(Outgoing);
|
||||
LogFile.Log("Out: " + Outgoing, LogType.FileAndConsole);
|
||||
}
|
||||
|
||||
if (!ProgrammerCommand.Contains("RAW_DATA") && !ProgrammerRawMode)
|
||||
{
|
||||
ExpectingReplyFromProgrammer = true;
|
||||
}
|
||||
|
||||
if (ProgrammerCommand.Contains("LAST") && ProgrammerRawMode)
|
||||
{
|
||||
ExpectingReplyFromProgrammer = true;
|
||||
}
|
||||
|
||||
if (ProgrammerCommand.Contains("DATA_ALL") && ProgrammerRawMode)
|
||||
{
|
||||
ExpectingReplyFromProgrammer = true;
|
||||
}
|
||||
|
||||
if (ProgrammerCommand.Contains("RAW_DATA") && !ProgrammerRawMode)
|
||||
{
|
||||
LogFile.Log("Phone is not in raw mode ON, leaving...", LogType.FileAndConsole);
|
||||
|
||||
// Workaround for problem
|
||||
// SerialPort is sometimes not disposed correctly when the device is already removed.
|
||||
// So explicitly dispose here
|
||||
Serial.Close();
|
||||
|
||||
LogFile.Log("Phone has been emergency flashed unsuccessfully!", LogType.FileAndConsole);
|
||||
PayloadStream.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ProgrammerCommand.Contains("RAW_DATA") && ProgrammerRawMode)
|
||||
{
|
||||
LogFile.Log("Phone is not in raw mode ON, leaving...", LogType.FileAndConsole);
|
||||
|
||||
// Workaround for problem
|
||||
// SerialPort is sometimes not disposed correctly when the device is already removed.
|
||||
// So explicitly dispose here
|
||||
Serial.Close();
|
||||
|
||||
LogFile.Log("Phone has been emergency flashed unsuccessfully!", LogType.FileAndConsole);
|
||||
PayloadStream.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Connected)
|
||||
{
|
||||
Serial.SendData(PacketFromPcToProgrammer);
|
||||
}
|
||||
|
||||
if (ExpectingReplyFromProgrammer)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
Connected = ConnectToProgrammer(PacketFromPcToProgrammer);
|
||||
|
||||
if (Connected)
|
||||
{
|
||||
LogFile.Log("Handshake completed with programmer in validated image programming (VIP) mode", LogType.FileAndConsole);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile.Log("Handshake with programmer failed", LogType.FileAndConsole);
|
||||
}
|
||||
|
||||
if (!Connected)
|
||||
{
|
||||
LogFile.Log("Phone programmer is now ignoring us, leaving...", LogType.FileAndConsole);
|
||||
|
||||
// Workaround for problem
|
||||
// SerialPort is sometimes not disposed correctly when the device is already removed.
|
||||
// So explicitly dispose here
|
||||
Serial.Close();
|
||||
|
||||
LogFile.Log("Phone has been emergency flashed unsuccessfully!", LogType.FileAndConsole);
|
||||
PayloadStream.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
Serial.SetTimeOut(500);
|
||||
Incoming = Encoding.ASCII.GetString(Serial.GetResponse(null));
|
||||
Serial.SetTimeOut(200);
|
||||
LogFile.Log("In: " + Incoming, LogType.FileAndConsole);
|
||||
}
|
||||
while (Incoming.IndexOf("response value") < 0);
|
||||
|
||||
if (Incoming.Contains("rawmode=\"false\""))
|
||||
{
|
||||
ProgrammerRawMode = false;
|
||||
LogFile.Log("Raw mode: OFF", LogType.FileAndConsole);
|
||||
}
|
||||
|
||||
if (Incoming.Contains("rawmode=\"true\""))
|
||||
{
|
||||
ProgrammerRawMode = true;
|
||||
LogFile.Log("Raw mode: ON", LogType.FileAndConsole);
|
||||
}
|
||||
|
||||
if (!Incoming.Contains("ACK"))
|
||||
{
|
||||
LogFile.Log("Phone programmer is now ignoring us, leaving...", LogType.FileAndConsole);
|
||||
|
||||
// Workaround for problem
|
||||
// SerialPort is sometimes not disposed correctly when the device is already removed.
|
||||
// So explicitly dispose here
|
||||
Serial.Close();
|
||||
|
||||
LogFile.Log("Phone has been emergency flashed unsuccessfully!", LogType.FileAndConsole);
|
||||
PayloadStream.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for problem
|
||||
// SerialPort is sometimes not disposed correctly when the device is already removed.
|
||||
// So explicitly dispose here
|
||||
Serial.Close();
|
||||
|
||||
LogFile.Log("Phone has been emergency flashed successfully!", LogType.FileAndConsole);
|
||||
PayloadStream.Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace WPinternals
|
||||
CRC16 = new CRC16(0x1189, 0xFFFF, 0xFFFF);
|
||||
|
||||
string[] DevicePathElements = DevicePath.Split(new char[] { '#' });
|
||||
if (string.Compare(DevicePathElements[3], "{86E0D1E0-8089-11D0-9CE4-08003E301F73}", true) == 0)
|
||||
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);
|
||||
if (PortName != null)
|
||||
@@ -316,9 +316,9 @@ namespace WPinternals
|
||||
}
|
||||
}
|
||||
|
||||
public class IncompleteMessageException : Exception { };
|
||||
public class BadMessageException : Exception { };
|
||||
public class BadConnectionException : Exception { };
|
||||
public class IncompleteMessageException : Exception { public IncompleteMessageException() { } public IncompleteMessageException(string message) : base(message) { } public IncompleteMessageException(string message, Exception innerException) : base(message, innerException) { } }
|
||||
public class BadMessageException : Exception { public BadMessageException() { } public BadMessageException(string message) : base(message) { } public BadMessageException(string message, Exception innerException) : base(message, innerException) { } }
|
||||
public class BadConnectionException : Exception { public BadConnectionException() { } public BadConnectionException(string message) : base(message) { } public BadConnectionException(string message, Exception innerException) : base(message, innerException) { } }
|
||||
|
||||
public class CRC16
|
||||
{
|
||||
|
||||
+6
-6
@@ -237,7 +237,7 @@ namespace WPinternals
|
||||
Type = ByteOperations.ReadUInt8(DecompressedImage, DecompressedFileHeaderOffset + 0x12)
|
||||
};
|
||||
byte[] FileGuidBytes = new byte[0x10];
|
||||
System.Buffer.BlockCopy(DecompressedImage, (int)DecompressedFileHeaderOffset + 0x00, FileGuidBytes, 0, 0x10);
|
||||
Buffer.BlockCopy(DecompressedImage, (int)DecompressedFileHeaderOffset + 0x00, FileGuidBytes, 0, 0x10);
|
||||
CurrentEFI.Guid = new Guid(FileGuidBytes);
|
||||
|
||||
// Parse sections of the EFI
|
||||
@@ -286,7 +286,7 @@ namespace WPinternals
|
||||
|
||||
internal byte[] GetFile(string Name)
|
||||
{
|
||||
EFI File = EFIs.Find(f => (string.Compare(Name, f.Name, true) == 0) || (string.Compare(Name, f.Guid.ToString(), true) == 0));
|
||||
EFI File = EFIs.Find(f => string.Equals(Name, f.Name, StringComparison.CurrentCultureIgnoreCase) || string.Equals(Name, f.Guid.ToString(), StringComparison.CurrentCultureIgnoreCase));
|
||||
if (File == null)
|
||||
{
|
||||
return null;
|
||||
@@ -300,7 +300,7 @@ namespace WPinternals
|
||||
|
||||
internal byte[] GetFile(Guid Guid)
|
||||
{
|
||||
EFI File = EFIs.Find(f => (Guid == f.Guid));
|
||||
EFI File = EFIs.Find(f => Guid == f.Guid);
|
||||
if (File == null)
|
||||
{
|
||||
return null;
|
||||
@@ -314,7 +314,7 @@ namespace WPinternals
|
||||
|
||||
internal void ReplaceFile(string Name, byte[] Binary)
|
||||
{
|
||||
EFI File = EFIs.Find(f => (string.Compare(Name, f.Name, true) == 0) || (string.Compare(Name, f.Guid.ToString(), true) == 0));
|
||||
EFI File = EFIs.Find(f => string.Equals(Name, f.Name, StringComparison.CurrentCultureIgnoreCase) || string.Equals(Name, f.Guid.ToString(), StringComparison.CurrentCultureIgnoreCase));
|
||||
if (File == null)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -515,7 +515,7 @@ namespace WPinternals
|
||||
{
|
||||
UInt16 VolumeHeaderSize = ByteOperations.ReadUInt16(Image, Offset + 0x30);
|
||||
byte[] Header = new byte[VolumeHeaderSize];
|
||||
System.Buffer.BlockCopy(Image, (int)Offset, Header, 0, VolumeHeaderSize);
|
||||
Buffer.BlockCopy(Image, (int)Offset, Header, 0, VolumeHeaderSize);
|
||||
ByteOperations.WriteUInt16(Header, 0x32, 0); // Clear checksum
|
||||
UInt16 CurrentChecksum = ByteOperations.ReadUInt16(Image, Offset + 0x32);
|
||||
UInt16 NewChecksum = ByteOperations.CalculateChecksum16(Header, 0, VolumeHeaderSize);
|
||||
@@ -553,7 +553,7 @@ namespace WPinternals
|
||||
UInt32 FileSize = ByteOperations.ReadUInt24(Image, Offset + 0x14);
|
||||
|
||||
byte[] Header = new byte[FileHeaderSize - 1];
|
||||
System.Buffer.BlockCopy(Image, (int)Offset, Header, 0, FileHeaderSize - 1);
|
||||
Buffer.BlockCopy(Image, (int)Offset, Header, 0, FileHeaderSize - 1);
|
||||
ByteOperations.WriteUInt16(Header, 0x10, 0); // Clear checksum
|
||||
byte CurrentHeaderChecksum = ByteOperations.ReadUInt8(Image, Offset + 0x10);
|
||||
byte CalculatedHeaderChecksum = ByteOperations.CalculateChecksum8(Header, 0, (UInt32)FileHeaderSize - 1);
|
||||
|
||||
Reference in New Issue
Block a user