問題
アプリケーションでは、アプリケーションのコンパイル段階で不明なコードを実行する必要があります。 さまざまなプラグイン、拡張機能、計算などが可能です。
解決策
.NETでは、コードをコンパイルして実行できます。 さらに、実行可能コードが使用できるリソースの範囲を狭めることにより、コードを安全に実行できます。
実装
コンパイルには、CodeDomProviderが必要です。これを使用すると、.NET言語のコンパイラインスタンスをインスタンス化できます。 コードに移りましょう。
- プライベート 文字列 EvalCode ( string typeName、 string methodName、 string sourceCode )
- {
- 文字列出力= ":)" ;
- var compiler = CodeDomProvider。 CreateProvider ( "CSharp" ) ;
- var parameters = new CompilerParameters
- {
- CompilerOptions = "/ t:library" 、
- GenerateInMemory = true 、
- IncludeDebugInformation = true
- } ;
- var results =コンパイラ。 CompileAssemblyFromSource (パラメーター、sourceCode ) ;
- if ( !結果。 エラー 。HasErrors )
- {
- var assembly = results。 CompiledAssembly ;
- var evaluatorType = assembly。 GetType ( typeName ) ;
- var evaluator =アクティベーター。 CreateInstance ( evaluatorType ) ;
- output = ( string ) InvokeMethod ( evaluatorType、methodName、evaluator、 new object [ ] { output } ) ;
- 出力を返す ;
- }
- output = " \ r \ nヒューストン、コンパイル時に問題があります!" ;
- 結果を返します。 エラー キャスト < CompilerError > ( ) 。 Aggregate ( output、 ( current、ce ) => current + string。Format ( " \ r \ n line {0}:{1}" 、 ce。Line、ce。ErrorText ) ) ;
- }
- [ FileIOPermission ( SecurityAction。Deny、Unrestricted = true ) ]
- プライベート オブジェクト InvokeMethod (タイプevaluatorType、 string methodName、 オブジェクトエバリュエーター、 オブジェクト [ ] methodParams )
- {
- evaluatorTypeを返します。 InvokeMember ( methodName、 System。Reflection。BindingFlags。InvokeMethod 、 null 、evaluator、methodParams ) ;
- }
ご覧のとおり、超自然的なものはありません。 コンパイラを作成し、それにコードを渡し、DLLを取得します。 リフレクションを使用して、目的のメソッドを実行します。
実行中のコード:
27行目は興味深いですが、これにより、コードが持つ権限を制限できます(動的だけでなく)。 .NETには、実行可能なコードのセキュリティを制御できる
コードアクセスセキュリティメカニズムがあります。
ディスクへの書き込みを試みるときのセキュリティエラー:
コードの実行は非常に「無害」に見えるという事実にもかかわらず、これは非常にリソース集約的なプロセスであることを覚えておく価値があります。 たとえば、アプリケーションの現在のドメインでコードを実行すると(デモで行われたように)、アプリケーションの長時間の動作中にメモリが単純に終了する場合があります(.NETはドメインからアセンブリをアンロードできません)。
デモ:
Dyndllfunwf.zip