Ejemplo n.º 1
0
		void GetCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var nameInfo = DecryptFieldName(info.field.Name.String);
			Extract_v17_r73740(creatorInfo, nameInfo, out uint arg, out uint table, out bool isCallvirt);
			uint token = (arg ^ creatorInfo.magic) | table;

			calledMethod = module.ResolveToken((int)token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 2
0
		void GetCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var nameInfo = DecryptFieldName(info.field.Name.String);
			Extract_v17_r73740(creatorInfo, nameInfo, out uint arg, out uint table, out bool isCallvirt);
			if (x86emu == null)
				x86emu = new X86Emulator(fileData);
			uint token = x86emu.Emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;

			calledMethod = module.ResolveToken((int)token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 3
0
		static OpCode GetCallOpCode(ProxyCreatorInfo info, bool isCallvirt) {
			switch (info.proxyCreatorType) {
			case ProxyCreatorType.Newobj:
				return OpCodes.Newobj;

			case ProxyCreatorType.CallOrCallvirt:
				return isCallvirt ? OpCodes.Callvirt : OpCodes.Call;

			default: throw new NotImplementedException();
			}
		}
Ejemplo n.º 4
0
		void GetCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
			var sig = module.ReadBlob(info.field.MDToken.Raw);
			int len = sig.Length;
			uint magic = (uint)((sig[len - 2] << 24) | (sig[len - 3] << 16) | (sig[len - 5] << 8) | sig[len - 6]);
			uint rid = getRid(creatorInfo, magic);
			int token = (sig[len - 7] << 24) | (int)rid;
			uint table = (uint)token >> 24;
			if (table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");
			calledMethod = module.ResolveToken(token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, info.field);
		}
Ejemplo n.º 5
0
		static OpCode GetCallOpCode(ProxyCreatorInfo info, FieldDef field) {
			switch (info.proxyCreatorType) {
			case ProxyCreatorType.CallOrCallvirt:
				if (field.Name.String.Length > 0 && field.Name.String[0] == info.callvirtChar)
					return OpCodes.Callvirt;
				return OpCodes.Call;

			case ProxyCreatorType.Newobj:
				return OpCodes.Newobj;

			default: throw new NotSupportedException();
			}
		}
Ejemplo n.º 6
0
		void GetCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 1 : 0;
			var nameInfo = DecryptFieldName(info.field.Name.String);

			uint token = BitConverter.ToUInt32(nameInfo, offs) ^ creatorInfo.magic;
			uint table = token >> 24;
			if (table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");

			calledMethod = module.ResolveToken(token) as IMethod;

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && nameInfo[0] == '\r')
				isCallvirt = true;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 7
0
		void Extract_v17_r73740(ProxyCreatorInfo creatorInfo, byte[] nameInfo, out uint arg, out uint table, out bool isCallvirt) {
			switch (creatorInfo.proxyCreatorType) {
			case ProxyCreatorType.CallOrCallvirt:
				arg = BitConverter.ToUInt32(nameInfo, 1);
				table = (uint)(nameInfo[0] & 0x7F) << 24;
				isCallvirt = (nameInfo[0] & 0x80) != 0;
				break;

			case ProxyCreatorType.Newobj:
				arg = BitConverter.ToUInt32(nameInfo, 0);
				table = (uint)nameInfo[4] << 24;
				isCallvirt = false;
				break;

			default:
				throw new ApplicationException("Invalid creator type");
			}
		}
Ejemplo n.º 8
0
		void GetCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var reader = new BinaryReader(new MemoryStream(info.data));

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt)
				isCallvirt = reader.ReadBoolean();

			var asmRef = ReadAssemblyNameReference(reader);
			// If < 1.0 r42919, then high byte is 06, else it's cleared.
			uint token = (reader.ReadUInt32() & 0x00FFFFFF) | 0x06000000;
			if (reader.BaseStream.Position != reader.BaseStream.Length)
				throw new ApplicationException("Extra data");

			if (asmRef.FullName == ourAsm)
				calledMethod = module.ResolveToken(token) as IMethod;
			else
				calledMethod = CreateMethodReference(asmRef, token);

			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 9
0
		void GetCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			bool isNew = creatorInfo.version == ConfuserVersion.v14_r58802;

			int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 2 : 1;
			if (isNew)
				offs--;
			int callvirtOffs = isNew ? 0 : 1;

			// This is an obfuscator bug. Field names are stored in the #Strings heap,
			// and strings in that heap are UTF8 zero terminated strings, but Confuser
			// can generate names with zeros in them. This was fixed in 1.4 58857.
			if (offs + 2 > info.field.Name.String.Length) {
				calledMethod = null;
				callOpcode = OpCodes.Call;
				return;
			}

			uint token = BitConverter.ToUInt32(Encoding.Unicode.GetBytes(info.field.Name.String.ToCharArray(), offs, 2), 0) ^ creatorInfo.magic;
			uint table = token >> 24;
			if (table != 0 && table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");

			// 1.3 r55346 now correctly uses method reference tokens and finally fixed the old
			// bug of using methoddef tokens to reference external methods.
			if (isNew || info.field.Name.String[0] == (char)1 || table != 0x06)
				calledMethod = module.ResolveToken(token) as IMethod;
			else {
				var asmRef = module.ResolveAssemblyRef((uint)info.field.Name.String[0] - 2 + 1);
				calledMethod = CreateMethodReference(asmRef, token);
			}

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && info.field.Name.String[callvirtOffs] == '\r')
				isCallvirt = true;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 10
0
		void GetCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var reader = new BinaryReader(new MemoryStream(info.data));

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt)
				isCallvirt = reader.ReadBoolean();

			var asmRef = ReadAssemblyNameReference(reader);
			// If < 1.0 r42919, then high byte is 06, else it's cleared.
			uint token = (reader.ReadUInt32() & 0x00FFFFFF) | 0x06000000;
			if (reader.BaseStream.Position != reader.BaseStream.Length)
				throw new ApplicationException("Extra data");

			if (asmRef.FullName == ourAsm)
				calledMethod = module.ResolveToken(token) as IMethod;
			else
				calledMethod = CreateMethodReference(asmRef, token);

			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 11
