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); }
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); } }
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; } }
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; } } } }
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); }