/// <summary> /// Loads the unit from the given stream. The caller should dispose the /// stream after the API is called (the stream contents will have been copied /// to unmanaged memory already). /// </summary> /// <param name="location">The location to be exposed from IUnit</param> /// <param name="stream">The data to be used as the unit</param> public IUnit LoadUnitFrom(string location, Stream stream) { var fileName = Path.GetFileName(location); var name = NameTable.GetNameFor(fileName); var document = new StreamDocument(location, name, stream); var unit = _reader.OpenModule(document); this.RegisterAsLatest(unit); return(unit); }
//name doesn't containt the namespace, only the type name private INamedTypeDefinition LoadNestedTypeDef(string name, IScope <ITypeDefinitionMember> parent) { INamedTypeDefinition type = null; string firstName = null; string remainingName = null; int plusIdx = name.IndexOf('+'); if (plusIdx > 0) { firstName = name.Substring(0, plusIdx); remainingName = name.Substring(plusIdx + 1); } else if (plusIdx < 0) { firstName = name; } else /* plusIdx = 0 */ { throw new Exception("Invalid type def name"); } int numGenArgs; string shortName; Util.ParseGenName(firstName, out shortName, out numGenArgs); IName firstIName = NameTable.GetNameFor(shortName); foreach (ITypeDefinitionMember member in parent.GetMembersNamed(firstIName, false)) { type = member as INamedTypeDefinition; if (type != null && type.GenericParameterCount == numGenArgs) { break; } } if (type != null) { if (remainingName == null) { return(type); } else { return(LoadNestedTypeDef(remainingName, type)); } } else { throw new Exception("Cannot find the type: " + name); } }
public override IExpression Rewrite(IMethodCall methodCall) { _log.Info("Rewrite IMethodCall: " + OperatorUtils.Formatter.Format(methodCall)); var methodDefinition = TypeHelper.GetMethod(methodCall.MethodToCall.ContainingType.ResolvedType, NameTable.GetNameFor(MutationTarget.PassInfo), methodCall.Arguments.Select(a => a.Type).ToArray()); var newCall = new MethodCall(methodCall); newCall.MethodToCall = methodDefinition;// // (IMethodReference)MutationTarget.StoredObjects.Values.Single(); _log.Info("Returning MethodCall to: " + OperatorUtils.Formatter.Format(methodCall)); return(newCall); }
public override IRootUnitNamespace Rewrite(IRootUnitNamespace root) { var testClass = new NamespaceTypeDefinition { BaseClasses = new List <ITypeReference>(1) { Host.PlatformType.SystemObject }, ContainingUnitNamespace = root, InternFactory = Host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = NameTable.GetNameFor("VisualMutatorGeneratedClass"), }; ((RootUnitNamespace)root).Members.Add(testClass); ((Assembly)Module).AllTypes.Add(testClass); var mainMethod = new MethodDefinition { ContainingTypeDefinition = testClass, InternFactory = Host.InternFactory, IsCil = true, IsStatic = true, Name = NameTable.GetNameFor("FailOnZero"), Type = Host.PlatformType.SystemInt32, Visibility = TypeMemberVisibility.Public, }; mainMethod.Parameters = new List <IParameterDefinition>() { new ParameterDefinition() { Type = Host.PlatformType.SystemInt32, Name = NameTable.GetNameFor("x"), } }; testClass.Methods.Add(mainMethod); var body = new SourceMethodBody(Host) { MethodDefinition = mainMethod, LocalsAreZeroed = true }; mainMethod.Body = body; body.Block = GeneratedBlock; return(root); }
private INamedTypeDefinition LoadFullyQualifiedTypeDef(string name, INamespaceDefinition parentNs) { int dotIdx = name.IndexOf('.'); if (dotIdx > 0) { string firstNs = name.Substring(0, dotIdx); string remainingName = name.Substring(dotIdx + 1); INamespaceDefinition ns = null; IName firstINs = NameTable.GetNameFor(firstNs); foreach (INamespaceMember member in parentNs.GetMembersNamed(firstINs, false)) { ns = member as INamespaceDefinition; if (ns != null) { break; } } if (ns != null) { return(LoadFullyQualifiedTypeDef(remainingName, ns)); } else { throw new Exception("Cannot find the namespace: " + firstNs); } } else if (dotIdx < 0) { return(LoadTypeDef(name, parentNs)); } else /* dotIdx == 0 */ { throw new Exception("Invalid type def name"); } }
static void Main(string[] args) { var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor("hello"), ModuleName = nameTable.GetNameFor("hello.exe"), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); var testClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Test"), }; rootUnitNamespace.Members.Add(testClass); assembly.AllTypes.Add(testClass); testClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; var mainMethod = new MethodDefinition() { ContainingTypeDefinition = testClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; testClass.Methods.Add(mainMethod); var ilGenerator = new ILGenerator(host, mainMethod); var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console"); var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString); ilGenerator.Emit(OperationCode.Ldstr, "hello"); ilGenerator.Emit(OperationCode.Call, writeLine); ilGenerator.Emit(OperationCode.Ret); var body = new ILGeneratorMethodBody(ilGenerator, true, 1, mainMethod, Enumerable <ILocalDefinition> .Empty, Enumerable <ITypeDefinition> .Empty); mainMethod.Body = body; using (var peStream = File.Create("hello.exe")) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
private IExpression ReplaceOperation <T>(T operation) where T : IExpression { var mcall = operation as MethodCall; if (mcall != null) { if (mcall.MethodToCall.Name.Value == "Abs") { return(operation); } } if (MutationTarget.PassInfo.IsIn("Abs", "NegAbs")) { INamedTypeDefinition systemConsole = UnitHelper.FindType(NameTable, CoreAssembly, "System.Math"); IMethodDefinition abs = TypeHelper.GetMethod(systemConsole, NameTable.GetNameFor("Abs"), operation.Type); var call = new MethodCall { IsStaticCall = true, MethodToCall = abs, Type = abs.Type }; call.Arguments.Add(operation); IExpression result = call; if (MutationTarget.PassInfo == "NegAbs") { result = new UnaryNegation { CheckOverflow = false, Operand = call, Type = operation.Type, }; } return(result); } else { INamedTypeDefinition systemConsole = UnitHelper.FindType(NameTable, Module, "VisualMutatorGeneratedClass"); IMethodDefinition failOnZero = (IMethodDefinition)systemConsole.GetMembersNamed(NameTable.GetNameFor("FailOnZero"), false).Single(); var call = new MethodCall { IsStaticCall = true, MethodToCall = failOnZero, Type = failOnZero.Type }; call.Arguments.Add(operation); return(call); } }
static void Main(string[] args) { var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor("hello"), ModuleName = nameTable.GetNameFor("hello.exe"), Kind = ModuleKind.ConsoleApplication, PlatformType = host.PlatformType, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); var testClass = new NamespaceTypeDefinition() { BaseClasses = new List <ITypeReference>(1) { host.PlatformType.SystemObject }, ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Test"), }; rootUnitNamespace.Members.Add(testClass); assembly.AllTypes.Add(testClass); var mainMethod = new MethodDefinition() { ContainingTypeDefinition = testClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; testClass.Methods.Add(mainMethod); var body = new SourceMethodBody(host) { MethodDefinition = mainMethod, LocalsAreZeroed = true }; mainMethod.Body = body; var block = new BlockStatement(); body.Block = block; var systemConsole = UnitHelper.FindType(nameTable, coreAssembly, "System.Console"); var writeLine = TypeHelper.GetMethod(systemConsole, nameTable.GetNameFor("WriteLine"), host.PlatformType.SystemString); var call = new MethodCall() { IsStaticCall = true, MethodToCall = writeLine, Type = host.PlatformType.SystemVoid }; call.Arguments.Add(new CompileTimeConstant() { Type = host.PlatformType.SystemString, Value = "hello" }); block.Statements.Add(new ExpressionStatement() { Expression = call }); block.Statements.Add(new ReturnStatement()); using (var peStream = File.Create("hello.exe")) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
public void Compile(string fileName) { string appName = Path.GetFileNameWithoutExtension(fileName); string exeName = appName + ".exe"; string src = ""; using (TextReader file = new StreamReader(fileName)) { src = file.ReadToEnd(); } var nameTable = new NameTable(); using (var host = new PeReader.DefaultHost(nameTable)) { // Load Mirage types IModule module = host.LoadUnitFrom("Mirage.dll") as IModule; if (module == null || module is Dummy) { return; } var machineType = module.GetAllTypes().First(x => x.Name.Value == "Machine"); var inputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleInput"); var outputType = module.GetAllTypes().First(x => x.Name.Value == "ConsoleOutput"); // Create assembly var coreAssembly = host.LoadAssembly(host.CoreAssemblySymbolicIdentity); var assembly = new Assembly() { Name = nameTable.GetNameFor(appName), ModuleName = nameTable.GetNameFor(exeName), PlatformType = host.PlatformType, Kind = ModuleKind.ConsoleApplication, RequiresStartupStub = host.PointerSize == 4, TargetRuntimeVersion = coreAssembly.TargetRuntimeVersion, }; assembly.AssemblyReferences.Add(coreAssembly); // Create namespace var rootUnitNamespace = new RootUnitNamespace(); assembly.UnitNamespaceRoot = rootUnitNamespace; rootUnitNamespace.Unit = assembly; // Create module class var moduleClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, Name = nameTable.GetNameFor("<Module>"), }; assembly.AllTypes.Add(moduleClass); // Create program class var programClass = new NamespaceTypeDefinition() { ContainingUnitNamespace = rootUnitNamespace, InternFactory = host.InternFactory, IsClass = true, IsPublic = true, Methods = new List <IMethodDefinition>(1), Name = nameTable.GetNameFor("Program"), }; programClass.BaseClasses = new List <ITypeReference>() { host.PlatformType.SystemObject }; rootUnitNamespace.Members.Add(programClass); // Add types to the assembly assembly.AllTypes.Add(machineType); foreach (var t in machineType.NestedTypes) { assembly.AllTypes.Add(t); } assembly.AllTypes.Add(inputType); assembly.AllTypes.Add(outputType); assembly.AllTypes.Add(programClass); // Create main method var mainMethod = new MethodDefinition() { ContainingTypeDefinition = programClass, InternFactory = host.InternFactory, IsCil = true, IsStatic = true, Name = nameTable.GetNameFor("Main"), Type = host.PlatformType.SystemVoid, Visibility = TypeMemberVisibility.Public, }; assembly.EntryPoint = mainMethod; programClass.Methods.Add(mainMethod); // Create constructors and methods IMethodReference machineConstructor = new Microsoft.Cci.MethodReference( host, machineType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); IMethodReference inputConstructor = new Microsoft.Cci.MethodReference( host, inputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var inputCast = TypeHelper.GetMethod(inputType, nameTable.GetNameFor("op_Implicit"), inputType); IMethodReference outputConstructor = new Microsoft.Cci.MethodReference( host, outputType, CallingConvention.HasThis, host.PlatformType.SystemVoid, host.NameTable.Ctor, 0 ); var outputCast = TypeHelper.GetMethod(outputType, nameTable.GetNameFor("op_Implicit"), outputType); var opIncPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncPointers")); var opDecPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecPointers")); var opIncHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("IncHiPointer")); var opDecHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DecHiPointer")); var opReflectHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("ReflectHiPointer")); var opLoadHiPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadHiPointer")); var opDragLoPointer = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("DragLoPointer")); var opXchPointers = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("XchPointers")); var opClear = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Clear")); var opAdd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Add")); var opDec = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Dec")); var opNot = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Not")); var opAnd = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("And")); var opOr = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Or")); var opXor = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Xor")); var opSal = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sal")); var opSar = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Sar")); var opLoadData = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("LoadData"), host.PlatformType.SystemString); var opInput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Input"), inputCast.Type); var opOutput = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Output"), outputCast.Type); var opJz = TypeHelper.GetMethod(machineType, nameTable.GetNameFor("Jz")); // Create program code var labels = new Stack <ILGeneratorLabel>(100); var ilGenerator = new ILGenerator(host, mainMethod); ilGenerator.Emit(OperationCode.Newobj, machineConstructor); ilGenerator.Emit(OperationCode.Stloc_0); ilGenerator.Emit(OperationCode.Newobj, inputConstructor); ilGenerator.Emit(OperationCode.Stloc_1); ilGenerator.Emit(OperationCode.Newobj, outputConstructor); ilGenerator.Emit(OperationCode.Stloc_2); int pc = 0; while (pc < src.Length) { char opcode = src[pc++]; switch (opcode) { case '>': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncPointers); break; case '<': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecPointers); break; case ']': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opIncHiPointer); break; case '[': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDecHiPointer); break; case '#': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opReflectHiPointer); break; case '$': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opLoadHiPointer); break; case '=': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDragLoPointer); break; case '%': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXchPointers); break; case '_': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opClear); break; case '+': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAdd); break; case '-': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opDec); break; case '~': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opNot); break; case '&': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opAnd); break; case '|': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opOr); break; case '^': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opXor); break; case '*': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSal); break; case '/': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opSar); break; case '(': int dataStart = pc; int dataEnd = dataStart; while (src[pc++] != ')') { dataEnd = pc; } ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldstr, src.Substring(dataStart, dataEnd - dataStart)); ilGenerator.Emit(OperationCode.Callvirt, opLoadData); break; case '?': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_1); ilGenerator.Emit(OperationCode.Call, inputCast); ilGenerator.Emit(OperationCode.Callvirt, opInput); break; case '!': ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Ldloc_2); ilGenerator.Emit(OperationCode.Call, outputCast); ilGenerator.Emit(OperationCode.Callvirt, opOutput); break; case '{': var cycleStart = new ILGeneratorLabel(); var cycleEnd = new ILGeneratorLabel(); labels.Push(cycleStart); labels.Push(cycleEnd); ilGenerator.Emit(OperationCode.Br, cycleEnd); ilGenerator.MarkLabel(cycleStart); break; case '}': ilGenerator.MarkLabel(labels.Pop()); ilGenerator.Emit(OperationCode.Ldloc_0); ilGenerator.Emit(OperationCode.Callvirt, opJz); ilGenerator.Emit(OperationCode.Ldc_I4_0); ilGenerator.Emit(OperationCode.Ceq); ilGenerator.Emit(OperationCode.Stloc_3); ilGenerator.Emit(OperationCode.Ldloc_3); ilGenerator.Emit(OperationCode.Brtrue, labels.Pop()); break; default: break; } } ilGenerator.Emit(OperationCode.Ret); mainMethod.Body = new ILGeneratorMethodBody( ilGenerator, true, 8, mainMethod, new List <ILocalDefinition>() { new LocalDefinition() { Type = machineType }, new LocalDefinition() { Type = inputType }, new LocalDefinition() { Type = outputType }, new LocalDefinition() { Type = host.PlatformType.SystemInt32 }, }, Enumerable <ITypeDefinition> .Empty ); using (var peStream = File.Create(exeName)) { PeWriter.WritePeToStream(assembly, host, peStream); } } }
// Name doesn't containt the namespace, only the type name. private INamedTypeDefinition LoadTypeDef(string name, IScope <INamespaceMember> parent) { INamedTypeDefinition type = null; string firstName = null; string remainingName = null; int plusIdx = name.IndexOf('+'); if (plusIdx > 0) { firstName = name.Substring(0, plusIdx); remainingName = name.Substring(plusIdx + 1); } else if (plusIdx < 0) { firstName = name; } else /* plusIdx = 0 */ { throw new Exception("Invalid type def name"); } int numGenArgs; string shortName; Util.ParseGenName(firstName, out shortName, out numGenArgs); IName firstIName = NameTable.GetNameFor(shortName); foreach (INamespaceMember member in parent.GetMembersNamed(firstIName, false)) { type = member as INamedTypeDefinition; if (type != null && type.GenericParameterCount == numGenArgs) { break; } } // HACK to handle class names like "gcroot<System::String ^>" // TODO: Does this result in false matches? if (type == null) { foreach (INamespaceMember member in parent.GetMembersNamed(NameTable.GetNameFor(firstName), false)) { type = member as INamedTypeDefinition; if (type != null) { break; } } } if (type != null) { if (remainingName == null) { return(type); } else { return(LoadNestedTypeDef(remainingName, type)); } } else { throw new Exception("Cannot find the type: " + name); } }