|
|
@ -9,13 +9,62 @@ namespace apphost_extract_v2.Models
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public class ApphostFile30 : IApphostFile
|
|
|
|
public class ApphostFile30 : IApphostFile
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public ApphostFile30(FileStream fs, PEHeaders peheader) : base(fs, peheader) { }
|
|
|
|
private const int HEADER_OFFSET_PTR = 0x23E00;
|
|
|
|
|
|
|
|
private const int HEADER_SIZE = 0xD;
|
|
|
|
|
|
|
|
private const int FILE_ENTRY_SIZE = 0x12;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public ApphostFile30(FileStream fs, PEHeaders peheader) : base(fs, peheader)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Header = new AppHostFileHeader();
|
|
|
|
|
|
|
|
var headerAddress = BitConverter.ToInt32(fs.ReadBuffer(HEADER_OFFSET_PTR, 4));
|
|
|
|
|
|
|
|
var headerBuffer = fs.ReadBuffer(headerAddress, HEADER_SIZE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Header.Raw = headerBuffer;
|
|
|
|
|
|
|
|
Header.Path = Encoding.UTF8.GetString(fs.ReadBuffer(headerAddress + HEADER_SIZE, 0xC));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Header.Manifest = ParseManifest();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private AppHostManifest ParseManifest()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
AppHostManifest manifest = new AppHostManifest();
|
|
|
|
|
|
|
|
var embeddedFileCount = BitConverter.ToInt32(Header.Raw, 0x8);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < embeddedFileCount; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
manifest.FileEntries.Add(GetNextEntry());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return manifest;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private AppHostFileEntry GetNextEntry()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
AppHostFileEntry entry = new AppHostFileEntry();
|
|
|
|
|
|
|
|
byte[] entryBuffer = new byte[FILE_ENTRY_SIZE];
|
|
|
|
|
|
|
|
FileStream.Read(entryBuffer, 0, entryBuffer.Length);
|
|
|
|
|
|
|
|
entry.Raw = entryBuffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
entry.Offset = BitConverter.ToInt64(entry.Raw, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//hopefully nobody embeds a file larger than 2GB :D
|
|
|
|
|
|
|
|
entry.Size = (int)BitConverter.ToInt64(entry.Raw, 0x8);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] stringBuffer = new byte[entry.Raw[0x11]];
|
|
|
|
|
|
|
|
FileStream.Read(stringBuffer, 0, stringBuffer.Length);
|
|
|
|
|
|
|
|
entry.Name = Encoding.UTF8.GetString(stringBuffer);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return entry;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void Close()
|
|
|
|
public override void Close()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw new NotImplementedException();
|
|
|
|
FileStream.Close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|