为什么我会收到错误DTD在此文档中是不允许的?

时间:2011-02-21 17:24:55

标签: c# xml dtd

下面是代码:

// 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行 完整。

1 个答案:

答案 0 :(得分:0)

我认为您没有向我们提供您正在阅读的实际XML文档。它顶部可能有一个“DOCTYPE”,它指定.DTD文件。

编辑文档以使其不具有DOCTYPE,或以编程方式忽略DOCTYPE。您可以通过以下方式执行此操作:Ignore DOCTYPE .dtd, but .dtd file must still exist