|
|
|
@ -12,23 +12,28 @@ namespace apphost_extract
|
|
|
|
|
private FileStream FileStream;
|
|
|
|
|
|
|
|
|
|
public AppHostFileHeader Header { get; set; }
|
|
|
|
|
private const int HEADER_OFFSET_PTR = 0x27600;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public AppHostFile(FileStream fileStream)
|
|
|
|
|
{
|
|
|
|
|
FileStream = fileStream;
|
|
|
|
|
Header = new AppHostFileHeader(FileStream);
|
|
|
|
|
|
|
|
|
|
var buffer = new byte[sizeof(int)];
|
|
|
|
|
FileStream.Seek(HEADER_OFFSET_PTR, SeekOrigin.Begin);
|
|
|
|
|
FileStream.Read(buffer, 0, buffer.Length);
|
|
|
|
|
|
|
|
|
|
Header = new AppHostFileHeader(FileStream, BitConverter.ToInt32(buffer, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static AppHostFile Open(string path)
|
|
|
|
|
{
|
|
|
|
|
if (!File.Exists(path)) Log.Fatal("File not found.");
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
|
|
|
|
|
AppHostFile file = new AppHostFile(fs);
|
|
|
|
|
Log.Info("File opened successfully!");
|
|
|
|
|
return file;
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
@ -37,5 +42,33 @@ namespace apphost_extract
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ExtractAll(string outputDir)
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(outputDir);
|
|
|
|
|
foreach (var fileEntry in Header.Manifest.FileEntries)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var bytes = fileEntry.Read();
|
|
|
|
|
var name = fileEntry.Name;
|
|
|
|
|
var filePath = Path.Combine(outputDir, name);
|
|
|
|
|
File.WriteAllBytes(filePath, bytes);
|
|
|
|
|
|
|
|
|
|
Log.Critical($"Extracted {name}");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Log.Error($"Could not extract {fileEntry.Name}: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
FileStream.Close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|