0
		void GetCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 1 : 0;
			var nameInfo = DecryptFieldName(info.field.Name.String);

			uint token = BitConverter.ToUInt32(nameInfo, offs) ^ creatorInfo.magic;
			uint table = token >> 24;
			if (table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");

			calledMethod = module.ResolveToken(token) as IMethod;

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && nameInfo[0] == '\r')
				isCallvirt = true;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 12
0
		void Extract_v17_r73740(ProxyCreatorInfo creatorInfo, byte[] nameInfo, out uint arg, out uint table, out bool isCallvirt) {
			switch (creatorInfo.proxyCreatorType) {
			case ProxyCreatorType.CallOrCallvirt:
				arg = BitConverter.ToUInt32(nameInfo, 1);
				table = (uint)(nameInfo[0] & 0x7F) << 24;
				isCallvirt = (nameInfo[0] & 0x80) != 0;
				break;

			case ProxyCreatorType.Newobj:
				arg = BitConverter.ToUInt32(nameInfo, 0);
				table = (uint)nameInfo[4] << 24;
				isCallvirt = false;
				break;

			default:
				throw new ApplicationException("Invalid creator type");
			}
		}
Ejemplo n.º 13
0
		void GetCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) =>
			GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
				if (x86emu == null)
					x86emu = new X86Emulator(fileData);
				return x86emu.Emulate((uint)creatorInfo2.nativeMethod.RVA, magic);
			});
Ejemplo n.º 14
0
		void GetCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) =>
			GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => creatorInfo2.magic ^ magic);
