Skip to content

Commit

Permalink
Add personalized image support for iOS 17
Browse files Browse the repository at this point in the history
  • Loading branch information
master131 committed Jul 24, 2023
1 parent 4fb7f9a commit 8b0944e
Show file tree
Hide file tree
Showing 8 changed files with 1,440 additions and 185 deletions.
695 changes: 674 additions & 21 deletions LICENSE

Large diffs are not rendered by default.

45 changes: 37 additions & 8 deletions iFakeLocation/DeveloperImageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ static class DeveloperImageHelper {

private const string ImagePath = "DeveloperImages";

private static readonly string[] MobileImageFileList = new[] {
"DeveloperDiskImage.dmg",
"DeveloperDiskImage.dmg.signature"
};

private static readonly string[] PersonalisedImageFileList = new[] {
"Image.dmg",
"BuildManifest.plist",
"Image.dmg.trustcache"
};

public static bool HasImageForDevice(DeviceInformation device) {
string[] p;
return HasImageForDevice(device, out p);
Expand All @@ -30,20 +41,38 @@ static class DeveloperImageHelper {
return VersionMapping.ContainsKey(v) ? VersionMapping[v] : v;
}

public static bool IsKnownImageFileName(string fileName) {
fileName = fileName.Split('/', '\\').Last();
return MobileImageFileList.Contains(fileName) || PersonalisedImageFileList.Contains(fileName);
}

private static bool ImageExists(string[] paths) {
return paths.Length == 2 && File.Exists(paths[0]) && File.Exists(paths[1]);
return paths.All(File.Exists);
}

public static bool HasImageForDevice(DeviceInformation device, out string[] paths) {
var verStr = GetSoftwareVersion(device);
var a = Path.Combine(ImagePath, verStr, "DeveloperDiskImage.dmg");
var b = a + ".signature";

var expectedFiles = int.Parse(verStr.Split('.')[0]) >= 17
? PersonalisedImageFileList.Select(p => (object)Path.Combine(ImagePath, verStr, p)).ToArray()
: MobileImageFileList.Select(p => (object)Path.Combine(ImagePath, verStr, p)).ToArray();

var s = Path.DirectorySeparatorChar;
return ImageExists(paths = new[] {a, b}) ||
ImageExists(paths = new[] {$".{s}..{s}{a}",
$".{s}..{s}{b}"}) ||
ImageExists(paths = new[] {$".{s}..{s}..{s}{a}",
$".{s}..{s}..{s}{b}"});
string[][] pathPatterns = new[] {
new[] { "{0}", "{1}", "{2}" },
new[] { $".{s}..{s}{{0}}", $".{s}..{s}{{1}}", $".{s}..{s}{{2}}" },
new[] { $".{s}..{s}..{s}{{0}}", $".{s}..{s}..{s}{{1}}", $".{s}..{s}..{s}{{2}}" }
};

foreach (var pathPattern in pathPatterns) {
if (ImageExists(paths = pathPattern.Take(expectedFiles.Length)
.Select(pattern => string.Format(pattern, expectedFiles)).ToArray())) {
return true;
}
}

paths = null;
return false;
}

public static Tuple<string, string>[] GetLinksForDevice(DeviceInformation device) {
Expand Down
584 changes: 525 additions & 59 deletions iFakeLocation/DeviceInformation.cs

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions iFakeLocation/PlistHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Collections.Generic;
using System.IO;
using Claunia.PropertyList;
using iMobileDevice;
using iMobileDevice.Plist;

namespace iFakeLocation {
static class PlistHelper {
private static object ConvertNSToNET(NSObject obj) {
if (obj == null) {
return null;
}

if (obj is NSDictionary) {
return ReadPlistDictFromNSObject(obj);
}

if (obj is NSArray a) {
var arr = new object[a.Count];
for (int i = 0; i < arr.Length; i++)
arr[i] = ConvertNSToNET(a[i]);
return arr;
}

if (obj is NSData d) {
return d.Bytes;
}

if (obj is NSDate dd) {
return dd.Date;
}

if (obj is NSNumber n) {
if (n.isBoolean()) {
return n.ToBool();
}

if (n.isInteger()) {
return n.ToLong();
}

if (n.isReal()) {
return n.ToDouble();
}
}

if (obj is NSSet s) {
var objs = s.AllObjects();
var arr = new List<object>();
for (var i = 0; i < s.Count; i++)
arr.Add(ConvertNSToNET(objs[i]));
return arr;
}

if (obj is NSString ss) {
return ss.Content;
}
return null;
}

private static Dictionary<string, object> ReadPlistDictFromNSObject(NSObject nsObject,
ICollection<string> keys = null) {
var dict = new Dictionary<string, object>();
if (nsObject is not NSDictionary nsDict) {
return dict;
}

foreach (var kvp in nsDict) {
if (keys != null && !keys.Contains(kvp.Key))
continue;
dict[kvp.Key] = ConvertNSToNET(kvp.Value);
}
return dict;
}

public static Dictionary<string, object> ReadPlistDictFromNode(PlistHandle node,
ICollection<string> keys = null) {
var dict = new Dictionary<string, object>();
var plist = LibiMobileDevice.Instance.Plist;

var nt = plist.plist_get_node_type(node);
if (nt != PlistType.Dict)
return dict;

// Convert to XML and parse via plist-cil (libplist appears to have bugs that cause crashes?)
uint length = 0;
plist.plist_to_xml(node, out var plistXml, ref length);
return ReadPlistDictFromNSObject(XmlPropertyListParser.ParseString(plistXml), keys);
}

public static Dictionary<string, object>
ReadPlistDictFromStream(Stream stream, ICollection<string> keys = null) {

var nsObject = PropertyListParser.Parse(stream);
return ReadPlistDictFromNSObject(nsObject, keys);
}

public static Dictionary<string, object>
ReadPlistDictFromString(string str, ICollection<string> keys = null) {

var nsObject = XmlPropertyListParser.ParseString(str);
return ReadPlistDictFromNSObject(nsObject, keys);
}

public static string ToPlistXml(Dictionary<string, object> dict) {
return NSObject.Wrap(dict).ToXmlPropertyList();
}
}
}
83 changes: 0 additions & 83 deletions iFakeLocation/PlistReader.cs

This file was deleted.

16 changes: 4 additions & 12 deletions iFakeLocation/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
namespace iFakeLocation
{
class Program {
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[AttributeUsage(AttributeTargets.Method)]
class EndpointMethod : Attribute {
public string Name { get; }

Expand Down Expand Up @@ -284,7 +284,7 @@ class DownloadState {
else {
try {
if (DeveloperImageHelper.HasImageForDevice(device, out string[] p)) {
device.EnableDeveloperMode(p[0], p[1]);
device.EnableDeveloperMode(p);
device.StopLocation();
SetResponse(ctx, new { success = true });
}
Expand Down Expand Up @@ -330,7 +330,7 @@ class DownloadState {
}
// Ensure the developer image exists
else if (DeveloperImageHelper.HasImageForDevice(device, out var p)) {
device.EnableDeveloperMode(p[0], p[1]);
device.EnableDeveloperMode(p);
device.SetLocation(new PointLatLng {Lat = data.lat, Lng = data.lng});
SetResponse(ctx, new {success = true});
}
Expand Down Expand Up @@ -361,7 +361,7 @@ class DownloadState {
using (var fs = File.OpenRead(file)) {
using (var zf = new ZipFile(fs)) {
foreach (ZipEntry ze in zf) {
if (!ze.IsFile || !ze.Name.Contains("DeveloperDiskImage.dmg"))
if (!ze.IsFile || !DeveloperImageHelper.IsKnownImageFileName(ze.Name))
continue;
using (var ds = zf.GetInputStream(ze)) {
var dest = Path.Combine(Path.GetDirectoryName(file),
Expand Down Expand Up @@ -436,14 +436,6 @@ class DownloadState {
string basePath = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
Environment.CurrentDirectory = basePath;

foreach (SecurityProtocolType protocol in Enum.GetValues(typeof(SecurityProtocolType))) {
try {
ServicePointManager.SecurityProtocol |= protocol;
}
catch {
}
}

try {
NativeLibraries.Load();
}
Expand Down

0 comments on commit 8b0944e

Please sign in to comment.