📜 ⬆️ ⬇️

Top Secret or Static IP on Windows Phone

It took me recently to make a static IP on my Windows Phone.
I went to look for a solution in Google. Everything I found there was directly related to setting up the router or fully rooted phones (my root was covered after upgrading to Tango), so this solution didn’t work for me either. And so, a brilliant idea came to mind - what if the guys from Samsung had already worked, but forgot to report it? So it was repeatedly with the menu Diagnosis. Let me remind you that through a hole in it they created a full-fledged root, launched exe files without signatures and much, much more. In the past. Again we google, but it doesn’t give anything - no one really knows the working diagnostic codes. Good. We are looking for xap diagnostic menu. Surprisingly, I found, because they are usually embedded deep in the core. The kernel was written in native code, but the interface is in C #. Exactly what is needed! Found, however, in the cache of the Chinese resource on the last page, but not the point.
Well, go! Open your favorite dotPeek from JetBrains and see the following picture:
image

Those items in which the trees refused to open are dll containing the native code. Immediately discard them.
We also discard those that begin with the words Microsoft. These are only links. There is the first project - DiagnosisApp.
Expand and look at the root and main namespaces:
image

In the root we see that the DotObfuscator has tried there, which greatly complicates the process: extra goto, empty conditions, cycles, single-letter variable names ...
The DiagnosisApp is more interesting. We see here the class responsible for the page code itself. All logic, in the best traditions of bydlokod, lies not in the ViewModel, but directly in the class. Without any partial there. At the beginning of the class we see the variables of type Button. Exactly what is needed! This is after all the dial pad:
internal Button btnDelete; internal Button btn1; internal Button btn3; internal Button btn2; internal Button btn4; internal Button btn5; internal Button btn6; internal Button btn7; internal Button btn8; internal Button btn9; internal Button btnSharp; internal Button btn0; internal Button btnStar; 


We are looking for a Click event:
 this.btn1.Click += new RoutedEventHandler(this.b); this.btn2.Click += new RoutedEventHandler(this.b); this.btn3.Click += new RoutedEventHandler(this.b); this.btn4.Click += new RoutedEventHandler(this.b); this.btn5.Click += new RoutedEventHandler(this.b); this.btn6.Click += new RoutedEventHandler(this.b); this.btn7.Click += new RoutedEventHandler(this.b); this.btn8.Click += new RoutedEventHandler(this.b); this.btn9.Click += new RoutedEventHandler(this.b); this.btn0.Click += new RoutedEventHandler(this.b); this.btnStar.Click += new RoutedEventHandler(this.b); this.btnSharp.Click += new RoutedEventHandler(this.b); 

')
It leads nowhere, only the control of the delete button and vibration.

 private void b(object A_0, RoutedEventArgs A_1) { if (1 == 0) ; label_2: this.timer_btn.Stop(); this.timer_btn.Start(); this.vibrate.Start(TimeSpan.FromSeconds(0.05)); this.e((string) ((ContentControl) A_0).Content); bool flag = this.txtDial.Text.Length <= 0; int num = 1; while (true) { switch (num) { case 0: this.btnDelete.Visibility = Visibility.Visible; num = 2; continue; case 1: if (!flag) { num = 0; continue; } else goto label_7; case 2: goto label_5; default: goto label_2; } } label_5: return; label_7:; } 


Well, thank God, to understand this better and not to start ...
It would seem a dead end, but it turns out that everything is controlled by a timer, which is activated after each button press:

 this.timer_btn.Tick += new EventHandler(this.ParseDial); public void ParseDial(object sender, EventArgs e) { if (1 == 0) ; this.timer_btn.Stop(); this.GetEnumFromList(this.f(this.txtDial.Text)); } public void GetEnumFromList(uint hashCode) { label_2: int A_0 = 0; int num = 12; bool flag; while (true) { switch (num) { case 0: case 16: num = 3; continue; case 1: if (!flag) { num = 10; continue; } else { flag = Convert.ToBoolean(this.iNVBlock); num = 14; continue; } case 2: this.TitleBrush.Color = Color.FromArgb(byte.MaxValue, (byte) 0, (byte) 80, byte.MaxValue); this.textBlockPageTitle.Foreground = (Brush) this.TitleBrush; this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode, (object) HiddenKeyTable.Current.hashTable[A_0].iHashcode), UriKind.Relative)); num = 9; continue; case 3: case 9: case 15: num = 4; continue; case 4: if (1 == 0) ; ++A_0; num = 17; continue; case 5: if (flag) { this.TitleBrush.Color = Color.FromArgb(byte.MaxValue, byte.MaxValue, (byte) 0, (byte) 0); this.textBlockPageTitle.Foreground = (Brush) this.TitleBrush; num = 0; continue; } else { num = 8; continue; } case 6: if (!flag) { num = 13; continue; } else goto case 4; case 7: if (!flag) { num = 11; continue; } else { flag = HiddenKeyTable.Current.hashTable[A_0].iHash.CompareTo(hashCode) != 0; num = 6; continue; } case 8: this.TitleBrush.Color = Color.FromArgb(byte.MaxValue, byte.MaxValue, (byte) 127, (byte) 0); this.textBlockPageTitle.Foreground = (Brush) this.TitleBrush; this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode), UriKind.Relative)); num = 16; continue; case 10: this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode, (object) HiddenKeyTable.Current.hashTable[A_0].iHashcode), UriKind.Relative)); num = 15; continue; case 11: goto label_26; case 12: case 17: flag = A_0 < this.length; num = 7; continue; case 13: this.HybridInterface_FCRProxy.w(out this.iNVBlock); flag = !this.g(A_0); num = 1; continue; case 14: if (flag) { this.TitleBrush.Color = Color.FromArgb(byte.MaxValue, byte.MaxValue, (byte) 127, (byte) 0); this.textBlockPageTitle.Foreground = (Brush) this.TitleBrush; flag = this.d(); num = 5; continue; } else { num = 2; continue; } default: goto label_2; } } label_26:; } 


Lord, to understand this code you need a lot of alcohol ... We delete everything except navigation to the pages:

 this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode, (object) HiddenKeyTable.Current.hashTable[A_0].iHashcode), UriKind.Relative)); this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode), UriKind.Relative)); this.NavigationService.Navigate(new Uri(string.Format(HiddenKeyTable.Current.hashTable[A_0].strPage, (object) HiddenKeyTable.Current.hashTable[A_0].iPageMode, (object) HiddenKeyTable.Current.hashTable[A_0].iHashcode), UriKind.Relative)); 


