Example #1
0
        private List <TranslateUnit> ParsePEFile()
        {
            PEUtil.ResetPEResourceIndex();
            List <TranslateUnit> result = new List <TranslateUnit>();
            int number = 0;

            byte[] binary = null;
            using (FileStream fs = new FileStream(m_peFileName, FileMode.Open))
            {
                BinaryReader br = new BinaryReader(fs);
                binary = br.ReadBytes(System.Convert.ToInt32(fs.Length));
            }

            // check if this file is PE file
            string startFlag = PEUtil.ConvertByteArrayToHexString(binary, 0, 2);

            if (!"4D5A".Equals(startFlag))
            {
                throw new Exception("This file is not a valid PE file (not start with 4D5Ah)");
            }
            string allHex = PEUtil.ConvertByteArrayToHexString(binary);

            if (!allHex.Contains("50450000"))
            {
                throw new Exception("This file is not a valid PE file (not contain with 50450000h)");
            }

            // get pe header information
            PEReader peReader = new PEReader(m_peFileName);
            string   name1    = PEUtil.GetSectionName(peReader.ImageSectionHeader[0]);

            PEResourceDataList resDataList = new PEResourceDataList();

            PEResourceEntries[] ResourceEntriesAll = peReader.ResourceEntriesAll;
            for (int i = 0; i < ResourceEntriesAll.Length; i++)
            {
                PEResourceEntries resourceEntries = ResourceEntriesAll[i];
                // which resouce should be extracted
                // first version information : 0Eh
                if (resourceEntries.level1Entry.Name_l >= 0)
                {
                    int vCount = resourceEntries.level2Entries.Length;
                    for (int j = 0; j < vCount; j++)
                    {
                        PEReader.IMAGE_RESOURCE_DIRECTORY_ENTRY level2 = resourceEntries.level2Entries[j];
                        object obj = resourceEntries.level2Map3Entries[level2];
                        PEReader.IMAGE_RESOURCE_DIRECTORY_ENTRY[] level3Array = (PEReader.IMAGE_RESOURCE_DIRECTORY_ENTRY[])obj;

                        for (int k = 0; k < level3Array.Length; k++)
                        {
                            PEResourceData resData = new PEResourceData();
                            PEReader.IMAGE_RESOURCE_DIRECTORY_ENTRY level3 = level3Array[k];
                            PEReader.IMAGE_RESOURCE_DATA_ENTRY      data   = (PEReader.IMAGE_RESOURCE_DATA_ENTRY)resourceEntries.level3DATA[level3];
                            uint dataRVA  = data.OffsetToData;
                            uint dataSize = data.Size;
                            uint resRVA   = peReader.ResourceRVA;
                            if (dataRVA < resRVA)
                            {
                                continue;
                            }

                            uint dataOffset = peReader.ResourceOffSet + (dataRVA - resRVA);
                            if (dataOffset + dataSize > binary.Length)
                            {
                                continue;
                            }

                            byte[] resourceData = new byte[dataSize];
                            Array.Copy(binary, dataOffset, resourceData, 0, dataSize);
                            string content = Encoding.Unicode.GetString(resourceData);

                            resData.ResourceType = resourceEntries.level1Entry.Name_l;
                            resData.FileOffset   = dataOffset;
                            resData.Size         = dataSize;
                            resData.Data         = resourceData;
                            resData.Content      = content;
                            resData.PEFileName   = m_peFileName;
                            resDataList.Add(resData);
                        }
                    }
                }
            }

            foreach (PEResourceData resData in resDataList)
            {
                resData.ParseData(number);
                List <TranslateUnit> tus = resData.GetTus();
                result.AddRange(tus);
                if (tus.Count != 0)
                {
                    byte[] ddd = resData.GetSrcData();
                    int    lll = ddd.Length;
                }
            }

            string peOffset   = PEUtil.GetPEHeaderAddress(allHex);
            int    h_peOffset = PEUtil.ConvertHexToInt(peOffset);

            bool     isDotNet = true;
            Assembly ass      = null;

            try
            {
                ass      = Assembly.Load(binary);
                isDotNet = true;
                m_log.Log("Loading " + m_peFileName + " with Microsoft .Net parser.");
            }
            catch (BadImageFormatException)
            {
                string name = peReader.Is32BitHeader ? "Win32" : "Win32+";
                isDotNet = false;
                m_log.Log("Loading " + m_peFileName + " with " + name + " parser.");
            }

            if (isDotNet)
            {
                // mono
                AssemblyDefinition asm    = MonoUtil.LoadAssembly(m_peFileName);
                ModuleDefinition   module = asm.MainModule;
                foreach (Resource r in module.Resources.OrderBy(m => m.Name))
                {
                    if (r is EmbeddedResource)
                    {
                        EmbeddedResource er = r as EmbeddedResource;
                        if (er != null)
                        {
                            Stream s = er.GetResourceStream();
                            s.Position = 0;
                            ResourceReader reader;
                            try
                            {
                                reader = new ResourceReader(s);
                            }
                            catch (ArgumentException ae)
                            {
                                throw ae;
                            }
                            foreach (DictionaryEntry entry in reader.Cast <DictionaryEntry>().OrderBy(e => e.Key.ToString()))
                            {
                                var keyString = entry.Key.ToString();

                                if (entry.Value is String)
                                {
                                    TranslateUnit unit = new TranslateUnit("" + (++number), keyString, "0", "0", (string)entry.Value);
                                    unit.Category = er.Name;
                                    result.Add(unit);
                                    continue;
                                }

                                if (entry.Value is byte[])
                                {
                                    Stream ms = new MemoryStream((byte[])entry.Value);
                                }

                                if (entry.Value is Stream && keyString.ToLower().EndsWith(".baml"))
                                {
                                    Stream ps = entry.Value as Stream;
                                    ps.Position = 0;

                                    string    textContent = "";
                                    string    id          = "";
                                    XDocument xdoc        = BamlUtil.LoadIntoDocument(new MyAssemblyResolver(), asm, ps);
                                    string    xxx         = xdoc.ToString();

                                    IEnumerable <XElement> elements = xdoc.Elements();
                                    XElement xroot = elements.First <XElement>();

                                    // get TextBlock
                                    //XName name = XName.Get("TextBlock", baml_xmlns);
                                    elements = XmlUtil.SelectElementsByName(xroot, "TextBlock");
                                    foreach (XElement element in elements)
                                    {
                                        XAttribute xatt = XmlUtil.SelectAttributeByName(element, "Text", "Text");
                                        if (xatt != null)
                                        {
                                            textContent = xatt.Value;
                                            id          = BamlUtil.GetTUID("Uid", XmlUtil.SelectAttributeByName(element, "Uid", "x:Uid").Value);
                                        }
                                        else
                                        {
                                            textContent = element.Value;

                                            XElement parent = element.Parent;
                                            if (parent.Name.LocalName.Equals("Button"))
                                            {
                                                id = BamlUtil.GetButtonId(parent) + ".TextBlock";
                                            }
                                        }

                                        TranslateUnit unit = new TranslateUnit("" + (++number), id, "0", "0", textContent);
                                        unit.Category = keyString;
                                        result.Add(unit);
                                    }

                                    // get Button and CheckBox : ContentControl.Content , Name
                                    //name = XName.Get("Button", baml_xmlns);
                                    //elements = xdoc.Descendants(name);
                                    elements = XmlUtil.SelectElementsByName(xroot, "Button");
                                    foreach (XElement element in elements)
                                    {
                                        XAttribute xatt = XmlUtil.SelectAttributeByName(element, "Content", "ContentControl.Content");

                                        if (xatt != null)
                                        {
                                            textContent = xatt.Value;
                                            id          = BamlUtil.GetButtonId(element) + ".Content";

                                            TranslateUnit unit = new TranslateUnit("" + (++number), id, "0", "0", textContent);
                                            unit.Category = keyString;
                                            result.Add(unit);
                                        }
                                    }
                                    //name = XName.Get("CheckBox", baml_xmlns);
                                    //elements = xdoc.Descendants(name);
                                    elements = XmlUtil.SelectElementsByName(xroot, "CheckBox");
                                    foreach (XElement element in elements)
                                    {
                                        XAttribute xatt = XmlUtil.SelectAttributeByName(element, "Content", "ContentControl.Content");

                                        if (xatt != null)
                                        {
                                            textContent = xatt.Value;
                                            id          = BamlUtil.GetButtonId(element) + ".Content";;

                                            TranslateUnit unit = new TranslateUnit("" + (++number), id, "0", "0", textContent);
                                            unit.Category = keyString;
                                            result.Add(unit);
                                        }

                                        XAttribute xatt2 = XmlUtil.SelectAttributeByName(element, "ToolTip", "FrameworkElement.ToolTip");

                                        if (xatt2 != null)
                                        {
                                            textContent = xatt2.Value;
                                            id          = BamlUtil.GetButtonId(element) + ".ToolTip";;

                                            TranslateUnit unit = new TranslateUnit("" + (++number), "0", "0", id, textContent);
                                            unit.Category = keyString;
                                            result.Add(unit);
                                        }
                                    }

                                    // others, add later
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }