예제 #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);

            // dos MZ header
            if (!"4D5A".Equals(startFlag))
            {
                throw new Exception("This file is not a valid PE file (not start with 4D5Ah)");
            }
            // PE signature PE00
            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);
        }
예제 #2
0
        private void WritePEResource(List <TranslateUnit> units)
        {
            PEUtil.ResetPEResourceIndex();
            // backup file first if none
            string backupFile = m_peFileName + ".bak";

            if (!File.Exists(backupFile))
            {
                File.Copy(m_peFileName, backupFile);
            }

            int number = 0;

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

            PEReader peReader = new PEReader(backupFile);
            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;
                            uint   dataOffset   = peReader.ResourceOffSet + (dataRVA - resRVA);
                            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();
                if (tus.Count != 0)
                {
                    byte[] ddd = resData.GetSrcData();
                    byte[] nnn = resData.Merge(units);

                    uint resOffset = resData.FileOffset;
                    uint resSize   = resData.Size;
                    PEUtil.UpdateBinary(binary, resOffset, resSize, nnn);
                }
            }

            // update resource - version first

            /*
             * PEReader peReader = new PEReader(m_peFileName);
             * 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 == PEResoourceType.RT_VERSION)
             *  {
             *      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++)
             *          {
             *              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;
             *              uint dataOffset = peReader.ResourceOffSet + (dataRVA - resRVA);
             *              byte[] resourceData = new byte[dataSize];
             *              Array.Copy(binary, dataOffset, resourceData, 0, dataSize);
             *
             *
             *              string versionInfor = Encoding.Unicode.GetString(resourceData);
             *              //string newversionInfor = versionInfor.Replace("΢ÈíÖйú", "ͯÄêÖø×÷");
             *              PEUtil.UpdateVersionInfoWithWinAPI(m_peFileName, resourceData, units);
             *              //string newversionInfor = PEUtil.UpdateVersionInfo(versionInfor, units);
             *              //byte[] newResourceData = new byte[dataSize];
             *              //newResourceData = Encoding.Unicode.GetBytes(newversionInfor);
             *
             *              //Array.Copy(newResourceData, 0, binary, dataOffset, dataSize);
             *          }
             *      }
             *  }
             * }
             */

            // write data back to file
            using (FileStream fs = new FileStream(m_peFileName, FileMode.Open))
            {
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(binary);
            }
        }
예제 #3
0
        public void ParseData(int number)
        {
            _tus      = new List <TranslateUnit>();
            _datasubs = new List <DataSub>();

            if (!TypeToHandle.Contains(this.ResourceType))
            {
                return;
            }

            int     dataIndex     = 0;
            int     subIndex      = 0;
            string  category      = null;
            PEWord  word          = null;
            DataSub datasub       = null;
            string  categoryIndex = null;
            string  content       = "";

            switch (this.ResourceType)
            {
            case PEResoourceType.RT_MENU:
                category      = "RT_MENU";
                subIndex      = 0;
                categoryIndex = "" + PEUtil.GetPEResourceIndex(PEResoourceType.RT_MENU);
                // ignore MENUHEADER struct (word, word)
                dataIndex += 4;
                datasub    = new DataSub(false);
                DataSub.AddData(Data, 0, 4, datasub.data);
                // check next option
                PEWord signWord    = PEWord.GetNextWord(Data, dataIndex);
                bool   continueGet = true;

                while (continueGet)
                {
                    content = "";
                    long          idIndex = signWord.Byte0 + signWord.Byte1 * 256;
                    TranslateUnit tu      = new TranslateUnit("" + (++number), "" + idIndex, categoryIndex, "" + (++subIndex));
                    tu.Category = category;

                    // is NormalMenuItem or not
                    if (idIndex == 1 && Data[dataIndex + 2] <= 16)
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex = dataIndex + 2;
                    }

                    DataSub.AddData(Data, dataIndex, 2, datasub.data);
                    _datasubs.Add(datasub);
                    dataIndex = dataIndex + 2;

                    datasub = new DataSub(true);

                    word = PEWord.GetNextWord(Data, dataIndex);
                    while (word != null && !word.IsEmpty())
                    {
                        content = content + word.ToUnicodeStr();
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex = dataIndex + 2;
                        word      = PEWord.GetNextWord(Data, dataIndex);
                    }

                    tu.SourceContent = content;
                    _tus.Add(tu);
                    _datasubs.Add(datasub);

                    if (word == null)
                    {
                        continueGet = false;
                    }
                    else
                    {
                        datasub = new DataSub(false);
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);

                        while (word.IsEmpty())
                        {
                            dataIndex = dataIndex + 2;
                            word      = PEWord.GetNextWord(Data, dataIndex);

                            if (word == null)
                            {
                                continueGet = false;
                                break;
                            }

                            if (word.IsEmpty())
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            }
                        }
                    }

                    if (continueGet && !word.IsEmpty())
                    {
                        if (word.Byte0 == PEResourceSign.MFR_END)
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex = dataIndex + 2;
                            signWord  = PEWord.GetNextWord(Data, dataIndex);
                        }
                        else
                        {
                            signWord = word;
                        }
                    }
                }

                _datasubs.Add(datasub);
                // end of RE_MENU

                // remove tus if error
                if (!XmlUtil.TryWriteTus(_tus))
                {
                    ClearThisData();
                }

                break;

            case PEResoourceType.RT_STRING:
                category      = "RT_STRING";
                subIndex      = 0;
                categoryIndex = "" + PEUtil.GetPEResourceIndex(PEResoourceType.RT_STRING);

                PEWord w = PEWord.GetNextWord(Data, dataIndex);
                datasub = new DataSub(false);
                while (w != null)
                {
                    if (w.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex = dataIndex + 2;
                        w         = PEWord.GetNextWord(Data, dataIndex);
                    }
                    else
                    {
                        string idIndex = "" + _tus.Count;
                        int    count   = w.Byte1 * 256 + w.Byte0;

                        // cannot handle this TR_STRING, clear it.
                        if (count * 2 + dataIndex > Data.Length)
                        {
                            ClearThisData();
                            break;
                        }

                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        _datasubs.Add(datasub);

                        dataIndex = dataIndex + 2;
                        content   = PEWord.GetNextWords(Data, dataIndex, count * 2);
                        datasub   = new DataSub(true);
                        DataSub.AddData(Data, dataIndex, count * 2, datasub.data);

                        dataIndex = dataIndex + count * 2;
                        w         = PEWord.GetNextWord(Data, dataIndex);

                        if (w != null)
                        {
                            count = w.Byte1 * 256 + w.Byte0;
                            while (w != null && !w.IsEmpty() && Data.Length - dataIndex < count * 2)
                            {
                                content += w.ToUnicodeStr();
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                w          = PEWord.GetNextWord(Data, dataIndex);
                                if (w != null)
                                {
                                    count = w.Byte1 * 256 + w.Byte0;
                                }
                            }
                        }

                        _datasubs.Add(datasub);
                        datasub = new DataSub(false);

                        TranslateUnit tu = new TranslateUnit("" + (++number), idIndex, categoryIndex, "" + (++subIndex));
                        tu.Category      = category;
                        tu.SourceContent = content;
                        _tus.Add(tu);
                    }
                }

                _datasubs.Add(datasub);
                // end of RE_STRING

                // remove tus if error
                if (!XmlUtil.TryWriteTus(_tus))
                {
                    ClearThisData();
                }

                break;

            case PEResoourceType.RT_DIALOG:
                category      = "RT_DIALOG";
                subIndex      = 0;
                categoryIndex = "" + PEUtil.GetPEResourceIndex(PEResoourceType.RT_DIALOG);

                // extract extend dialog : DLGTEMPLATEEX DLGITEMTEMPLATEEX
                PEDWord dw = PEDWord.GetNextDWord(Data, 0);
                if (dw.Byte0 == 1 && dw.Byte1 == 0 && dw.Byte2 == 255 && dw.Byte3 == 255)
                {
                    // first 22 bytes
                    datasub = new DataSub(false);
                    DataSub.AddData(Data, dataIndex, 22, datasub.data);
                    dataIndex = 22;

                    // styles dword : 12 13 14 15
                    long   ddd      = 40L;
                    long   lll      = 8L;
                    long   ned      = ddd | lll;
                    string hext     = PEUtil.ConvertByteArrayToHexString(Data, 12, 4);
                    int    style    = PEUtil.ConvertHexToInt(hext);
                    bool   setStyle = (style == ddd || style == ned);

                    // todo: check menu and windowsClass
                    // short   menu : 0000
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else if (word.Byte0 == 255 && word.Byte1 == 255)
                    {
                        DataSub.AddData(Data, dataIndex, 4, datasub.data);
                        dataIndex += 4;
                    }
                    else
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;

                        word = PEWord.GetNextWord(Data, dataIndex);
                        while (!word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    // short   windowClass : 0000
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else if (word.Byte0 == 255 && word.Byte1 == 255)
                    {
                        DataSub.AddData(Data, dataIndex, 4, datasub.data);
                        dataIndex += 4;
                    }
                    else
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;

                        word = PEWord.GetNextWord(Data, dataIndex);
                        while (!word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }

                    // title or not : 0000 or title
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else
                    {
                        _datasubs.Add(datasub);
                        datasub = new DataSub(true);

                        content = "";
                        while (!word.IsEmpty())
                        {
                            content += word.ToUnicodeStr();
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        TranslateUnit tu = new TranslateUnit("" + (++number), "0", categoryIndex, "" + (++subIndex));
                        tu.Category      = category;
                        tu.SourceContent = content;
                        _tus.Add(tu);

                        _datasubs.Add(datasub);
                        datasub = new DataSub(false);
                        while (word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }
                    }

                    bool firstLap = true;
                    // DLGITEMTEMPLATEEX
                    // pointsize word, weight word, italic byte, charset byte, typeface WCHAR[stringLen]
                    if (!setStyle)
                    {
                        while (dataIndex < Size - 27)
                        {
                            // find 80 and start again
                            if (firstLap)
                            {
                                firstLap = false;
                                word     = PEWord.GetNextWord(Data, dataIndex);

                                while (word.Byte1 != 80)
                                {
                                    DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                    dataIndex += 2;
                                    word       = PEWord.GetNextWord(Data, dataIndex);

                                    if (word == null)
                                    {
                                        _datasubs.Add(datasub);
                                        return;
                                    }
                                }

                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }

                            // DLGITEMTEMPLATEEX following
                            // first 12
                            DataSub.AddData(Data, dataIndex, 12, datasub.data);
                            dataIndex += 12;

                            // windowClass : 0xFFFF or not
                            word = PEWord.GetNextWord(Data, dataIndex);

                            //0x0080 Button
                            //0x0081 Edit
                            //0x0082 Static
                            //0x0083 List box
                            //0x0084 Scroll bar
                            //0x0085 Combo box
                            if (word.Byte0 == 255 && word.Byte1 == 255)
                            {
                                DataSub.AddData(Data, dataIndex, 4, datasub.data);
                                dataIndex += 4;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }
                            //a null-terminated Unicode string
                            else
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                                while (!word.IsEmpty())
                                {
                                    DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                    dataIndex += 2;
                                    word       = PEWord.GetNextWord(Data, dataIndex);
                                }

                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }

                            // title  : 0xFFFF or not
                            // If the first element of this array is 0xFFFF, the array has one additional element
                            // that specifies the ordinal value of a resource, such as an icon, in an executable file.
                            if (word.IsEmpty())
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }
                            else if (word.Byte0 == 255 && word.Byte1 == 255)
                            {
                                DataSub.AddData(Data, dataIndex, 4, datasub.data);
                                dataIndex += 4;

                                _datasubs.Add(datasub);
                                word = PEWord.GetNextWord(Data, dataIndex);
                            }
                            //a null-terminated Unicode string
                            else
                            {
                                _datasubs.Add(datasub);
                                datasub = new DataSub(true);
                                word    = PEWord.GetNextWord(Data, dataIndex);
                                content = "";
                                while (!word.IsEmpty())
                                {
                                    content += word.ToUnicodeStr();
                                    DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                    dataIndex += 2;
                                    word       = PEWord.GetNextWord(Data, dataIndex);
                                }

                                TranslateUnit tu = new TranslateUnit("" + (++number), "0", categoryIndex, "" + (++subIndex));
                                tu.Category      = category;
                                tu.SourceContent = content;
                                _tus.Add(tu);

                                _datasubs.Add(datasub);
                                datasub = new DataSub(false);
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }

                            // creat data : 0x0000 or length
                            while (word != null)
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);

                                if (word != null && word.Byte1 == 80)
                                {
                                    dataIndex += 2;
                                    word       = PEWord.GetNextWord(Data, dataIndex);
                                    break;
                                }
                            }
                        }

                        if (dataIndex < Size)
                        {
                            datasub = new DataSub(false);
                            DataSub.AddData(Data, dataIndex, (int)Size - dataIndex, datasub.data);
                            _datasubs.Add(datasub);
                        }
                    }
                }
                // extract common dialog : DLGTEMPLATE DLGITEMTEMPLATE
                else
                {
                    // first 14 bytes
                    datasub = new DataSub(false);
                    DataSub.AddData(Data, dataIndex, 14, datasub.data);
                    dataIndex = 14;

                    // todo: check menu and windowsClass
                    // short   menu : 0000
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else if (word.Byte0 == 255 && word.Byte1 == 255)
                    {
                        DataSub.AddData(Data, dataIndex, 4, datasub.data);
                        dataIndex += 4;
                    }
                    else
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;

                        word = PEWord.GetNextWord(Data, dataIndex);
                        while (!word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    // short   windowClass : 0000
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else if (word.Byte0 == 255 && word.Byte1 == 255)
                    {
                        DataSub.AddData(Data, dataIndex, 4, datasub.data);
                        dataIndex += 4;
                    }
                    else
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;

                        word = PEWord.GetNextWord(Data, dataIndex);
                        while (!word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }

                    // title or not : 0000 or title
                    word = PEWord.GetNextWord(Data, dataIndex);
                    if (word.IsEmpty())
                    {
                        DataSub.AddData(Data, dataIndex, 2, datasub.data);
                        dataIndex += 2;
                    }
                    else
                    {
                        _datasubs.Add(datasub);
                        datasub = new DataSub(true);

                        content = "";
                        while (word != null && !word.IsEmpty())
                        {
                            content += word.ToUnicodeStr();
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        TranslateUnit tu = new TranslateUnit("" + (++number), "0", categoryIndex, "" + (++subIndex));
                        tu.Category      = category;
                        tu.SourceContent = content;
                        _tus.Add(tu);

                        _datasubs.Add(datasub);
                        datasub = new DataSub(false);
                        if (word != null)
                        {
                            while (word.IsEmpty())
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }
                        }
                    }

                    bool firstLap = true;
                    // DLGITEMTEMPLATE
                    while (dataIndex < Size - 21)
                    {
                        // find 80 and start again
                        if (firstLap)
                        {
                            firstLap = false;
                            word     = PEWord.GetNextWord(Data, dataIndex);

                            while (word.Byte1 != 80)
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);

                                if (word == null)
                                {
                                    _datasubs.Add(datasub);
                                    return;
                                }
                            }

                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        // DLGITEMTEMPLATE following
                        // first 14
                        DataSub.AddData(Data, dataIndex, 14, datasub.data);
                        dataIndex += 14;

                        // windowClass : 0xFFFF or not
                        word = PEWord.GetNextWord(Data, dataIndex);

                        //0x0080 Button
                        //0x0081 Edit
                        //0x0082 Static
                        //0x0083 List box
                        //0x0084 Scroll bar
                        //0x0085 Combo box
                        if (word.Byte0 == 255 && word.Byte1 == 255)
                        {
                            DataSub.AddData(Data, dataIndex, 4, datasub.data);
                            dataIndex += 4;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }
                        //a null-terminated Unicode string
                        else
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                            while (!word.IsEmpty())
                            {
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }

                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        // title  : 0xFFFF or not
                        // If the first element of this array is 0xFFFF, the array has one additional element
                        // that specifies the ordinal value of a resource, such as an icon, in an executable file.
                        if (word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }
                        else if (word.Byte0 == 255 && word.Byte1 == 255)
                        {
                            DataSub.AddData(Data, dataIndex, 4, datasub.data);
                            dataIndex += 4;

                            _datasubs.Add(datasub);
                            word = PEWord.GetNextWord(Data, dataIndex);
                        }
                        //a null-terminated Unicode string
                        else
                        {
                            _datasubs.Add(datasub);
                            datasub = new DataSub(true);
                            word    = PEWord.GetNextWord(Data, dataIndex);
                            content = "";
                            while (!word.IsEmpty())
                            {
                                content += word.ToUnicodeStr();
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                            }

                            TranslateUnit tu = new TranslateUnit("" + (++number), "0", categoryIndex, "" + (++subIndex));
                            tu.Category      = category;
                            tu.SourceContent = content;
                            _tus.Add(tu);

                            _datasubs.Add(datasub);
                            datasub = new DataSub(false);
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }

                        // creat data : 0x0000 or length
                        while (word != null)
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);

                            if (word != null && word.Byte1 == 80)
                            {
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                                break;
                            }
                        }
                    }

                    if (dataIndex < Size)
                    {
                        datasub = new DataSub(false);
                        DataSub.AddData(Data, dataIndex, (int)Size - dataIndex, datasub.data);
                        _datasubs.Add(datasub);
                    }
                }

                // end of RT_DIALOG

                // remove tus if error
                if (!XmlUtil.TryWriteTus(_tus))
                {
                    ClearThisData();
                }

                break;

            case PEResoourceType.RT_VERSION:
                category      = "RT_VERSION";
                subIndex      = 0;
                dataIndex     = 0;
                categoryIndex = "" + PEUtil.GetPEResourceIndex(PEResoourceType.RT_VERSION);

                word = PEWord.GetNextWord(Data, dataIndex);
                int wLength_VERSION = word.Byte0 + 256 * word.Byte1;

                dataIndex += 2;
                word       = PEWord.GetNextWord(Data, dataIndex);
                int wValueLength_VERSION = word.Byte0 + 256 * word.Byte1;

                int fileInfoIndex = PEUtil.GetIndexOfArray(Data, PEResourceSign.VERSION_StringFileInfo_1);
                if (fileInfoIndex != -1)
                {
                    dataIndex = fileInfoIndex - 2;
                    word      = PEWord.GetNextWord(Data, dataIndex);
                    int wLength_StringFileInfo = word.Byte0 + 256 * word.Byte1;
                    int end_StringFileInfo     = dataIndex + wLength_StringFileInfo;

                    // find String structure
                    dataIndex = dataIndex + PEResourceSign.VERSION_StringFileInfo_1.Length + 2;
                    word      = PEWord.GetNextWord(Data, dataIndex);

                    while (word.IsEmpty())
                    {
                        dataIndex += 2;
                        word       = PEWord.GetNextWord(Data, dataIndex);
                    }

                    // starting of StringTable
                    int wLength_StringTable = word.Byte0 + 256 * word.Byte1;
                    dataIndex += 22;
                    datasub    = new DataSub(false);
                    DataSub.AddData(Data, 0, dataIndex, datasub.data);

                    word = PEWord.GetNextWord(Data, dataIndex);

                    if (word.IsEmpty())
                    {
                        while (word.IsEmpty())
                        {
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);
                        }
                    }
                    _datasubs.Add(datasub);

                    // starting of String
                    while (dataIndex < end_StringFileInfo)
                    {
                        datasub = new DataSub(false);
                        PEWord wLength_String      = PEWord.GetNextWord(Data, dataIndex);
                        PEWord wValueLength_String = PEWord.GetNextWord(Data, dataIndex + 2);

                        int wLength_String_int      = wLength_String.Byte0 + 256 * wLength_String.Byte1;
                        int wValueLength_String_int = 2 * (wValueLength_String.Byte0 + 256 * wValueLength_String.Byte1);

                        // get id
                        string id      = "";
                        int    idIndex = dataIndex + 6;
                        PEWord nw      = PEWord.GetNextWord(Data, idIndex);

                        if (nw.Byte0 == 1 && nw.Byte1 == 0)
                        {
                            idIndex += 2;
                            nw       = PEWord.GetNextWord(Data, idIndex);
                        }

                        while (!nw.IsEmpty())
                        {
                            id      += nw.ToUnicodeStr();
                            idIndex += 2;
                            nw       = PEWord.GetNextWord(Data, idIndex);
                        }

                        int startOfValue = wLength_String_int - wValueLength_String_int;

                        if (startOfValue < 0 || startOfValue < (id.Length * 2 + 6))
                        {
                            startOfValue = wLength_String_int - wValueLength_String_int / 2;
                        }

                        if (startOfValue < 0)
                        {
                            while (nw.IsEmpty())
                            {
                                idIndex += 2;
                                nw       = PEWord.GetNextWord(Data, idIndex);
                            }

                            startOfValue = idIndex - dataIndex;
                        }

                        // miss first char of AdobeConverter.exe
                        word = PEWord.GetNextWord(Data, dataIndex + startOfValue - 2);
                        if (!word.IsEmpty())
                        {
                            startOfValue = startOfValue - 2;
                        }

                        word = PEWord.GetNextWord(Data, dataIndex + startOfValue);
                        while (word.IsEmpty())
                        {
                            startOfValue = startOfValue + 2;
                            word         = PEWord.GetNextWord(Data, dataIndex + startOfValue);
                        }

                        DataSub.AddData(Data, dataIndex, startOfValue, datasub.data);
                        _datasubs.Add(datasub);
                        dataIndex += startOfValue;
                        content    = "";
                        datasub    = new DataSub(true);
                        word       = PEWord.GetNextWord(Data, dataIndex);

                        while (content.Length < wValueLength_String_int / 2)
                        {
                            content += word.ToUnicodeStr();
                            DataSub.AddData(Data, dataIndex, 2, datasub.data);
                            dataIndex += 2;
                            word       = PEWord.GetNextWord(Data, dataIndex);

                            if (word.IsEmpty())
                            {
                                _datasubs.Add(datasub);

                                datasub = new DataSub(false);
                                DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                dataIndex += 2;
                                word       = PEWord.GetNextWord(Data, dataIndex);
                                while (word != null && word.IsEmpty())
                                {
                                    DataSub.AddData(Data, dataIndex, 2, datasub.data);
                                    dataIndex += 2;
                                    word       = PEWord.GetNextWord(Data, dataIndex);
                                }

                                break;
                            }
                        }

                        TranslateUnit tu = new TranslateUnit("" + (++number), id, categoryIndex, "" + (++subIndex));
                        tu.Category      = category;
                        tu.SourceContent = content;
                        _tus.Add(tu);

                        _datasubs.Add(datasub);
                    }

                    datasub = new DataSub(false);
                    DataSub.AddData(Data, dataIndex, Data.Length - dataIndex, datasub.data);
                    _datasubs.Add(datasub);
                }

                // end of RT_VERSION

                // remove tus if error
                if (!XmlUtil.TryWriteTus(_tus))
                {
                    ClearThisData();
                }

                break;
            }
        }
