static void ExtractOffsets(Stream stream, MetadataProcessor.ImageAccessor accessor, out uint csOffset, out uint sn, out uint snLen) { BinaryReader rdr = new BinaryReader(stream); stream.Seek(0x3c, SeekOrigin.Begin); uint offset = rdr.ReadUInt32(); stream.Seek(offset, SeekOrigin.Begin); stream.Seek(0x6, SeekOrigin.Current); uint sections = rdr.ReadUInt16(); stream.Seek(offset = offset + 0x18, SeekOrigin.Begin); //Optional hdr bool pe32 = (rdr.ReadUInt16() == 0x010b); csOffset = offset + 0x40; stream.Seek(offset = offset + (pe32 ? 0xE0U : 0xF0U), SeekOrigin.Begin); //sections stream.Seek(offset - 16, SeekOrigin.Begin); uint mdDir = accessor.ResolveVirtualAddress(rdr.ReadUInt32()); stream.Seek(mdDir + 0x20, SeekOrigin.Begin); sn = accessor.ResolveVirtualAddress(rdr.ReadUInt32()); snLen = rdr.ReadUInt32(); }
public override void Process(NameValueCollection parameters, Stream stream, MetadataProcessor.ImageAccessor accessor) { Random rand = new Random(); BinaryReader rdr = new BinaryReader(stream); stream.Seek(0x3c, SeekOrigin.Begin); uint offset = rdr.ReadUInt32(); stream.Seek(offset, SeekOrigin.Begin); stream.Seek(0x6, SeekOrigin.Current); uint sections = rdr.ReadUInt16(); stream.Seek(offset = offset + 0x18, SeekOrigin.Begin); //Optional hdr bool pe32 = (rdr.ReadUInt16() == 0x010b); stream.Seek(offset = offset + (pe32 ? 0xE0U : 0xF0U), SeekOrigin.Begin); //sections stream.Seek(-0xc, SeekOrigin.Current); for (int i = 0; i < sections; i++) { bool seen = false; for (int j = 0; j < 8; j++) { byte b = rdr.ReadByte(); if (b == 0 & !seen) { seen = true; stream.Seek(-1, SeekOrigin.Current); stream.WriteByte(0x20); } } uint vSize = rdr.ReadUInt32(); uint vLoc = rdr.ReadUInt32(); uint rSize = rdr.ReadUInt32(); uint rLoc = rdr.ReadUInt32(); stream.Seek(0x10, SeekOrigin.Current); } var mdPtr = accessor.ResolveVirtualAddress(accessor.GetTextSegmentRange(TextSegment.MetadataHeader).Start); stream.Position = mdPtr + 12; long verLenPos = stream.Position; uint verLen = rdr.ReadUInt32(); stream.Position += verLen; stream.Position += 2; ushort streams = rdr.ReadUInt16(); uint startOfStreams = 0xffffffff; for (int i = 0; i < streams; i++) { startOfStreams = Math.Min(rdr.ReadUInt32(), startOfStreams); stream.Position += 4; long begin = stream.Position; int c = 0; string s = ""; byte b; while ((b = rdr.ReadByte()) != 0) { s += (char)b; c++; } if (s == "#~") { stream.Position = begin + 1; stream.WriteByte((byte)'-'); } stream.Position = (stream.Position + 3) & ~3; } uint m = startOfStreams - (uint)(stream.Position - mdPtr); uint size = (uint)(stream.Position - (verLenPos + 4)); stream.Position = verLenPos; stream.Write(BitConverter.GetBytes(verLen + m), 0, 4); byte[] x = new byte[verLen]; stream.Read(x, 0, (int)verLen); byte[] t = new byte[size - verLen]; stream.Read(t, 0, (int)t.Length); stream.Position = verLenPos + 4; stream.Write(x, 0, x.Length); stream.Write(new byte[m], 0, (int)m); stream.Write(t, 0, t.Length); }
public void Phase5(Stream stream, MetadataProcessor.ImageAccessor accessor) { stream.Seek(0, SeekOrigin.Begin); uint csOffset; uint sn; uint snLen; ExtractCodes(stream, accessor, out csOffset, out sn, out snLen); stream.Position = 0; MemoryStream ms = new MemoryStream(); ms.WriteByte(0xd6); ms.WriteByte(0x6f); BinaryWriter wtr = new BinaryWriter(ms); wtr.Write((uint)codes.Length); for (int i = 0; i < codes.Length; i++) { wtr.Write((int)(ptrs[i] ^ key4)); if (ptrs[i] == 0) { continue; } Confuser.Database.AddEntry("AntiTamper", rvas[i].ToString("X8"), ms.Position); wtr.Write((int)(rvas[i] ^ key5)); wtr.Write(codes[i].Length); wtr.Write(codes[i]); } byte[] buff; BinaryReader sReader = new BinaryReader(stream); using (MemoryStream str = new MemoryStream()) { var mdPtr = accessor.ResolveVirtualAddress(accessor.GetTextSegmentRange(TextSegment.MetadataHeader).Start); stream.Position = mdPtr + 12; stream.Position += sReader.ReadUInt32() + 4; stream.Position += 2; ushort streams = sReader.ReadUInt16(); for (int i = 0; i < streams; i++) { uint offset = mdPtr + sReader.ReadUInt32(); uint size = sReader.ReadUInt32(); int c = 0; while (sReader.ReadByte() != 0) { c++; } long ori = stream.Position += (((c + 1) + 3) & ~3) - (c + 1); stream.Position = offset; str.Write(sReader.ReadBytes((int)size), 0, (int)size); stream.Position = ori; } buff = str.ToArray(); } byte[] iv; byte[] dat = Encrypt(Confuser.ObfuscationHelper, buff, ms.ToArray(), out iv, key6); byte[] md5 = MD5.Create().ComputeHash(buff); long checkSum = BitConverter.ToInt64(md5, 0) ^ BitConverter.ToInt64(md5, 8); wtr = new BinaryWriter(stream); stream.Seek(csOffset, SeekOrigin.Begin); wtr.Write(accessor.GetTextSegmentRange(TextSegment.MetadataHeader).Start ^ (uint)key0); // Write to section stream.Seek(accessor.GetSection(sectName).PointerToRawData, SeekOrigin.Begin); wtr.Write(checkSum ^ key1); wtr.Write(sn); wtr.Write(snLen); wtr.Write(iv.Length ^ key2); wtr.Write(iv); wtr.Write(dat.Length ^ key3); wtr.Write(dat); }
void ExtractCodes(Stream stream, MetadataProcessor.ImageAccessor accessor, out uint csOffset, out uint sn, out uint snLen) { BinaryReader rdr = new BinaryReader(stream); stream.Seek(0x3c, SeekOrigin.Begin); uint offset = rdr.ReadUInt32(); stream.Seek(offset, SeekOrigin.Begin); stream.Seek(0x6, SeekOrigin.Current); uint sections = rdr.ReadUInt16(); stream.Seek(offset = offset + 0x18, SeekOrigin.Begin); //Optional hdr bool pe32 = (rdr.ReadUInt16() == 0x010b); csOffset = offset + 0x40; stream.Seek(offset = offset + (pe32 ? 0xE0U : 0xF0U), SeekOrigin.Begin); //sections for (int i = 0; i < rvas.Length; i++) { if (rvas[i] == 0) { continue; } ptrs[i] = accessor.ResolveVirtualAddress(rvas[i]); stream.Seek(ptrs[i], SeekOrigin.Begin); byte b = rdr.ReadByte(); if ((b & 0x3) == 0x2) { stream.Seek((uint)b >> 2, SeekOrigin.Current); } else { stream.Seek(-1, SeekOrigin.Current); ushort f = rdr.ReadUInt16(); stream.Seek(2, SeekOrigin.Current); uint size = rdr.ReadUInt32(); stream.Seek(4 + size, SeekOrigin.Current); if ((f & 0x80) != 0) { stream.Seek((stream.Position + 3) & ~3, SeekOrigin.Begin); bool more; do { byte fl = rdr.ReadByte(); more = ((fl & 0x80) != 0); if ((fl & 0x40) != 0) { stream.Seek(-1, SeekOrigin.Current); uint sectLen = rdr.ReadUInt32() >> 8; stream.Seek(-4 + sectLen, SeekOrigin.Current); } else { byte sectLen = rdr.ReadByte(); stream.Seek(-1 + sectLen, SeekOrigin.Current); } } while (more); } } long len = stream.Position - ptrs[i]; stream.Seek(ptrs[i], SeekOrigin.Begin); codes[i] = rdr.ReadBytes((int)len); stream.Seek(ptrs[i], SeekOrigin.Begin); byte[] bs = new byte[len]; // write null to the method? //Confuser.Random.NextBytes(bs); //byte[] bs2 = bs.Reverse().ToArray(); //stream.Write(bs2, 0, (int)len / 2); //stream.Write(bs2, (int)len / 2, (int)len / 2); // write nothing but 0's to the method stream.Write(bs, 0, (int)len); } stream.Seek(offset - 16, SeekOrigin.Begin); uint mdDir = accessor.ResolveVirtualAddress(rdr.ReadUInt32()); stream.Seek(mdDir + 0x20, SeekOrigin.Begin); sn = accessor.ResolveVirtualAddress(rdr.ReadUInt32()); snLen = rdr.ReadUInt32(); }