Already better. Here you can see that the navigation goes through a certain table HiddenKeyTable, and the key is the result of a certain function f (A_0), which is a hash of the entered code. We look at the function code:

 private uint f(string A_0) { switch (0) //  switch ,     - default,    { default: //   label_2: //  label uint num1 = 0U; int index = 0; int num2 = 2; uint num3; bool flag; //     ,    while (true) { switch (num2) //  switch,      { case 0: goto label_9; case 1: case 2: flag = index < A_0.Length; num2 = 4; continue; case 3: num3 = num1; num2 = 0; continue; case 4: if (!flag) { num2 = 3; continue; } else { num1 = (num1 << 5) + num1 + (uint) A_0[index]; //   ,    ++index; if (1 == 0) ; num2 = 1; continue; } default: goto label_2; } } label_9: return num3; } } 


Well, you have to figure out without alcohol. We remove lines of code that simply confuse, such as switch (0), extra cases, debugger, we go through the code and see where it ends up (converted to a readable form):

 private static uint GetHashCode(string code) { var hash = 0U; foreach (var ch in code) hash = (hash << 5) + hash + ch; return hash; } 


Having found the non-working codes, I found that something like * # 123 # is used everywhere, i.e. the numeric code starts with * # and ends with #. Form the line:

 const string format = "*#{0}#" 


And now the brute force method to break through the hash and compare it with the value from the table:

 public static void Main() { BruteHash("0{0}"); //     0,   - ,     BruteHash("{0}"); //    } private static void BruteHash(string f) { const string format = "*#{0}#"; //    var thread = new Thread(() => { var i = 0; while (true) { var code = string.Format(f, i); var codeStr = string.Format(format, code); var value = GetHashCode(codeStr); //      *#123# if (IsIpHash(value)) //    { Console.Write(codeStr); //  return; } i++; } }); thread.Start(); } private static uint GetHashCode(string code) { var hash = 0U; foreach (var ch in code) hash = (hash << 5) + hash + ch; return hash; } private static bool IsIpHash(uint hash) { return hash == 3974577854U; } 


The value 3974577854U is easy to find: in the HiddenKeyTable table by IP lookup, I found the g_IPSetting key, the value of which is exactly this number. It remains only to run and literally in a second we get the result - code * # 232340 #, enter, and voila! We can change the IP address, subnet mask, gateway, DNS. It works only with Diagnosis 1109, Samsung Omnia W. I haven’t tested it on others, alas. The reasons for hiding this code are not clear, really. Having stuck in the table, I found some other working codes:

* # 9900 # - DEBUGDUMP
* # 745 # - RILDUMP (SLOG_DUMP, sth to file)
* # 9990 # - g_VERIFYCOMPARE (IMEI compare for PLS operation 8)
* # 2470 # - g_CAMERAUPDATE (CameraFWUpdate)
* # 0589 #! - g_LIGHTSENSORTEST
* # 1111 # - g_SWversionFTA (Test Mode FTA SW version)
* # 2222 # - g_HWversionFTA (Test Mode FTA HW version)
* # 1234 # - g_SWversionEx (Version of systems, wifi, bt, csc, pda, phone)
* # 0228 # - g_BATTERYINFO
* # 0842 # - g_DEVICETEST
* # 0283 # - g_PHONELOOPBACKTEST
* # 7284 # - g_USBPATHCHANGE
* # 232337 # - g_BLUETOOTH_MAC_VIEWER
* # 232331 # - g_BLUETOOTH_RF_TEST
* # 232338 # - g_WIFI_MAC_VIEWER
* # 770 # - g_VPHONE770
* # 771 # - g_VPHONE771
* # 772 # - g_VPHONE772
* # 773 # - g_VPHONE773
* # 774 # - g_VPHONE774
* # 775 # - g_VPHONE775
* # 776 # - g_VPHONE776
* # 777 # - g_VPHONE777
* # 778 # - g_VPHONE778
* # 779 # - g_VPHONE779
* # 7451 # - g_ERROR_REPORT_ON
* # 6381 # - g_RILNETLOG_ON
* # 6380 # - g_RILNETLOG_OFF
* # 9908 # - g_GUMITEST3G_CAB_INSTALL
* # 9920 # - g_CONNECTION_SETTING (connection string)
* # 07 # - g_VIEWHISTORYNW
* # 2663 # - g_TouchFirmare_2663 (touch screen version)
* # 99785 # - g_PVKKey
* # 997856 # - g_PVKFileName
* # 86824 # - g_TouchkeySensitivity (firmware deupgrade available! (From 09 to 08))
* # 0123 # - g_MPS (MPS viewer, connection string)
* # 232340 # - g_IPSetting (IP SETTINGS !!!)

The rest are marked in the BlockType.none table, I still do not understand how to call them, there is a HybridInterface_FCRProxy.w () function that returns something, but I could not figure it out.

Link to download XAP archive . I apologize, I do not know where to pour.

PS If I wrote or designed something wrong, please - indicate this in the LAN. So far, I do not know exactly how to make out. Thank.

Source: https://habr.com/ru/post/173325/


All Articles