예제 #4
0
        public PEReader(string filePath)
        {
            // Read in the DLL or EXE and get the timestamp
            using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                BinaryReader reader = new BinaryReader(stream);
                dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader);

                // Add 4 bytes to the offset
                stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);

                UInt32 ntHeadersSignature = reader.ReadUInt32();
                fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader);
                if (this.Is32BitHeader)
                {
                    optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader);
                }
                else
                {
                    optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader);
                }

                // image data directory
                int numberOfRvaAndSizes = (int)((this.Is32BitHeader) ? optionalHeader32.NumberOfRvaAndSizes : optionalHeader64.NumberOfRvaAndSizes);
                imageDataDirectory = new IMAGE_DATA_DIRECTORY[numberOfRvaAndSizes];

                for (int i = 0; i < numberOfRvaAndSizes; i++)
                {
                    IMAGE_DATA_DIRECTORY direc = FromBinaryReader <IMAGE_DATA_DIRECTORY>(reader);
                    imageDataDirectory[i] = direc;
                }

                // image section header, optionalHeader offset 18h = 24
                uint optionSize = fileHeader.SizeOfOptionalHeader;
                stream.Seek(dosHeader.e_lfanew + 24 + optionSize, SeekOrigin.Begin);

                imageSectionHeader = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections];
                for (int i = 0; i < FileHeader.NumberOfSections; i++)
                {
                    IMAGE_SECTION_HEADER sectionHeader = FromBinaryReader <IMAGE_SECTION_HEADER>(reader);
                    imageSectionHeader[i] = sectionHeader;
                }

                // read resource
                IMAGE_DATA_DIRECTORY resourceDataDirectory = imageDataDirectory[2];
                uint resDataRVA  = resourceDataDirectory.VirtualAddress;
                uint resDataSize = resourceDataDirectory.Size;
                uint resEndRVA   = resDataRVA + resDataSize;
                resource_offset      = 0;
                resource_rva         = 0;
                resource_rawDataSize = 0;
                foreach (IMAGE_SECTION_HEADER sectionHeader in imageSectionHeader)
                {
                    uint secRVA    = sectionHeader.VirtualAddress;
                    uint secEndRVA = secRVA + sectionHeader.SizeOfRawData;
                    if (secRVA <= resDataRVA && resEndRVA > secRVA && secEndRVA >= resEndRVA)
                    {
                        resource_offset      = sectionHeader.PointerToRawData;
                        resource_rva         = secRVA;
                        resource_rawDataSize = sectionHeader.SizeOfRawData;
                    }
                }

                if (resource_offset == 0)
                {
                    ResourceEntry_ALL = new PEResourceEntries[0];
                }
                else
                {
                    stream.Seek(resource_offset, SeekOrigin.Begin);

                    // resource level 1
                    IMAGE_RESOURCE_DIRECTORY d1 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                    int entriesCount1           = d1.NumberOfIdEntries + d1.NumberOfNamedEntries;
                    IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries1 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount1];
                    ResourceEntry_ALL = new PEResourceEntries[entriesCount1];
                    for (int i = 0; i < entriesCount1; i++)
                    {
                        IMAGE_RESOURCE_DIRECTORY_ENTRY entry = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                        entries1[i] = entry;
                    }

                    for (int i = 0; i < entriesCount1; i++)
                    {
                        IMAGE_RESOURCE_DIRECTORY_ENTRY entry = entries1[i];
                        PEResourceEntries resEntries         = new PEResourceEntries();
                        resEntries.level1Entry       = entry;
                        resEntries.level2Map3Entries = new Hashtable();
                        resEntries.level3DATA        = new Hashtable();

                        // level 2
                        // type
                        long offset_2 = resource_offset + entry.OffsetToData_l;
                        stream.Seek(offset_2, SeekOrigin.Begin);
                        if (PEUtil.ConvertIntToBin((int)entry.OffsetToData_h).StartsWith("1"))
                        {
                            IMAGE_RESOURCE_DIRECTORY d2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                            int entriesCount2           = d2.NumberOfIdEntries + d2.NumberOfNamedEntries;
                            IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries2 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount2];
                            for (int ii = 0; ii < entriesCount2; ii++)
                            {
                                IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                                entries2[ii] = entry2;
                            }
                            resEntries.level2Entries = entries2;

                            // level 3
                            for (int j = 0; j < entriesCount2; j++)
                            {
                                IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = entries2[j];
                                // type
                                long offset_3 = resource_offset + entry2.OffsetToData_l;
                                stream.Seek(offset_3, SeekOrigin.Begin);

                                IMAGE_RESOURCE_DIRECTORY d3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader);
                                int entriesCount3           = d3.NumberOfIdEntries + d3.NumberOfNamedEntries;
                                IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries3 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount3];
                                for (int k = 0; k < entriesCount3; k++)
                                {
                                    IMAGE_RESOURCE_DIRECTORY_ENTRY entry3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader);
                                    entries3[k] = entry3;

                                    long offset_4 = resource_offset + entry3.OffsetToData_l;
                                    stream.Seek(offset_4, SeekOrigin.Begin);
                                    IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader <IMAGE_RESOURCE_DATA_ENTRY>(reader);

                                    if (!resEntries.level3DATA.ContainsKey(entry3))
                                    {
                                        resEntries.level3DATA.Add(entry3, dataEntry);
                                    }
                                }
                                resEntries.level2Map3Entries.Add(entry2, entries3);
                            }
                        }
                        else
                        {
                            throw new Exception("Resource level 2 OffsetToData_h can not start with 0");
                            //                        IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader<IMAGE_RESOURCE_DATA_ENTRY>(reader);
                        }

                        ResourceEntry_ALL[i] = resEntries;
                    }
                }
            }
        }
예제 #5
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);

            // dos MZ header
            if (!"4D5A".Equals(startFlag))
            {
                throw new Exception("This file is not a valid PE file (not start with 4D5Ah)");
            }
            // PE signature PE00
            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)
            {
                throw new Exception("This file is a .NET file which is not support now.");
            }

            return(result);
        }