下面是代码:
// iBEC / iBSS - > SHSH生成器工具
使用System; 使用System.Collections.Generic; 使用System.Text;
命名空间SHSH_Tool { public enum VersionMode { V3_0 = 0, V3_0_1 }
class Program
{
static void PrintUsage()
{
Console.WriteLine("iBEC/iBSS to SHSH Tool");
Console.WriteLine("Usage: SHSH_Tool -tmpfiles X:\\Path\\To\\Tmp\\Directories -output X:\\Path\\To\\00.SHSH");
Console.WriteLine("Note: If you have files for 3.0.1, use the -301 switch.");
}
static void Main(string[] args)
{
VersionMode toolMode = VersionMode.V3_0;
string firmwareRootPath = null; // @"E:\Work\Dev\iPhone\iBEC_iBSS_Grabber";
string outputFilename = null; // @"E:\Work\Dev\svn\iPhone\SHSH_Tool\3.0.shsh";
string lastArg = null;
foreach (string arg in args)
{
if (arg == "-301")
{
toolMode = VersionMode.V3_0_1;
}
if (lastArg == "-tmpfiles")
{
firmwareRootPath = arg;
}
else if (lastArg == "-output")
{
outputFilename = arg;
}
lastArg = arg.ToLower();
}
if (firmwareRootPath == null || outputFilename == null)
{
PrintUsage();
return;
}
if (!System.IO.Directory.Exists(firmwareRootPath))
{
Console.WriteLine("Unable to open TMP directories path.");
PrintUsage();
return;
}
string restoreRamDiskToIgnore = "018-5304-002.dmg";
string manifestFilename = "BuildManifest.30.xml";
string shshTemplateFilename = "3.0.shsh.template";
if (toolMode == VersionMode.V3_0_1)
{
restoreRamDiskToIgnore = "018-5804-001.dmg";
manifestFilename = "BuildManifest.30.xml";
shshTemplateFilename = "3.0.1.shsh.template";
Console.WriteLine("Operating in 3.0.1 Mode");
}
else
{
Console.WriteLine("Operating in 3.0 Mode");
}
try
{
Console.WriteLine("Reading IPSW Manifest File...");
//System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(Util.ReadEmbeddedResource(manifestFilename));
BuildManifestReader manifestReader = new BuildManifestReader(manifestFilename);
Console.WriteLine("Found Manifest Files:");
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
Console.WriteLine(" - Key: " + manifestItem.Key + " [Digest: " + manifestItem.PartialDigest + "]");
}
Console.WriteLine("Processing TMP files...");
string strECID = null;
string[] subdirs = System.IO.Directory.GetDirectories(firmwareRootPath);
foreach (string subdir in subdirs)
{
if (!(subdir.Contains("Per") && subdir.EndsWith(".tmp")))
continue;
Console.WriteLine(" - Entering directory: " + subdir);
ProcessSubdirectory(subdir, manifestReader, ref strECID);
}
// Process current directory
ProcessSubdirectory(firmwareRootPath, manifestReader, ref strECID);
bool blobsOK = true;
Console.WriteLine("Verifying BLOB Data...");
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
if (manifestItem.BlobData == null && manifestItem.Path != restoreRamDiskToIgnore)
{
if (manifestItem.Found)
{
Console.WriteLine(" - ERROR: Invalid signed data for " + manifestItem.Path);
}
else
{
Console.WriteLine(" - ERROR: File not found for " + manifestItem.Path);
}
blobsOK = false;
}
}
if (blobsOK)
{
Console.WriteLine("Creating custom SHSH file...");
System.IO.StreamReader shshTemplateFileHdl = new System.IO.StreamReader(Util.ReadEmbeddedResource(shshTemplateFilename));
string shshTemplateFile = shshTemplateFileHdl.ReadToEnd();
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
shshTemplateFile = shshTemplateFile.Replace("[BLOB-" + manifestItem.Path + "]", manifestItem.BlobData);
shshTemplateFile = shshTemplateFile.Replace("[DIGEST-" + manifestItem.Path + "]", manifestItem.PartialDigest);
}
System.IO.StreamWriter shshFileWriter = new System.IO.StreamWriter(outputFilename);
shshFileWriter.Write(shshTemplateFile);
shshFileWriter.Close();
if (toolMode == VersionMode.V3_0)
{
Console.WriteLine("Success! 3.0 SHSH File stored at " + outputFilename);
}
else if (toolMode == VersionMode.V3_0_1)
{
Console.WriteLine("Success! 3.0.1 SHSH File stored at " + outputFilename);
}
}
else
{
Console.WriteLine("There were errors while trying to create SHSH file.");
}
}
catch (System.Exception e)
{
Console.WriteLine("There were errors while trying to create SHSH file.");
Console.WriteLine("Diagnostic: " + e.Message + " " + e.StackTrace);
}
finally
{
Console.WriteLine("Complete.");
}
}
static bool ProcessSubdirectory(string subdir, BuildManifestReader manifestReader, ref string strECID)
{
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
if (manifestItem.BlobData != null)
continue;
string path = manifestItem.Path.Replace("/", "\\");
string searchPath = subdir + "\\" + path;
if (System.IO.File.Exists(searchPath))
{
Console.WriteLine(" - " + manifestItem.Path);
if (!ProcessFile(searchPath, manifestItem, ref strECID))
return false;
}
else
{
string fileOnly = manifestItem.Path.Substring(manifestItem.Path.LastIndexOf("/") + 1);
searchPath = subdir + "\\" + fileOnly;
if (System.IO.File.Exists(searchPath))
{
Console.WriteLine(" - [Alternate Path] " + fileOnly);
if (!ProcessFile(searchPath, manifestItem, ref strECID))
return false;
}
}
}
return true;
}
static bool ProcessFile(string filename, BuildManifestItem manifestItem, ref string strECID)
{
manifestItem.Found = true;
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(System.IO.File.OpenRead(filename));
binaryReader.BaseStream.Seek(-2125, System.IO.SeekOrigin.End);
byte[] magic = binaryReader.ReadBytes(4);
StringBuilder sb = new StringBuilder(100);
foreach (byte b in magic)
{
sb.Append((char)b);
}
string magicstr = sb.ToString();
if (magicstr != "DICE")
{
Console.WriteLine(" - ERROR: Magic string not found! (DICE)");
return false;
}
// chew bytes to get to the ecid
binaryReader.ReadBytes(8);
// get the ECID
byte[] ecid = binaryReader.ReadBytes(8);
StringBuilder sbECID = new StringBuilder(20);
for (int idxECID = ecid.Length - 1; idxECID >= 0; idxECID--)
{
sbECID.Append(ecid[idxECID].ToString("x2"));
}
string strThisECID = sbECID.ToString();
if (strECID != null && strThisECID != strECID)
{
Console.WriteLine(" - ERROR: ECID Mismatch (Had: " + strECID + " Found: " + strThisECID + ")");
return false;
}
else if (strECID == null)
{
strECID = strThisECID;
Console.WriteLine("Detected ECID: " + strECID);
}
binaryReader.BaseStream.Seek(-2125, System.IO.SeekOrigin.End);
byte[] signedBytes = binaryReader.ReadBytes(2125);
string signedBytesEncoded = System.Convert.ToBase64String(signedBytes);
StringBuilder formattedBlobDataBuilder = new StringBuilder(3000);
for (int idxChar = 0, colCount = 0; idxChar < signedBytesEncoded.Length; idxChar++, colCount++)
{
formattedBlobDataBuilder.Append(signedBytesEncoded[idxChar]);
if (colCount + 1 == 60)
{
formattedBlobDataBuilder.Append("\n\t\t");
colCount = -1;
}
}
string formattedBlobData = formattedBlobDataBuilder.ToString();
manifestItem.BlobData = formattedBlobData;
return true;
}
}
public class BuildManifestItem
{
string _key;
public string Key
{
get { return _key; }
set { _key = value; }
}
string _path;
public string Path
{
get { return _path; }
set { _path = value; }
}
string _partialDigest;
public string PartialDigest
{
get { return _partialDigest; }
set { _partialDigest = value; }
}
string _blobData;
public string BlobData
{
get { return _blobData; }
set { _blobData = value; }
}
bool _found;
public bool Found
{
get { return _found; }
set { _found = value; }
}
}
public class BuildManifestReader
{
private Dictionary<string, BuildManifestItem> _manifestItems;
public Dictionary<string, BuildManifestItem> ManifestItems
{
get { return _manifestItems; }
set { _manifestItems = value; }
}
public BuildManifestReader(string manifestFilename)
{
_manifestItems = new Dictionary<string, BuildManifestItem>();
System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(Util.ReadEmbeddedResource(manifestFilename));
string elementName = null;
bool foundManifest = false;
BuildManifestItem manifestItem = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "key" && xmlReader.Depth == 5 && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
if (xmlReader.Value == "ApBoardID")
{
foundManifest = false;
}
else if (xmlReader.Value == "Manifest")
{
foundManifest = true;
}
}
else if (elementName == "key" && xmlReader.Depth == 6 && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
if (foundManifest)
{
manifestItem = new BuildManifestItem();
manifestItem.Key = xmlReader.Value;
}
}
else if (elementName == "key" && xmlReader.NodeType == System.Xml.XmlNodeType.Text && xmlReader.Value == "Path")
{
string path = GetPath(xmlReader);
manifestItem.Path = path;
}
else if (elementName == "key" && xmlReader.NodeType == System.Xml.XmlNodeType.Text && xmlReader.Value == "PartialDigest")
{
string digest = GetPartialDigest(xmlReader);
digest = digest.Replace("\n", "");
digest = digest.Replace("\t", "");
manifestItem.PartialDigest = digest;
if (!_manifestItems.ContainsKey(manifestItem.Key + "-" + manifestItem.Path))
{
_manifestItems.Add(manifestItem.Key + "-" + manifestItem.Path, manifestItem);
}
manifestItem = null;
}
}
}
string GetPath(System.Xml.XmlReader xmlReader)
{
string elementName = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType != System.Xml.XmlNodeType.Element && xmlReader.NodeType != System.Xml.XmlNodeType.Text)
continue;
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "string" && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
return xmlReader.Value;
}
else
{
return null;
}
}
return null;
}
string GetPartialDigest(System.Xml.XmlReader xmlReader)
{
string elementName = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType != System.Xml.XmlNodeType.Element && xmlReader.NodeType != System.Xml.XmlNodeType.Text)
continue;
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "data" && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
return xmlReader.Value;
}
else
{
return null;
}
}
return null;
}
}
class Util
{
public static System.IO.Stream ReadEmbeddedResource(string resourceName)
{
System.Reflection.Assembly curAssembly = System.Reflection.Assembly.GetExecutingAssembly();
string [] resources = curAssembly.GetManifestResourceNames();
foreach (string resource in resources)
{
if (resource.EndsWith(resourceName))
{
return curAssembly.GetManifestResourceStream(resource);
}
}
return null;
}
}
} 诊断:出于安全原因,此XML文档中禁止使用DTD。努力 le DTD处理将XmlReaderSettings上的ProhibitDtd属性设置为false和 将设置传递给XmlReader.Create方法。在System.Xml.XmlTextReaderI mpl.Throw(例外e) 在System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res,String arg) 在System.Xml.XmlTextReaderImpl.ParseDoctypeDecl() 在System.Xml.XmlTextReaderImpl.ParseDocumentContent() 在System.Xml.XmlTextReaderImpl.Read() 在C:\ Users \ A中的SHSH_Tool.BuildManifestReader..ctor(String manifestFilename) dministrator \ Desktop \ shsh \ Program.cs:第323行 在C:\ Users \ Administrator \ Desktop \ sh中的SHSH_Tool.Program.Main(String [] args) sh \ Program.cs:第87行 完整。
答案 0 :(得分:0)
我认为您没有向我们提供您正在阅读的实际XML文档。它顶部可能有一个“DOCTYPE”,它指定.DTD文件。
编辑文档以使其不具有DOCTYPE,或以编程方式忽略DOCTYPE。您可以通过以下方式执行此操作:Ignore DOCTYPE .dtd, but .dtd file must still exist