using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace CPPConvert { public partial class frmCPPConvert : Form { public frmCPPConvert() { InitializeComponent(); } private long _Offset; private static long _lastPos = 0l; private void ReadRecord(BinaryReader br) { long curPos = FS.Position; int nxtPos = PathStartList[0]; if (nxtPos - 4 != curPos) { Console.WriteLine("curpos, nxtpos, lastpos\t{0:X08}\t{1:X08}", curPos - _lastPos, nxtPos- _lastPos); FS.Seek(nxtPos - 4, SeekOrigin.Begin); } PathStartList.RemoveAt(0); _lastPos = FS.Position; string filePath = ReadString(br); Console.WriteLine(filePath.Substring(120,filePath.Length-120)); string type = ReadString(br); int pos = (int) FS.Position; byte [] buf = ReadBuffer(br); int size = buf.Length; if (buf.Length > 4 && StartsWith(buf, " 0) { FS.Position = pos + buf.Length + 4 - misMatch; size -= misMatch; } } //Console.WriteLine("filePath={0}\r\ntype={1}", filePath, type); if(type.ToLower().Contains("procedure")) { tbResults.AppendText(string.Format("Extracted {0}\r\n",PartialName(filePath,type))); SaveFile(filePath,type,buf,size); } } private string PartialName(string filePath, string type) { int skipSlashes = 2 +type.Length - type.Replace("/", "").Length; int start = filePath.Length; while(skipSlashes-- > 0) start = filePath.LastIndexOf('/', start-1); return filePath.Substring(start+1); } private void SaveFile(string filePath, string type, byte[] buf,int size) { string fn = (tbDest.Text.EndsWith("/") ? tbDest.Text : tbDest.Text + "/") + PartialName(filePath, type); BuildPath(fn); FileStream fs = File.Create(fn); BinaryWriter bw = new BinaryWriter(fs); if (filePath.ToUpper().EndsWith(".PNG") && buf[4]==0xA) { bw.Write(buf, 0, 4); bw.Write(Encoding.ASCII.GetBytes("\xD")); bw.Write(buf, 4, size-4); } else { } bw.Write(buf,0,size); bw.Close(); } private void BuildPath(string fn) { FileInfo fi = new FileInfo(fn); fi.Directory.Create(); } private string ReadString(BinaryReader br) { byte[] buffer = ReadBuffer(br); return Encoding.BigEndianUnicode.GetString(buffer, 0, buffer.Length); } private byte[] ReadBuffer(BinaryReader br) { int size = ReadBytesToInt32(br); if (size == -1) size = 0; if(size > FS.Length || size < 0) throw(new Exception(string.Format("Location {0:X08} has a buffer that is too big {1:X08}",FS.Position,size))); byte[] buffer = new byte[size]; br.Read(buffer, 0, size); _Offset += size; return buffer; } private int ReadBytesToInt32(BinaryReader br) { byte[] buffer = new byte[4]; long off = Offset; br.Read(buffer, 0, 4); int i = BitConverter.ToInt32(buffer.Reverse().ToArray(), 0); //if(i>255) Console.WriteLine("{0:X8} - {1:X8}", off,i); _Offset += 4; return i; } private void btnBrowse_Click(object sender, EventArgs e) { ofd.FileName = tbFile.Text; if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) tbFile.Text = ofd.FileName; } private void btnBrowseDest_Click(object sender, EventArgs e) { fbd.SelectedPath = tbDest.Text; if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) tbDest.Text = fbd.SelectedPath; } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } public long Offset { get { return FS.Seek(0, SeekOrigin.Current); } } FileStream _FS; public FileStream FS { get { return _FS; } set { _FS = value; } } private List _PathStartList; public List PathStartList { get { return _PathStartList; } set { _PathStartList = value; } } private List GetPathStartList(string findIt,FileStream fs) { List lst= new List(); BinaryReader br = new BinaryReader(FS); int buflen = (int) FS.Length; byte [] buf =br.ReadBytes(buflen); byte[] bFindIt = Encoding.BigEndianUnicode.GetBytes(findIt); int findlen = bFindIt.Length; pb.Text = "Looking for C:/"; pb.Maximum = (int) fs.Length; for (int i = 0; i < buflen - 4; i++) { if (buf[i] == bFindIt[0]) { int k=0; for (; k < findlen; k++) if (buf[k + i] != bFindIt[k]) break; if (k == findlen) lst.Add(i); } pb.Value = i; } pb.Text = "Done"; br.Close(); return lst; } private bool Foundit(byte[] buf, int offset, byte [] bFindIt) { for (int i = 0; i < bFindIt.Length; i++) if (buf[i + offset] != (int)bFindIt[i]) return false; return true; } private void processToolStripMenuItem_Click(object sender, EventArgs e) { tbResults.Clear(); ConvertCPP(tbFile.Text); pb.Text = "All Done"; } private void ConvertCPP(string fileName) { FS = File.OpenRead(fileName); PathStartList = GetPathStartList("C:/", FS); //Console.WriteLine("===> {0} Paths", PathStartList.Count); FS = File.OpenRead(fileName); BinaryReader br = new BinaryReader(FS); try { _Offset = 0; int nRecords = ReadBytesToInt32(br); //Console.WriteLine("===> {0} Records", nRecords); int i = 0; pb.Text = "Splitting File"; pb.Maximum = nRecords; while (_Offset < FS.Length && nRecords-- > 0) { ReadRecord(br); pb.Value = ++i; } } catch (Exception ex) { tbResults.AppendText(string.Format("{0} - {1}-{2}\r\n{3}\r\n\r\n", fileName, ex.GetType().Name, ex.Message, ex.StackTrace)); } finally { br.Close(); } } private void allToolStripMenuItem_Click(object sender, EventArgs e) { tbResults.Clear(); FileInfo[] myFiles = new FileInfo(tbFile.Text).Directory.GetFiles("*.cpp"); foreach (FileInfo fi in myFiles) ConvertCPP(fi.FullName); pb.Text = "All Done"; } private void testToolStripMenuItem_Click(object sender, EventArgs e) { FS = File.OpenRead(tbFile.Text); PathStartList = GetPathStartList("C:/", FS); FS = File.OpenRead(tbFile.Text); BinaryReader br = new BinaryReader(FS); int nRecords = ReadBytesToInt32(br); int bytesRead = 4; int countByThree = 0; while (bytesRead < FS.Length) { if(countByThree % 3 == 0) { long curPos = FS.Position; int nxtPos = PathStartList[0]; if (nxtPos - 4 != curPos) { Console.WriteLine("curpos, nxtpos, lastpos\t{0:X08}\t{1:X08}", curPos - _lastPos, nxtPos - _lastPos); FS.Seek(nxtPos - 4, SeekOrigin.Begin); } PathStartList.RemoveAt(0); } _lastPos = FS.Position; long pos = FS.Position; int size = ReadBytesToInt32(br); bytesRead += 4; byte[] buf = br.ReadBytes(size); bytesRead += size; StringBuilder sb = new StringBuilder(); sb.Append(string.Format("{0:D4} {1:X08} {2:X08} ",countByThree ,pos,size)); for (int i = 0; i < 120 && i < size; i++) { if(buf[i] < 0x20) sb.Append('.'); else sb.Append((char) buf[i]); } Console.WriteLine(sb.ToString()); if (StartsWith(buf, " 0) { FS.Position = pos + size + 4 - misMatch; bytesRead -= misMatch; } } countByThree++; } } private bool StartsWith(byte[] buf, string findIt) { byte[] bFindIt = Encoding.ASCII.GetBytes(findIt); int findlen = bFindIt.Length; int k=0; for (; k < findlen; k++) if (buf[k] != bFindIt[k]) return false; return true; } } }