Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
whoeevee committed Nov 3, 2024
0 parents commit db63ef6
Show file tree
Hide file tree
Showing 41 changed files with 1,742 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
bin/
obj/
.idea
._*
.DS_Store
/packages/
riderModule.iml
/_ReSharper.Caches/
41 changes: 41 additions & 0 deletions Common/DirectoryExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace ivinject.Common;

internal static class DirectoryExtensions
{
internal static string TempDirectoryPath()
{
return Path.Combine(
Path.GetTempPath(),
Path.ChangeExtension(Path.GetRandomFileName(), null)
);
}

internal static string HomeDirectoryPath() =>
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

internal static void CopyDirectory(string sourceDir, string destinationDir, bool recursive)
{
var dir = new DirectoryInfo(sourceDir);

if (!dir.Exists)
throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}");

var dirs = dir.GetDirectories();

Directory.CreateDirectory(destinationDir);

foreach (var file in dir.GetFiles())
{
var targetFilePath = Path.Combine(destinationDir, file.Name);
file.CopyTo(targetFilePath);
}

if (!recursive) return;

foreach (var subDir in dirs)
{
var newDestinationDir = Path.Combine(destinationDir, subDir.Name);
CopyDirectory(subDir.FullName, newDestinationDir, true);
}
}
}
14 changes: 14 additions & 0 deletions Common/FileStreamExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace ivinject.Common;

internal static class FileStreamExtensions
{
internal static uint FileHeader(this FileStream stream)
{
using var reader = new BinaryReader(stream);
var bytes = reader.ReadBytes(4);

return bytes.Length != 4
? uint.MinValue
: BitConverter.ToUInt32(bytes);
}
}
30 changes: 30 additions & 0 deletions Common/Models/BinaryHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace ivinject.Common.Models;

internal class BinaryHeaders
{
private const uint FatMagic = 0xcafebabe;
private const uint FatMagic64 = 0xcafebabf;
private const uint FatCigam = 0xbebafeca;
private const uint FatCigam64 = 0xbfbafeca;

private const uint MhMagic = 0xfeedface;
private const uint MhMagic64 = 0xfeedfacf;
private const uint MhCigam = 0xcefaedfe;
private const uint MhCigam64 = 0xcffaedfe;

internal static readonly uint[] FatHeaders =
[
FatMagic,
FatMagic64,
FatCigam,
FatCigam64
];

internal static readonly uint[] MhHeaders =
[
MhMagic,
MhMagic64,
MhCigam,
MhCigam64
];
}
68 changes: 68 additions & 0 deletions Common/Models/IviMachOBinary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Diagnostics;
using static ivinject.Common.Models.BinaryHeaders;

namespace ivinject.Common.Models;

internal class IviMachOBinary(string fileName)
{
private FileInfo FileInfo { get; } = new(fileName);

internal string Name => FileInfo.Name;
internal string FullName => FileInfo.FullName;

internal bool IsFatFile
{
get
{
var header = File.OpenRead(FullName).FileHeader();
return FatHeaders.Contains(header);
}
}

internal string FileSize
{
get
{
FileInfo.Refresh();
var size = FileInfo.Length;

return size switch
{

< 1024 => $"{size:F0} bytes",
_ when size >> 10 < 1024 => $"{size / (float)1024:F1} KB",
_ when size >> 20 < 1024 => $"{(size >> 10) / (float)1024:F1} MB",
_ => $"{(size >> 30) / (float)1024:F1} GB"
};
}
}

internal async Task<bool> IsEncrypted()
{
using var process = Process.Start(
new ProcessStartInfo
{
FileName = "otool",
Arguments = $"-l {FullName}",
RedirectStandardOutput = true
}
);

var output = await process!.StandardOutput.ReadToEndAsync();
return RegularExpressions.OToolEncryptedBinary().IsMatch(output);
}

internal async Task<bool> Thin()
{
using var process = Process.Start(
new ProcessStartInfo
{
FileName = "lipo",
Arguments = $"-thin arm64 {FullName} -output {FullName}"
}
);

await process!.WaitForExitAsync();
return process.ExitCode == 0;
}
}
12 changes: 12 additions & 0 deletions Common/Models/RegularExpressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.RegularExpressions;

namespace ivinject.Common.Models;

internal static partial class RegularExpressions
{
[GeneratedRegex("cryptid 1", RegexOptions.Compiled)]
internal static partial Regex OToolEncryptedBinary();

[GeneratedRegex(@"\.(?:app|\w*ipa)$", RegexOptions.Compiled)]
internal static partial Regex ApplicationPackage();
}
70 changes: 70 additions & 0 deletions Features/Codesigning/CodesigningMachOExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Diagnostics;
using System.Text;
using ivinject.Common.Models;

namespace ivinject.Features.Codesigning;

internal static class CodesigningMachOExtensions
{
internal static async Task<bool> SignAsync(
this IviMachOBinary binary,
string identity,
bool force,
FileInfo? entitlements,
bool preserveEntitlements = false
)
{
var arguments = new StringBuilder($"-s {identity}");

if (entitlements is not null)
arguments.Append($" --entitlements {entitlements.FullName}");
else if (preserveEntitlements)
arguments.Append(" --preserve-metadata=entitlements");

if (force)
arguments.Append(" -f");

arguments.Append($" {binary.FullName}");

using var process = Process.Start(
new ProcessStartInfo
{
FileName = "codesign",
Arguments = arguments.ToString(),
RedirectStandardOutput = true
}
);

await process!.WaitForExitAsync();
return process.ExitCode == 0;
}

internal static async Task<bool> RemoveSignatureAsync(this IviMachOBinary binary)
{
using var process = Process.Start(
new ProcessStartInfo
{
FileName = "codesign",
Arguments = $"--remove-signature {binary.FullName}"
}
);

await process!.WaitForExitAsync();
return process.ExitCode == 0;
}

internal static async Task<bool> DumpEntitlementsAsync(this IviMachOBinary binary, string outputFilePath)
{
using var process = Process.Start(
new ProcessStartInfo
{
FileName = "codesign",
Arguments = $"-d --entitlements {outputFilePath} --xml {binary.FullName}",
RedirectStandardError = true
}
);

await process!.WaitForExitAsync();
return process.ExitCode == 0;
}
}
Loading

0 comments on commit db63ef6

Please sign in to comment.