XP1

sda-flashtool.cs

XP1
Sep 1st, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.25 KB | None | 0 0
  1. using System;
  2. using System.Text;
  3. using System.IO;
  4.  
  5. using LibUsbDotNet;
  6. using LibUsbDotNet.Info;
  7. using LibUsbDotNet.Main;
  8. using System.Collections.ObjectModel;
  9.  
  10. /*
  11.  * sda-flashtool alpha r06
  12.  * developed by slashdevandroid '15
  13.  *
  14.  * Released under the following terms: for personal, non-commercial, and/or educational use only. As-is.
  15.  * UNCONDITIONALLY: you accept all terms, conditions, and all associated risks and liabilities. Portions may have
  16.  * additional rights and/or restrictions by other parties.
  17.  *
  18.  * *** FAIR USE NOTICE ***
  19.  * Portions may have additional rights and/or restrictions by other parties.
  20. */
  21.  
  22. namespace sda_flashtool
  23. {
  24.     public static class SharedGlobally
  25.     {
  26.         public static int ProgramVersion = 6;
  27.  
  28.         public static string ProgramInfo = String.Format("sda-flashtool [ALPHA] r{0:00}\nDeveloped by: slashdevandroid '15\n", ProgramVersion);
  29.         public static string ReleaseAndUseConditions = "Released under the following terms: for personal, non-commercial, and/or educational use only. As-is. UNCONDITIONALLY: you accept all terms, conditions, and all associated risks and liabilities. Portions may have additional rights and/or restrictions by other parties.";
  30.  
  31.         public static bool waitingResponse = false;
  32.         public static byte[] responseBuffer = new byte[4132];
  33.         public static int defaultTimeoutInMS = 90 * 1000;
  34.  
  35.         public static int transferredOut;
  36.         public static int transferredIn;
  37.  
  38.         public static UsbTransfer usbWriteTransfer;
  39.         public static UsbTransfer usbReadTransfer;
  40.  
  41.         public static ErrorCode ecWrite = ErrorCode.None;
  42.         public static ErrorCode ecRead = ErrorCode.None;
  43.  
  44.         public static bool PhoneInFailState = false;
  45.     }
  46.  
  47.     class MainClass
  48.     {
  49.         public static UsbDevice MyUsbDevice;
  50.  
  51.         public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x1ebf, 0x7001);
  52.  
  53.         public static UsbEndpointWriter usbWriter;
  54.         public static UsbEndpointReader usbReader;
  55.  
  56.         // methods for changing hex to strings and so forth
  57.         public static byte[] StringToByteArrayFastest(string hex)
  58.         {
  59.             if (hex.Length % 2 == 1)
  60.                 return new byte[] { 0x00 };
  61.  
  62.             byte[] arr = new byte[hex.Length >> 1];
  63.  
  64.             for (int i = 0; i < hex.Length >> 1; ++i)
  65.             {
  66.                 arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
  67.             }
  68.  
  69.             return arr;
  70.         }
  71.  
  72.         public static int GetHexVal(char hex)
  73.         {
  74.             int val = (int)hex;
  75.             return val - (val < 58 ? 48 : 55);
  76.         }
  77.  
  78.         public static string HexToStr(string HexString)
  79.         {
  80.             HexString = HexString.Replace("-", "");
  81.             HexString = HexString.Replace(":", "");
  82.  
  83.             byte[] raw = new byte[HexString.Length / 2];
  84.             for (int i = 0; i < raw.Length; i++)
  85.             {
  86.                 raw[i] = Convert.ToByte(HexString.Substring(i * 2, 2), 16);
  87.             }
  88.  
  89.             return (string)Encoding.ASCII.GetString(raw);
  90.         }
  91.  
  92.         public static string StrToHex(string toHex)
  93.         {
  94.             char[] values = toHex.ToCharArray();
  95.             string hexOut = string.Empty;
  96.  
  97.             foreach (char letter in values)
  98.             {
  99.                 int value = Convert.ToInt32(letter);
  100.                 hexOut += String.Format("{0:X}", value);
  101.             }
  102.  
  103.             return hexOut;
  104.         }
  105.  
  106.         public static string byteArrayToHexString(byte[] raw, int len = -1)
  107.         {
  108.             string returnVal;
  109.  
  110.             if (len == -1)
  111.                 returnVal = BitConverter.ToString(raw);
  112.             else
  113.                 returnVal = BitConverter.ToString(raw, 0, len);
  114.             return (string)returnVal;
  115.         }
  116.  
  117.         // begin usb interface stuff
  118.         public static void SendData(byte[] byteArray, int timeOut = 30000)
  119.         {
  120.             int bytesWritten;
  121.  
  122.             if (MainClass.usbReader == null || MainClass.usbWriter == null)
  123.                 return;
  124.  
  125.             System.Threading.Thread.Sleep(10);
  126.  
  127.             try
  128.             {
  129.                 SharedGlobally.ecWrite = MainClass.usbWriter.Transfer(byteArray, 0, byteArray.Length, timeOut, out bytesWritten);
  130.  
  131.                 if (SharedGlobally.ecWrite != ErrorCode.None)
  132.                 {
  133.                     Console.WriteLine(SharedGlobally.ecWrite.ToString() + UsbDevice.LastErrorString.ToString());
  134.                 }
  135.             }
  136.             catch
  137.             {
  138.                 Console.WriteLine(SharedGlobally.ecWrite.ToString() + UsbDevice.LastErrorString.ToString());
  139.             }
  140.         }
  141.  
  142.         public static void SendRawCommand(byte[] byteCmd, string descrp = "", bool waitResponse = true)
  143.         {
  144.             Console.ForegroundColor = ConsoleColor.Green;
  145.  
  146.             if (descrp == "")
  147.                 Console.WriteLine("SEND: {0}", byteArrayToHexString(byteCmd, 4));
  148.             else
  149.                 Console.WriteLine("SEND: {0}", descrp);
  150.  
  151.             Console.ResetColor();
  152.  
  153.             SharedGlobally.waitingResponse = waitResponse;
  154.  
  155.             SendData(byteCmd);
  156.         }
  157.  
  158.         public static void SendCommand(string d, bool waitResponse = true)
  159.         {
  160.             Console.ForegroundColor = ConsoleColor.Green;
  161.             Console.WriteLine("SEND: COMMAND:" + d.ToString());
  162.  
  163.             byte[] byteCmd = new byte[d.Length];
  164.             byteCmd = Encoding.ASCII.GetBytes(d);
  165.  
  166.             Console.ResetColor();
  167.  
  168.             SharedGlobally.waitingResponse = waitResponse;
  169.  
  170.             SendData(byteCmd);
  171.         }
  172.  
  173.         public static void SendByPKTTransferMethod(string @fileName, string flashTarget)
  174.         {
  175.             long fileByteSize = (new System.IO.FileInfo(fileName).Length);
  176.             int length = (int)fileByteSize;
  177.  
  178.             byte[] initialHeaderArray = new byte[12];
  179.             byte[] finalHeaderArray = new byte[12];
  180.  
  181.             int maxPKTLength = 209715200;
  182.             int numOfEvenSystemPackets = 1;
  183.  
  184.             if (length > maxPKTLength)
  185.                 numOfEvenSystemPackets = (int)length / (int)maxPKTLength;
  186.  
  187.             string hexLength = maxPKTLength.ToString("x").PadLeft(8, '0');
  188.  
  189.             Buffer.BlockCopy(Encoding.ASCII.GetBytes(hexLength), 0, initialHeaderArray, 0, 8);
  190.            
  191.             // FAIR USE
  192.             Buffer.BlockCopy(FairUseOnly.lengthConstant, 0, initialHeaderArray, 9, FairUseOnly.lengthConstant.Length);
  193.  
  194.             initialHeaderArray = FairUseOnly.headerLengthSimpleSubstitution(initialHeaderArray);
  195.  
  196.             string encodedInitialAndMiddle = BitConverter.ToString(initialHeaderArray).Replace("-", ":");
  197.             string encodedFinalHeader = BitConverter.ToString(finalHeaderArray).Replace("-", ":");
  198.  
  199.             Console.ForegroundColor = ConsoleColor.White;
  200.  
  201.             Console.WriteLine("\nFlashing...");
  202.             Console.WriteLine("File: '{0}'\nSize: '{1}' (bytes)", fileName, length, hexLength);
  203.             Console.WriteLine("ATTEMPTING FLASH: {0} -> {1}", fileName, flashTarget);
  204.             Console.ResetColor();
  205.  
  206.             string downloadPKTstr;
  207.             int currentPKTNumber = 1;
  208.  
  209.             // begin transfering
  210.             byte[] fileChunk = new byte[4096];
  211.  
  212.             using (FileStream fs = File.OpenRead(fileName))
  213.             {
  214.                 using (BinaryReader br = new BinaryReader(fs))
  215.                 {
  216.                     byte[] header;
  217.  
  218.                     for (currentPKTNumber = 1; currentPKTNumber < (numOfEvenSystemPackets + 1); currentPKTNumber++)
  219.                     {
  220.                         Console.ForegroundColor = ConsoleColor.White;
  221.                         Console.WriteLine("\nATTEMPTING Transfer of PKT{0}\n", currentPKTNumber);
  222.                         Console.ResetColor();
  223.  
  224.                         downloadPKTstr = "download-pkt:" + hexLength + string.Format(",{0:00}", currentPKTNumber);
  225.  
  226.                         SendCommand(downloadPKTstr);
  227.                         awaitResponse();
  228.  
  229.                         Array.Copy(initialHeaderArray, fileChunk, initialHeaderArray.Length);
  230.  
  231.                         header = new byte[4096 - initialHeaderArray.Length];
  232.                         header = br.ReadBytes(4096 - initialHeaderArray.Length);
  233.  
  234.                         Array.Copy(header, 0, fileChunk, initialHeaderArray.Length, header.Length);
  235.  
  236.                         if (SharedGlobally.PhoneInFailState == false)
  237.                         {
  238.                             SendData(fileChunk, 100);
  239.                         }
  240.  
  241.                         // 1 (header) + 51199 = 51200 * 4096 = 0xC800000 = max PKT size before flash.
  242.                         for (int startPacket = 1; startPacket < 51200; startPacket++)
  243.                         {
  244.                             Console.Title = string.Format("Transfering: PKT{0}/4 Transmitted:{1}/{2}", currentPKTNumber, fs.Position, fs.Length);
  245.                             Array.Clear(fileChunk, 0, fileChunk.Length);
  246.  
  247.                             fileChunk = br.ReadBytes(4096);
  248.  
  249.                             if (SharedGlobally.PhoneInFailState == false)
  250.                             {
  251.                                 SendData(fileChunk, 100);
  252.                             }
  253.                         }
  254.  
  255.                         System.Threading.Thread.Sleep(3000);
  256.  
  257.                         // AWAIT OKAY
  258.                         awaitResponse();
  259.  
  260.                         // FLASH IT.
  261.                         SendCommand("flash-pkt:" + flashTarget + string.Format(" {0:00}", currentPKTNumber));
  262.                         awaitResponse();
  263.                     }
  264.  
  265.                     // LAST PKT
  266.                     currentPKTNumber = (numOfEvenSystemPackets + 1);
  267.  
  268.                     int lastPacketSize = 12 + (int)fs.Length - (int)fs.Position;
  269.                     string finalHexLength = lastPacketSize.ToString("x").PadLeft(8, '0');
  270.  
  271.                     Buffer.BlockCopy(Encoding.ASCII.GetBytes(finalHexLength), 0, finalHeaderArray, 0, 8);
  272.  
  273.                     downloadPKTstr = "download-pkt:" + finalHexLength + string.Format(",{0:00}", currentPKTNumber);
  274.  
  275.                     finalHeaderArray = FairUseOnly.headerLengthSimpleSubstitution(finalHeaderArray);
  276.                     encodedFinalHeader = BitConverter.ToString(finalHeaderArray).Replace("-", ":");
  277.  
  278.                     Console.ForegroundColor = ConsoleColor.White;
  279.                     Console.WriteLine("\nTransfer of Final PKT{0}\n", currentPKTNumber);
  280.                     Console.ResetColor();
  281.  
  282.                     SendCommand(downloadPKTstr);
  283.                     awaitResponse();
  284.  
  285.                     fileChunk = new byte[4096];
  286.                     Array.Copy(finalHeaderArray, fileChunk, finalHeaderArray.Length);
  287.  
  288.                     header = new byte[4096 - finalHeaderArray.Length];
  289.                     header = br.ReadBytes(4096 - finalHeaderArray.Length);
  290.  
  291.                     Array.Copy(header, 0, fileChunk, finalHeaderArray.Length, header.Length);
  292.  
  293.  
  294.                     if (SharedGlobally.PhoneInFailState == false)
  295.                     {
  296.                         SendData(fileChunk, 100);
  297.                     }
  298.  
  299.                     int packetsLeft = ((int)length - (int)fs.Position) / 4096;
  300.  
  301.                     for (int packetNo = 0; packetNo < packetsLeft; packetNo++)
  302.                     {
  303.                         Console.Title = string.Format("Transfering: PKT{0}/4 Transmitted:{1}/{2}", currentPKTNumber, fs.Position, fs.Length);
  304.                         Array.Clear(fileChunk, 0, fileChunk.Length);
  305.                         fileChunk = br.ReadBytes(4096);
  306.  
  307.                         if (SharedGlobally.PhoneInFailState == false)
  308.                         {
  309.                             SendData(fileChunk, 100);
  310.                         }
  311.                     }
  312.  
  313.                     fileChunk = new byte[fs.Length - fs.Position];
  314.                     fileChunk = br.ReadBytes(fileChunk.Length);
  315.  
  316.                     SendData(fileChunk);
  317.  
  318.                     if (fs.Position == fs.Length)
  319.                         Console.ForegroundColor = ConsoleColor.Cyan;
  320.                     else
  321.                         Console.ForegroundColor = ConsoleColor.Red;
  322.  
  323.                     System.Threading.Thread.Sleep(4000);
  324.                     awaitResponse();
  325.  
  326.                     SendCommand("flash-pkt:" + flashTarget + string.Format(" {0:00}", currentPKTNumber));
  327.                     awaitResponse();
  328.                 }
  329.             }
  330.  
  331.         }
  332.  
  333.         private static void RECVFromUSB(object sender, EndpointDataEventArgs e)
  334.         {
  335.             Console.ResetColor();
  336.  
  337.             string check = System.Text.Encoding.UTF8.GetString(e.Buffer, 0, 10);
  338.             Console.ForegroundColor = ConsoleColor.Blue;
  339.  
  340.             if (check.Contains("OKAY") && !check.Contains("OKAYV1"))
  341.             {
  342.                 Console.WriteLine("RECV: OKAY", check);
  343.             }
  344.  
  345.             if (check.Contains("FAIL"))
  346.             {
  347.                 Console.ForegroundColor = ConsoleColor.Red;
  348.                 Console.WriteLine("RECV: DEVICE OPERATION FAILURE - FAIL{0}", System.Text.Encoding.UTF8.GetString(e.Buffer, 5, 14));
  349.                 SharedGlobally.PhoneInFailState = true;
  350.             }
  351.  
  352.             if (check.Contains("DATA"))
  353.             {
  354.                 Console.ForegroundColor = ConsoleColor.Yellow;
  355.                 Console.WriteLine("RECV: DEVICE AWAITING DATA TRANSFER: {0}", System.Text.Encoding.UTF8.GetString(e.Buffer, 4, 14));
  356.             }
  357.  
  358.             if (check.Contains("OKAYV1"))
  359.             {
  360.                 Console.WriteLine("RECV: DEVICE ACKs CMD");
  361.             }
  362.  
  363.             Console.ResetColor();
  364.  
  365.             lock (SharedGlobally.responseBuffer)
  366.             {
  367.                 Array.Copy(e.Buffer, SharedGlobally.responseBuffer, e.Buffer.Length);
  368.             }
  369.  
  370.             SharedGlobally.waitingResponse = false;
  371.         }
  372.  
  373.         private static void awaitResponse(int waitTime = -1, string expectedResponse = "")
  374.         {
  375.             if (waitTime == -1)
  376.                 waitTime = SharedGlobally.defaultTimeoutInMS;
  377.  
  378.             int _currentIdle = 0;
  379.  
  380.             while (SharedGlobally.waitingResponse == true)
  381.             {
  382.                 if (_currentIdle < waitTime)
  383.                 {
  384.                     Console.Title = String.Format("Timeout in: {0}/{1}", _currentIdle, waitTime);
  385.  
  386.                     System.Threading.Thread.Sleep(20);
  387.                     _currentIdle += 20;
  388.                 }
  389.                 else
  390.                 {
  391.                     throw new Exception("error awaiting response");
  392.                 }
  393.             }
  394.  
  395.             System.Threading.Thread.Sleep(19);
  396.  
  397.             SharedGlobally.waitingResponse = false;
  398.         }
  399.  
  400.         // FAIR USE -- REQUIRED TO FLASH/TRANSFER TO DEVICE
  401.         public static void DoUnlockSequence()
  402.         {
  403.             SendRawCommand(FairUseOnly.StartDownloadOne, "StartDownload One/Two");
  404.             awaitResponse();
  405.  
  406.             SendRawCommand(FairUseOnly.StartDownloadTwo, "StartDownload Two/Two");
  407.             awaitResponse();
  408.  
  409.             SendCommand("unlock-boot");
  410.             awaitResponse();
  411.  
  412.             SendRawCommand(FairUseOnly.enableUpgradeMode, "Enabling Upgrade Mode");
  413.             awaitResponse();
  414.         }
  415.  
  416.         // FAIR USE -- REQUIRED TO FLASH/TRANSFER TO DEVICE
  417.         public static void DoLockSequence()
  418.         {
  419.             System.Threading.Thread.Sleep(2000);
  420.             SendCommand("lock-boot");
  421.             awaitResponse();
  422.  
  423.             Console.WriteLine("FAIR USE - cleartext: write-par:V1?2");
  424.             SendRawCommand(FairUseOnly.disableUpgradeMode, "Disabling Upgrade mode - FAIR USE");
  425.             awaitResponse();
  426.  
  427.             SendCommand("StopDownload");
  428.             Console.WriteLine("REBOOTING DEVICE IN in 10s");
  429.             System.Threading.Thread.Sleep(10000);
  430.             SendCommand("reboot-bootloader");
  431.             awaitResponse();
  432.             System.Threading.Thread.Sleep(3000);
  433.         }
  434.  
  435.         public static void ShowAuthorNoticesAndDisclaimer()
  436.         {
  437.             Console.ForegroundColor = ConsoleColor.Green;
  438.             Console.WriteLine(SharedGlobally.ProgramInfo);
  439.  
  440.             Console.WriteLine("If you agree: type 'I agree' and press enter.\n");
  441.  
  442.             Console.ResetColor();
  443.             string writeYes = Console.ReadLine();
  444.  
  445.             if (writeYes != "I agree")
  446.             {
  447.                 Console.WriteLine("You didn't agree to the terms. Terminating.");
  448.                 Environment.Exit(0);
  449.             }
  450.         }
  451.  
  452.         public static void Main(string[] args)
  453.         {
  454.             ShowAuthorNoticesAndDisclaimer();
  455.  
  456.             try
  457.             {
  458.                 MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
  459.  
  460.                 if (MyUsbDevice == null)
  461.                 {
  462.                     Console.ForegroundColor = ConsoleColor.Red;
  463.                     Console.WriteLine("ERROR: USB Device: 0x1ebf:0x7001 not connected");
  464.                     throw new Exception("ERROR: USB Device was not found");
  465.                 }
  466.  
  467.                 MainClass.usbReader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
  468.                 MainClass.usbWriter = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
  469.  
  470.                 usbReader.DataReceived += (RECVFromUSB);
  471.                 usbReader.DataReceivedEnabled = true;
  472.  
  473.  
  474.                 DoUnlockSequence();
  475.  
  476.                 SendByPKTTransferMethod(@"new_system.img", "system");
  477.  
  478.                 DoLockSequence();
  479.             }
  480.             catch (Exception e)
  481.             {
  482.                 Console.WriteLine(e.ToString());
  483.             }
  484.             finally
  485.             {
  486.                 if (usbReader != null)
  487.                 {
  488.                     usbReader.DataReceivedEnabled = false;
  489.                     usbReader.DataReceived -= (RECVFromUSB);
  490.                 }
  491.  
  492.                 if (MyUsbDevice != null)
  493.                 {
  494.                     if (MyUsbDevice.IsOpen)
  495.                     {
  496.                         MyUsbDevice.Close();
  497.                     }
  498.                     MyUsbDevice = null;
  499.  
  500.                     UsbDevice.Exit();
  501.                 }
  502.             }
  503.  
  504.             Console.ResetColor();
  505.             Console.WriteLine("All Done! Enjoy.");
  506.  
  507.             Environment.Exit(0);
  508.         }
  509.     }
  510. }
Add Comment
Please, Sign In to add comment