GUI: Add support for opening APK and IPA package files
This commit is contained in:
@@ -29,11 +29,32 @@ namespace Il2CppInspectorGUI
|
|||||||
|
|
||||||
private void StatusUpdate(object sender, string status) => OnStatusUpdate?.Invoke(sender, status);
|
private void StatusUpdate(object sender, string status) => OnStatusUpdate?.Invoke(sender, status);
|
||||||
|
|
||||||
|
// Attempt to load an IL2CPP application package (APK or IPA)
|
||||||
|
public async Task<bool> LoadPackageAsync(string packageFile) {
|
||||||
|
try {
|
||||||
|
var streams = Inspector.GetStreamsFromPackage(packageFile);
|
||||||
|
if (streams == null)
|
||||||
|
throw new InvalidOperationException("The supplied package is not an APK or IPA file, or does not contain an IL2CPP application");
|
||||||
|
|
||||||
|
return await LoadMetadataAsync(streams.Value.Metadata) && await LoadBinaryAsync(streams.Value.Binary);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
LastException = ex;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Attempt to load an IL2CPP metadata file
|
// Attempt to load an IL2CPP metadata file
|
||||||
public Task<bool> LoadMetadataAsync(string metadataFile) =>
|
public async Task<bool> LoadMetadataAsync(string metadataFile) {
|
||||||
|
var stream = new MemoryStream(await File.ReadAllBytesAsync(metadataFile));
|
||||||
|
return await LoadMetadataAsync(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> LoadMetadataAsync(Stream metadataStream) =>
|
||||||
Task.Run(() => {
|
Task.Run(() => {
|
||||||
try {
|
try {
|
||||||
metadata = new Metadata(new MemoryStream(File.ReadAllBytes(metadataFile)));
|
OnStatusUpdate?.Invoke(this, "Processing metadata");
|
||||||
|
metadata = new Metadata(metadataStream);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
@@ -42,11 +63,17 @@ namespace Il2CppInspectorGUI
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public Task<bool> LoadBinaryAsync(string binaryFile) =>
|
// Attempt to load an IL2CPP binary file
|
||||||
|
public async Task<bool> LoadBinaryAsync(string binaryFile) {
|
||||||
|
var stream = new MemoryStream(await File.ReadAllBytesAsync(binaryFile));
|
||||||
|
return await LoadBinaryAsync(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> LoadBinaryAsync(Stream binaryStream) =>
|
||||||
Task.Run(() => {
|
Task.Run(() => {
|
||||||
try {
|
try {
|
||||||
// This may throw other exceptions from the individual loaders as well
|
// This may throw other exceptions from the individual loaders as well
|
||||||
IFileFormatReader stream = FileFormatReader.Load(binaryFile, StatusUpdate);
|
IFileFormatReader stream = FileFormatReader.Load(binaryStream, StatusUpdate);
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
throw new InvalidOperationException("Could not determine the binary file format");
|
throw new InvalidOperationException("Could not determine the binary file format");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,7 +360,7 @@
|
|||||||
<Style>
|
<Style>
|
||||||
<Setter Property="Rectangle.Visibility" Value="Hidden"></Setter>
|
<Setter Property="Rectangle.Visibility" Value="Hidden"></Setter>
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding ElementName=btnSelectMetadataFile, Path=Visibility}" Value="Visible">
|
<DataTrigger Binding="{Binding ElementName=grdFirstPage, Path=Visibility}" Value="Visible">
|
||||||
<Setter Property="Rectangle.Visibility" Value="Visible" />
|
<Setter Property="Rectangle.Visibility" Value="Visible" />
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding ElementName=btnSelectBinaryFile, Path=Visibility}" Value="Visible">
|
<DataTrigger Binding="{Binding ElementName=btnSelectBinaryFile, Path=Visibility}" Value="Visible">
|
||||||
@@ -375,7 +375,29 @@
|
|||||||
</Rectangle>
|
</Rectangle>
|
||||||
|
|
||||||
<!-- Light boxes -->
|
<!-- Light boxes -->
|
||||||
<Button Name="btnSelectMetadataFile" Style="{StaticResource LightBoxButton}" Margin="100" Click="BtnSelectMetadataFile_OnClick" Visibility="Visible">Select an IL2CPP metadata file</Button>
|
<Grid Name="grdFirstPage">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height ="*" />
|
||||||
|
<RowDefinition Height ="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Button Grid.Row="0" Name="btnSelectMetadataFile" Style="{StaticResource LightBoxButton}" Margin="100,100,100,50" Click="BtnSelectMetadataFile_OnClick">
|
||||||
|
<TextBlock TextAlignment="Center">
|
||||||
|
<TextBlock FontSize="22">Option 1</TextBlock>
|
||||||
|
<LineBreak/>
|
||||||
|
<TextBlock>Select an IL2CPP metadata file</TextBlock>
|
||||||
|
</TextBlock>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Row="1" Name="btnSelectPackageFile" Style="{StaticResource LightBoxButton}" Margin="100,50,100,100" Click="BtnSelectPackageFile_OnClick">
|
||||||
|
<TextBlock TextAlignment="Center">
|
||||||
|
<TextBlock FontSize="22">Option 2</TextBlock>
|
||||||
|
<LineBreak/>
|
||||||
|
<TextBlock>Select an APK or IPA file</TextBlock>
|
||||||
|
<LineBreak/>
|
||||||
|
<TextBlock FontSize="16">Encrypted IPA files are not supported</TextBlock>
|
||||||
|
</TextBlock>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
<Button Name="btnSelectBinaryFile" Style="{StaticResource LightBoxButton}" Margin="100" Click="BtnSelectBinaryFile_OnClick" Visibility="Hidden">Select an IL2CPP binary file</Button>
|
<Button Name="btnSelectBinaryFile" Style="{StaticResource LightBoxButton}" Margin="100" Click="BtnSelectBinaryFile_OnClick" Visibility="Hidden">Select an IL2CPP binary file</Button>
|
||||||
|
|
||||||
<!-- Back button -->
|
<!-- Back button -->
|
||||||
@@ -384,7 +406,7 @@
|
|||||||
<Style BasedOn="{StaticResource LightBoxButton}" TargetType="{x:Type Button}">
|
<Style BasedOn="{StaticResource LightBoxButton}" TargetType="{x:Type Button}">
|
||||||
<Setter Property="Visibility" Value="Hidden"></Setter>
|
<Setter Property="Visibility" Value="Hidden"></Setter>
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding ElementName=btnSelectMetadataFile, Path=Visibility}" Value="Hidden">
|
<DataTrigger Binding="{Binding ElementName=grdFirstPage, Path=Visibility}" Value="Hidden">
|
||||||
<Setter Property="Button.Visibility" Value="Visible"/>
|
<Setter Property="Button.Visibility" Value="Visible"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding ElementName=areaBusyIndicator, Path=Visibility}" Value="Visible">
|
<DataTrigger Binding="{Binding ElementName=areaBusyIndicator, Path=Visibility}" Value="Visible">
|
||||||
|
|||||||
@@ -72,9 +72,8 @@ namespace Il2CppInspectorGUI
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (openFileDialog.ShowDialog() == true) {
|
if (openFileDialog.ShowDialog() == true) {
|
||||||
txtBusyStatus.Text = "Processing metadata...";
|
|
||||||
areaBusyIndicator.Visibility = Visibility.Visible;
|
areaBusyIndicator.Visibility = Visibility.Visible;
|
||||||
btnSelectMetadataFile.Visibility = Visibility.Hidden;
|
grdFirstPage.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
// Load the metadata file
|
// Load the metadata file
|
||||||
if (await app.LoadMetadataAsync(openFileDialog.FileName)) {
|
if (await app.LoadMetadataAsync(openFileDialog.FileName)) {
|
||||||
@@ -84,7 +83,7 @@ namespace Il2CppInspectorGUI
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
areaBusyIndicator.Visibility = Visibility.Hidden;
|
areaBusyIndicator.Visibility = Visibility.Hidden;
|
||||||
btnSelectMetadataFile.Visibility = Visibility.Visible;
|
grdFirstPage.Visibility = Visibility.Visible;
|
||||||
MessageBox.Show(this, app.LastException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(this, app.LastException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,7 +116,39 @@ namespace Il2CppInspectorGUI
|
|||||||
else {
|
else {
|
||||||
areaBusyIndicator.Visibility = Visibility.Hidden;
|
areaBusyIndicator.Visibility = Visibility.Hidden;
|
||||||
btnSelectBinaryFile.Visibility = Visibility.Visible;
|
btnSelectBinaryFile.Visibility = Visibility.Visible;
|
||||||
MessageBox.Show(this, "Something went wrong! " + app.LastException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show(this, app.LastException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Select APK or IPA package file
|
||||||
|
/// </summary>
|
||||||
|
private async void BtnSelectPackageFile_OnClick(object sender, RoutedEventArgs e) {
|
||||||
|
var app = (App) Application.Current;
|
||||||
|
|
||||||
|
var openFileDialog = new OpenFileDialog {
|
||||||
|
Filter = "Android/iOS Application Package (*.apk;*.ipa;*.zip)|*.apk;*.ipa;*.zip|All files (*.*)|*.*",
|
||||||
|
CheckFileExists = true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (openFileDialog.ShowDialog() == true) {
|
||||||
|
txtBusyStatus.Text = "Extracting package...";
|
||||||
|
areaBusyIndicator.Visibility = Visibility.Visible;
|
||||||
|
grdFirstPage.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
|
// Load the package
|
||||||
|
if (await app.LoadPackageAsync(openFileDialog.FileName)) {
|
||||||
|
// Package loaded successfully
|
||||||
|
areaBusyIndicator.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
|
lstImages.ItemsSource = app.Il2CppModels;
|
||||||
|
lstImages.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
areaBusyIndicator.Visibility = Visibility.Hidden;
|
||||||
|
grdFirstPage.Visibility = Visibility.Visible;
|
||||||
|
MessageBox.Show(this, app.LastException.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,7 +159,7 @@ namespace Il2CppInspectorGUI
|
|||||||
private void BtnBack_OnClick(object sender, RoutedEventArgs e) {
|
private void BtnBack_OnClick(object sender, RoutedEventArgs e) {
|
||||||
lstImages.ItemsSource = null;
|
lstImages.ItemsSource = null;
|
||||||
btnSelectBinaryFile.Visibility = Visibility.Hidden;
|
btnSelectBinaryFile.Visibility = Visibility.Hidden;
|
||||||
btnSelectMetadataFile.Visibility = Visibility.Visible;
|
grdFirstPage.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user