1+ using dnlib . DotNet ;
2+ using dnlib . DotNet . Emit ;
3+ using System . Collections . Generic ;
4+ using System . Linq ;
5+
6+ namespace NetShield_Protector
7+ {
8+ public static class InjectHelper
9+ {
10+ private static TypeDefUser Clone ( TypeDef origin )
11+ {
12+ var ret = new TypeDefUser ( origin . Namespace , origin . Name )
13+ {
14+ Attributes = origin . Attributes
15+ } ;
16+
17+ if ( origin . ClassLayout != null )
18+ ret . ClassLayout = new ClassLayoutUser ( origin . ClassLayout . PackingSize , origin . ClassSize ) ;
19+
20+ foreach ( var genericParam in origin . GenericParameters )
21+ ret . GenericParameters . Add ( new GenericParamUser ( genericParam . Number , genericParam . Flags , "-" ) ) ;
22+
23+ return ret ;
24+ }
25+
26+ private static MethodDefUser Clone ( MethodDef origin )
27+ {
28+ var ret = new MethodDefUser ( origin . Name , null , origin . ImplAttributes , origin . Attributes ) ;
29+
30+ foreach ( var genericParam in origin . GenericParameters )
31+ ret . GenericParameters . Add ( new GenericParamUser ( genericParam . Number , genericParam . Flags , "-" ) ) ;
32+
33+ return ret ;
34+ }
35+
36+ private static FieldDefUser Clone ( FieldDef origin )
37+ {
38+ var ret = new FieldDefUser ( origin . Name , null , origin . Attributes ) ;
39+ return ret ;
40+ }
41+
42+ private static TypeDef PopulateContext ( TypeDef typeDef , InjectContext ctx )
43+ {
44+ TypeDef ret ;
45+ if ( ! ctx . Mep . TryGetValue ( typeDef , out var existing ) )
46+ {
47+ ret = Clone ( typeDef ) ;
48+ ctx . Mep [ typeDef ] = ret ;
49+ }
50+ else
51+ ret = ( TypeDef ) existing ;
52+
53+ foreach ( var nestedType in typeDef . NestedTypes )
54+ ret . NestedTypes . Add ( PopulateContext ( nestedType , ctx ) ) ;
55+
56+ foreach ( var method in typeDef . Methods )
57+ ret . Methods . Add ( ( MethodDef ) ( ctx . Mep [ method ] = Clone ( method ) ) ) ;
58+
59+ foreach ( var field in typeDef . Fields )
60+ ret . Fields . Add ( ( FieldDef ) ( ctx . Mep [ field ] = Clone ( field ) ) ) ;
61+
62+ return ret ;
63+ }
64+
65+ private static void CopyTypeDef ( TypeDef typeDef , InjectContext ctx )
66+ {
67+ var newTypeDef = ( TypeDef ) ctx . Mep [ typeDef ] ;
68+
69+ newTypeDef . BaseType = ctx . Importer . Import ( typeDef . BaseType ) ;
70+
71+ foreach ( var iface in typeDef . Interfaces )
72+ newTypeDef . Interfaces . Add ( new InterfaceImplUser ( ctx . Importer . Import ( iface . Interface ) ) ) ;
73+ }
74+
75+ private static void CopyMethodDef ( MethodDef methodDef , InjectContext ctx )
76+ {
77+ var newMethodDef = ( MethodDef ) ctx . Mep [ methodDef ] ;
78+
79+ newMethodDef . Signature = ctx . Importer . Import ( methodDef . Signature ) ;
80+ newMethodDef . Parameters . UpdateParameterTypes ( ) ;
81+
82+ if ( methodDef . ImplMap != null )
83+ newMethodDef . ImplMap = new ImplMapUser ( new ModuleRefUser ( ctx . TargetModule , methodDef . ImplMap . Module . Name ) , methodDef . ImplMap . Name , methodDef . ImplMap . Attributes ) ;
84+
85+ foreach ( var ca in methodDef . CustomAttributes )
86+ newMethodDef . CustomAttributes . Add ( new CustomAttribute ( ( ICustomAttributeType ) ctx . Importer . Import ( ca . Constructor ) ) ) ;
87+
88+ if ( ! methodDef . HasBody )
89+ return ;
90+ newMethodDef . Body = new CilBody ( methodDef . Body . InitLocals , new List < Instruction > ( ) ,
91+ new List < ExceptionHandler > ( ) , new List < Local > ( ) )
92+ { MaxStack = methodDef . Body . MaxStack } ;
93+
94+ var bodyMap = new Dictionary < object , object > ( ) ;
95+
96+ foreach ( var local in methodDef . Body . Variables )
97+ {
98+ var newLocal = new Local ( ctx . Importer . Import ( local . Type ) ) ;
99+ newMethodDef . Body . Variables . Add ( newLocal ) ;
100+ newLocal . Name = local . Name ;
101+ newLocal . Attributes = local . Attributes ;
102+
103+ bodyMap [ local ] = newLocal ;
104+ }
105+
106+ foreach ( var instr in methodDef . Body . Instructions )
107+ {
108+ var newInstr = new Instruction ( instr . OpCode , instr . Operand )
109+ {
110+ SequencePoint = instr . SequencePoint
111+ } ;
112+
113+ switch ( newInstr . Operand )
114+ {
115+ case IType type :
116+ newInstr . Operand = ctx . Importer . Import ( type ) ;
117+ break ;
118+
119+ case IMethod method :
120+ newInstr . Operand = ctx . Importer . Import ( method ) ;
121+ break ;
122+
123+ case IField field :
124+ newInstr . Operand = ctx . Importer . Import ( field ) ;
125+ break ;
126+ }
127+
128+ newMethodDef . Body . Instructions . Add ( newInstr ) ;
129+ bodyMap [ instr ] = newInstr ;
130+ }
131+
132+ foreach ( var instr in newMethodDef . Body . Instructions )
133+ {
134+ if ( instr . Operand != null && bodyMap . ContainsKey ( instr . Operand ) )
135+ instr . Operand = bodyMap [ instr . Operand ] ;
136+ else if ( instr . Operand is Instruction [ ] v )
137+ instr . Operand = v . Select ( target => ( Instruction ) bodyMap [ target ] ) . ToArray ( ) ;
138+ }
139+
140+ foreach ( var eh in methodDef . Body . ExceptionHandlers )
141+ newMethodDef . Body . ExceptionHandlers . Add ( new ExceptionHandler ( eh . HandlerType )
142+ {
143+ CatchType = eh . CatchType == null ? null : ctx . Importer . Import ( eh . CatchType ) ,
144+ TryStart = ( Instruction ) bodyMap [ eh . TryStart ] ,
145+ TryEnd = ( Instruction ) bodyMap [ eh . TryEnd ] ,
146+ HandlerStart = ( Instruction ) bodyMap [ eh . HandlerStart ] ,
147+ HandlerEnd = ( Instruction ) bodyMap [ eh . HandlerEnd ] ,
148+ FilterStart = eh . FilterStart == null ? null : ( Instruction ) bodyMap [ eh . FilterStart ]
149+ } ) ;
150+
151+ newMethodDef . Body . SimplifyMacros ( newMethodDef . Parameters ) ;
152+ }
153+
154+ private static void CopyFieldDef ( FieldDef fieldDef , InjectContext ctx )
155+ {
156+ var newFieldDef = ( FieldDef ) ctx . Mep [ fieldDef ] ;
157+
158+ newFieldDef . Signature = ctx . Importer . Import ( fieldDef . Signature ) ;
159+ }
160+
161+ private static void Copy ( TypeDef typeDef , InjectContext ctx , bool copySelf )
162+ {
163+ if ( copySelf )
164+ CopyTypeDef ( typeDef , ctx ) ;
165+
166+ foreach ( var nestedType in typeDef . NestedTypes )
167+ Copy ( nestedType , ctx , true ) ;
168+
169+ foreach ( var method in typeDef . Methods )
170+ CopyMethodDef ( method , ctx ) ;
171+
172+ foreach ( var field in typeDef . Fields )
173+ CopyFieldDef ( field , ctx ) ;
174+ }
175+
176+ public static TypeDef Inject ( TypeDef typeDef , ModuleDef target )
177+ {
178+ var ctx = new InjectContext ( target ) ;
179+ PopulateContext ( typeDef , ctx ) ;
180+ Copy ( typeDef , ctx , true ) ;
181+ return ( TypeDef ) ctx . Mep [ typeDef ] ;
182+ }
183+
184+ public static MethodDef Inject ( MethodDef methodDef , ModuleDef target )
185+ {
186+ var ctx = new InjectContext ( target )
187+ {
188+ Mep =
189+ {
190+ [ methodDef ] = Clone ( methodDef )
191+ }
192+ } ;
193+ CopyMethodDef ( methodDef , ctx ) ;
194+ return ( MethodDef ) ctx . Mep [ methodDef ] ;
195+ }
196+
197+ public static IEnumerable < IDnlibDef > Inject ( TypeDef typeDef , TypeDef newType , ModuleDef target )
198+ {
199+ var ctx = new InjectContext ( target )
200+ {
201+ Mep =
202+ {
203+ [ typeDef ] = newType
204+ }
205+ } ;
206+ PopulateContext ( typeDef , ctx ) ;
207+ Copy ( typeDef , ctx , false ) ;
208+ return ctx . Mep . Values . Except ( new [ ] { newType } ) ;
209+ }
210+
211+ private class InjectContext : ImportMapper
212+ {
213+ public readonly Dictionary < IDnlibDef , IDnlibDef > Mep = new Dictionary < IDnlibDef , IDnlibDef > ( ) ;
214+
215+ public readonly ModuleDef TargetModule ;
216+
217+ public InjectContext ( ModuleDef target )
218+ {
219+ TargetModule = target ;
220+ Importer = new Importer ( target , ImporterOptions . TryToUseTypeDefs , new GenericParamContext ( ) , this ) ;
221+ }
222+
223+ public Importer Importer { get ; }
224+
225+ public override ITypeDefOrRef Map ( ITypeDefOrRef typeDefOrRef )
226+ {
227+ return typeDefOrRef is TypeDef typeDef && Mep . ContainsKey ( typeDef ) ? Mep [ typeDef ] as TypeDef : null ;
228+ }
229+
230+ public override IMethod Map ( MethodDef methodDef )
231+ {
232+ return Mep . ContainsKey ( methodDef ) ? Mep [ methodDef ] as MethodDef : null ;
233+ }
234+
235+ public override IField Map ( FieldDef fieldDef )
236+ {
237+ return Mep . ContainsKey ( fieldDef ) ? Mep [ fieldDef ] as FieldDef : null ;
238+ }
239+ }
240+ }
241+ }
0 commit comments