public static byte[] XOR(byte[] inputStream)
{
#region Consts
// Size of Version field in RPC_HEADER_EXT
const int RpcHeaderExtVersionByteSize = 2;
// Size of Flags field in RPC_HEADER_EXT
const int RpcHeaderExtFlagsByteSize = 2;
// The length of RPC_HEADER_EXT.
const int RPCHeaderExtLength = 8;
// The value that each byte to be obfuscated has XOR applied with, section 3.1.4.11.1.3.
const byte XorMask = 0xA5;
#endregion
if (inputStream == null)
{
throw new ArgumentNullException("inputStream");
}
if (inputStream.Length < RPCHeaderExtLength)
{
throw new ArgumentException("Input must contain valid RPC_HEADER_EXT.", "inputStream");
}
ushort size = BitConverter.ToUInt16(inputStream, RpcHeaderExtVersionByteSize + RpcHeaderExtFlagsByteSize);
byte[] outStream = new byte[size + RPCHeaderExtLength];
// Copy RPC_HEADER_EXT header info
Array.Copy(inputStream, 0, outStream, 0, RPCHeaderExtLength);
// Update XorMagic flag.
RpcHeaderExtFlags flag = (RpcHeaderExtFlags)BitConverter.ToInt16(inputStream, RpcHeaderExtVersionByteSize);
flag ^= RpcHeaderExtFlags.XorMagic;
Array.Copy(BitConverter.GetBytes((short)flag), 0, outStream, RpcHeaderExtVersionByteSize, RpcHeaderExtFlagsByteSize);
// Obfuscate data by applying XOR to each byte with the value 0xA5
for (uint counter = RPCHeaderExtLength; counter < outStream.Length; counter++)
{
outStream[counter] = (byte)(inputStream[counter] ^ XorMask);
}
return outStream;
}