First, overview:
Recently, it is also looking at the AOP aspect, knowing that emit can be achieved. The previous knowledge of emit is the part of the instructions that reflector to decompile the method. Just use this opportunity to learn the next emit also use this essay to record the process of learning. Some of the places I do not know also hope that you understand the guidance of friends.
Learn about the opcodes before you learn
Second, the tool
1, vs2015
2,. NET Reflector 9.0
Iii. examples of Getting Started
1. Output Hello World
C # code
Static void Main (string[] args) { Console.WriteLine ("Hello world! " ); }
View Code
The IL code that was obtained by the anti-compilation
Emit implementation Code
Public voidHellowworld () {//definition Hellow Method no return value no parameterDynamicMethod Helloworldmethod =NewDynamicMethod ("Hellowworld",NULL,NULL); //create IL, generate code dynamicallyILGenerator IL =Helloworldmethod.getilgenerator (); //push the output onto the stackIL. Emit (OPCODES.LDSTR,"Hello world!"); //Executive Console.WriteLineIL. Emit (Opcodes.call,typeof(Console). GetMethod ("WriteLine",NewType[] {typeof(string) })); //Method EndIL. Emit (Opcodes.ret); Helloworddelegate Method= (helloworddelegate) helloworldmethod.createdelegate (typeof(helloworddelegate)); Method (); }
View Code
The delegate is called during the call. If there are parameters, the "operation may break runtime stability" is indicated. (not clear)
Iv. Building Assemblies
1, the following through the construction of a class containing two methods to do the example
Public intADD (intAintb) {returnA +b; } Public stringAddlist (string[] Array) { stringresult =string. Empty; for(inti =0; I < array. Length; i++) {result= result +Array[i]; } returnresult; }
View Code
2, see the next two ways to decompile the IL code
Let's take a look at how this il was implemented.
L0000 to L0009: Assign String.Empty to custom variable resultname, load integer 0,l0009 jump to l001b Execute
l001b to L0027: Loads 1 index values, loads parameter 1 (static from 0), Ldlen pushes the number of arrays from 0 to the stack, compares the size of two numeric values (stores the results of the comparison to index 2, and then takes out (omitted in this step)), then jumps to l_000b execution
l000b to l001a: Load 0 index values, load parameter 1,ldelem_ref to load string type element, execute String.Concat method, store value at index 0, load index 1 value, load integer 1, add two values, store value at index 0
L002A End Return
3, the following we through the emit code to achieve
Public voidgenerateassembly () {stringName ="IL. Dynamic"; stringFileName =string. Format ("{0}.dll", name); //Building AssembliesAssemblyName assemblyname =NewAssemblyName (name); //Application Set DomainAppDomain domain =Appdomain.currentdomain; //instantiate a AssemblyBuilder object for dynamic assembly constructionAssemblyBuilder AssemblyBuilder =domain. DefineDynamicAssembly (AssemblyName, Assemblybuilderaccess.runandsave); //define module (without filename as transient module, not persistent)ModuleBuilder ModuleBuilder =assemblybuilder.definedynamicmodule (name); //Defining TypesTypeBuilder TypeBuilder =Modulebuilder.definetype (name, typeattributes.public); //define an Add method for simple additionMethodBuilder MethodBuilder = Typebuilder.definemethod ("ADD", Methodattributes.public,typeof(Int32),NewType[] {typeof(int),typeof(int) }); //IL implementationILGenerator IL =Methodbuilder.getilgenerator (); IL. Emit (opcodes.ldarg_1); IL. Emit (opcodes.ldarg_2); IL. Emit (Opcodes.add); IL. Emit (Opcodes.ret); //define a addlist string with a for stitching methodMethodBuilder Method2builder = Typebuilder.definemethod ("addlist", methodattributes.public| Methodattributes.static,typeof(string),NewType[] {typeof(string[]) }); FieldBuilder FieldName= Typebuilder.definefield ("Resultname",typeof(string), Fieldattributes.private |fieldattributes.static); ILGenerator Addil=Method2builder.getilgenerator (); //local variable to hold the sum resultLocalBuilder resultstr = addil.declarelocal (typeof(String)); ////The local variables used in the loopLocalBuilder i = addil.declarelocal (typeof(Int32)); Label Concatlabel=Addil.definelabel (); Label Looplabel=Addil.definelabel (); //Set String result = String. Empty;Addil.emit (OPCODES.LDSFLD, fieldName); Addil.emit (OPCODES.STLOC_0); //Set I=0Addil.emit (OPCODES.LDC_I4_0); Addil.emit (opcodes.stloc_1); Addil.emit (opcodes.br, Concatlabel); //Enter the loop bodyAddil.marklabel (Looplabel); Addil.emit (OPCODES.LDLOC_0); //parameters specify static starting from 0Addil.emit (OPCODES.LDARG_0); Addil.emit (opcodes.ldloc_1); //Ldelem_ref used to load string type elementsAddil.emit (OPCODES.LDELEM_REF); Addil.emit (Opcodes.call,typeof(string). GetMethod ("Concat",NewType[] {typeof(string),typeof(string) })); Addil.emit (OPCODES.STLOC_0); Addil.emit (opcodes.ldloc_1); //i++Addil.emit (opcodes.ldc_i4_1); Addil.emit (Opcodes.add); Addil.emit (opcodes.stloc_1); Addil.marklabel (Concatlabel); Addil.emit (opcodes.ldloc_1); Addil.emit (OPCODES.LDARG_0); Addil.emit (Opcodes.ldlen); Addil.emit (OPCODES.CONV_I4); //CLT Compares two value sizesAddil.emit (OPCODES.CLT); Addil.emit (opcodes.brtrue_s, Looplabel); Addil.emit (OPCODES.LDLOC_0); Addil.emit (Opcodes.ret); Type type=TypeBuilder.CreateType (); Assemblybuilder.save (FileName); int[] INTs =New int[] {1,2,3,4 }; string[] Array =New string[] {"a","b","C" }; ObjectOB =activator.createinstance (type); varresult = type. GetMethod ("ADD"). Invoke (OB,New Object[] {8,9 }); varRESULT1 = type. GetMethod ("addlist"). Invoke (OB,New Object[] {array}); }
View Code
3.1, AssemblyBuilderAccess
Run |
can be executed but not saved |
Save |
Save but not execute |
Runandsave |
Can execute and save |
ReflectionOnly |
Load in reflection-only context |
4. Running output
4.1. Generate files
See the C # code generated by IL with tool anti-compilation
4.2. Operation Result
Through this example to IL can have a comparative basis of understanding, in the later study and then slowly drink everyone to communicate. Project Download system.il
Il Preliminary understanding