allowing for manual offset entry in case auto analysis fails

master apphost-extract-v2-fix
VollRagm 3 years ago
parent 026baa2b82
commit a07c4d89f9

@ -27,27 +27,28 @@ namespace apphost_extract_v2
public IApphostFile Open() public IApphostFile Open()
{ {
var textSegment = PEHeader.GetSegment(".text"); var textSegment = PEHeader.GetSegment(".text");
var sw = Stopwatch.StartNew(); var sw = Stopwatch.StartNew();
Log.Info("Scanning for version string pointer..."); Log.Info("Scanning for version string pointer...");
var sigscanResults = PatternScan(File, var sigscanResults = PatternScan(File,
textSegment.PointerToRawData, textSegment.SizeOfRawData, textSegment.PointerToRawData, textSegment.SizeOfRawData,
VERSION_SIGNATURE, VERSION_SIGNATURE_MASK); VERSION_SIGNATURE, VERSION_SIGNATURE_MASK);
sw.Stop(); sw.Stop();
if (sigscanResults.Length == 0) if (sigscanResults.Length == 0)
return null; return null;
var versionOffset = (int)BitConverter.ToUInt32(File.ReadBuffer(sigscanResults[0] + 3, 4)); var versionOffset = (int)BitConverter.ToUInt32(File.ReadBuffer(sigscanResults[0] + 3, 4));
var versionStringPtr = PEHeader.AddVirtualOffset(sigscanResults[0] + 7, versionOffset); var versionStringPtr = PEHeader.AddVirtualOffset(sigscanResults[0] + 7, versionOffset);
var versionString = Encoding.Unicode.GetString( var versionString = Encoding.Unicode.GetString(
File.ReadBuffer( File.ReadBuffer(
versionStringPtr, 6)); versionStringPtr, 6));
Log.Info($"Found version string at 0x{versionStringPtr:X8} in {sw.ElapsedMilliseconds}ms -> {versionString}");
Console.WriteLine();
Log.Info($"Found version string at 0x{versionStringPtr:X8} in {sw.ElapsedMilliseconds}ms -> {versionString}");
Console.WriteLine();
switch (versionString) switch (versionString)
{ {
@ -63,5 +64,22 @@ namespace apphost_extract_v2
return null; return null;
} }
} }
public IApphostFile Open(string versionString, uint headerOffset)
{
switch (versionString)
{
case "3.0":
return new ApphostFile30(File, PEHeader, headerOffset);
case "3.1":
return new ApphostFile31(File, PEHeader, headerOffset);
case "5":
return new ApphostFile5(File, PEHeader, headerOffset);
default:
return null;
}
}
} }
} }

@ -30,6 +30,23 @@ namespace apphost_extract_v2.Models
Header.Manifest = ParseManifest(); Header.Manifest = ParseManifest();
} }
public ApphostFile30(FileStream fs, PEHeaders peheader, uint headerOffset) : base(fs, peheader)
{
Header = new AppHostFileHeader();
Log.Info($"Reading header at 0x{HEADER_OFFSET_PTR:X8}...");
var headerAddress = headerOffset;
if (headerAddress == 0)
Log.Fatal("The address of the Bundle header is 0 :/");
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() private AppHostManifest ParseManifest()
{ {
AppHostManifest manifest = new AppHostManifest(); AppHostManifest manifest = new AppHostManifest();

@ -29,6 +29,22 @@ namespace apphost_extract_v2.Models
Header.Manifest = ParseManifest(); Header.Manifest = ParseManifest();
} }
public ApphostFile31(FileStream fs, PEHeaders peheader, uint headerOffset) : base(fs, peheader)
{
Header = new AppHostFileHeader();
var headerAddress = headerOffset;
if (headerAddress == 0)
Log.Fatal("The address of the Bundle header is 0 :/");
var headerBuffer = fs.ReadBuffer(headerAddress, HEADER_SIZE);
Log.Info($"Reading header at 0x{HEADER_OFFSET_PTR:X8}...");
Header.Raw = headerBuffer;
Header.Path = Encoding.UTF8.GetString(fs.ReadBuffer(headerAddress + HEADER_SIZE, 0xC));
Header.Manifest = ParseManifest();
}
private AppHostManifest ParseManifest() private AppHostManifest ParseManifest()
{ {
AppHostManifest manifest = new AppHostManifest(); AppHostManifest manifest = new AppHostManifest();

@ -34,6 +34,24 @@ namespace apphost_extract_v2.Models
} }
public ApphostFile5(FileStream fs, PEHeaders peheader, uint headerOffset) : base(fs, peheader)
{
Header = new AppHostFileHeader();
var headerAddress = headerOffset;
if (headerAddress == 0)
Log.Fatal("Unable to located bundle header :/");
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 uint FindHeaderOffset() private uint FindHeaderOffset()
{ {
var textSegment = PEHeader.GetSegment(".text"); var textSegment = PEHeader.GetSegment(".text");

@ -19,8 +19,16 @@ namespace apphost_extract_v2
var apphostAnalyzer = new Analyzer(fileInfo); var apphostAnalyzer = new Analyzer(fileInfo);
var apphost = apphostAnalyzer.Open(); var apphost = apphostAnalyzer.Open();
if(apphost == null) if (apphost == null)
Log.Fatal("Unable to determine apphost version."); {
Log.Error("Unable to determine apphost version automatically.");
var version = Log.QueryString("Please enter the apphost version, you can find it in the entry point of the app (3.0, 3.1, 5): ");
var headerOffset = uint.Parse(Log.QueryString("Please enter the Header offset \n(parse pdb, search for header_offset in names or\n use string reference 'Bundle Header Offset: [%lx]', find the .data ptr and enter its value): ").Replace("0x", ""), System.Globalization.NumberStyles.HexNumber);
apphostAnalyzer = new Analyzer(fileInfo);
apphost = apphostAnalyzer.Open(version, headerOffset);
}
Log.Info("File parsed successfully, extracting contents..."); Log.Info("File parsed successfully, extracting contents...");
Console.WriteLine(); Console.WriteLine();

@ -0,0 +1,7 @@
{
"profiles": {
"apphost-extract-v2": {
"commandName": "Project"
}
}
}
Loading…
Cancel
Save