Ejemplo n.º 15
0
		void GetCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var nameInfo = DecryptFieldName(info.field.Name.String);
			uint arg, table;
			bool isCallvirt;
			Extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
			uint token = (arg ^ creatorInfo.magic) | table;

			calledMethod = module.ResolveToken((int)token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 16
0
		void GetCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			var nameInfo = DecryptFieldName(info.field.Name.String);
			uint arg, table;
			bool isCallvirt;
			Extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
			if (x86emu == null)
				x86emu = new x86Emulator(fileData);
			uint token = x86emu.Emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;

			calledMethod = module.ResolveToken((int)token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 17
0
		void GetCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => creatorInfo2.magic ^ magic);
		}
Ejemplo n.º 18
0
		void GetCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
				if (x86emu == null)
					x86emu = new x86Emulator(fileData);
				return x86emu.Emulate((uint)creatorInfo2.nativeMethod.RVA, magic);
			});
		}
Ejemplo n.º 19
0
		void GetCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
			bool isNew = creatorInfo.version == ConfuserVersion.v14_r58802;

			int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 2 : 1;
			if (isNew)
				offs--;
			int callvirtOffs = isNew ? 0 : 1;

			// This is an obfuscator bug. Field names are stored in the #Strings heap,
			// and strings in that heap are UTF8 zero terminated strings, but Confuser
			// can generate names with zeros in them. This was fixed in 1.4 58857.
			if (offs + 2 > info.field.Name.String.Length) {
				calledMethod = null;
				callOpcode = OpCodes.Call;
				return;
			}

			uint token = BitConverter.ToUInt32(Encoding.Unicode.GetBytes(info.field.Name.String.ToCharArray(), offs, 2), 0) ^ creatorInfo.magic;
			uint table = token >> 24;
			if (table != 0 && table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");

			// 1.3 r55346 now correctly uses method reference tokens and finally fixed the old
			// bug of using methoddef tokens to reference external methods.
			if (isNew || info.field.Name.String[0] == (char)1 || table != 0x06)
				calledMethod = module.ResolveToken(token) as IMethod;
			else {
				var asmRef = module.ResolveAssemblyRef((uint)info.field.Name.String[0] - 2 + 1);
				calledMethod = CreateMethodReference(asmRef, token);
			}

			bool isCallvirt = false;
			if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && info.field.Name.String[callvirtOffs] == '\r')
				isCallvirt = true;
			callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
		}
Ejemplo n.º 20
0
		static OpCode GetCallOpCode(ProxyCreatorInfo info, bool isCallvirt) {
			switch (info.proxyCreatorType) {
			case ProxyCreatorType.Newobj:
				return OpCodes.Newobj;

			case ProxyCreatorType.CallOrCallvirt:
				return isCallvirt ? OpCodes.Callvirt : OpCodes.Call;

			default: throw new NotImplementedException();
			}
		}
Ejemplo n.º 21
0
		static OpCode GetCallOpCode(ProxyCreatorInfo info, FieldDef field) {
			switch (info.proxyCreatorType) {
			case ProxyCreatorType.CallOrCallvirt:
				if (field.Name.String.Length > 0 && field.Name.String[0] == info.callvirtChar)
					return OpCodes.Callvirt;
				return OpCodes.Call;

			case ProxyCreatorType.Newobj:
				return OpCodes.Newobj;

			default: throw new NotSupportedException();
			}
		}
Ejemplo n.º 22
0
		void GetCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
			var sig = module.ReadBlob(info.field.MDToken.Raw);
			int len = sig.Length;
			uint magic = (uint)((sig[len - 2] << 24) | (sig[len - 3] << 16) | (sig[len - 5] << 8) | sig[len - 6]);
			uint rid = getRid(creatorInfo, magic);
			int token = (sig[len - 7] << 24) | (int)rid;
			uint table = (uint)token >> 24;
			if (table != 6 && table != 0x0A && table != 0x2B)
				throw new ApplicationException("Invalid method token");
			calledMethod = module.ResolveToken(token) as IMethod;
			callOpcode = GetCallOpCode(creatorInfo, info.field);
		}