その場でコードをコンパイルして安全に実行する

問題



アプリケーションでは、アプリケーションのコンパイル段階で不明なコードを実行する必要があります。 さまざまなプラグイン、拡張機能、計算などが可能です。



解決策



.NETでは、コードをコンパイルして実行できます。 さらに、実行可能コードが使用できるリソースの範囲を狭めることにより、コードを安全に実行できます。







実装



コンパイルには、CodeDomProviderが必要です。これを使用すると、.NET言語のコンパイラインスタンスをインスタンス化できます。 コードに移りましょう。



  1. プライベート 文字列 EvalCode string typeName、 string methodName、 string sourceCode
  2. {
  3. 文字列出力= ":)" ;
  4. var compiler = CodeDomProvider。 CreateProvider "CSharp" ;
  5. var parameters = new CompilerParameters
  6. {
  7. CompilerOptions = "/ t:library"
  8. GenerateInMemory = true
  9. IncludeDebugInformation = true
  10. } ;
  11. var results =コンパイラ。 CompileAssemblyFromSource パラメーター、sourceCode ;
  12. if 結果。 エラー 。HasErrors
  13. {
  14. var assembly = results。 CompiledAssembly ;
  15. var evaluatorType = assembly。 GetType typeName ;
  16. var evaluator =アクティベーター。 CreateInstance evaluatorType ;
  17. output = string InvokeMethod evaluatorType、methodName、evaluator、 new object [ ] { output } ;
  18. 出力を返す ;
  19. }
  20. output = " \ r \ nヒューストン、コンパイル時に問題があります!" ;
  21. 結果を返します。 エラー キャスト < CompilerError > Aggregate output、 current、ce => current + string。Format " \ r \ n line {0}:{1}"ce。Line、ce。ErrorText ;
  22. }
  23. [ FileIOPermission SecurityAction。Deny、Unrestricted = true ]
  24. プライベート オブジェクト InvokeMethod タイプevaluatorType、 string methodName、 オブジェクトエバリュエーター、 オブジェクト [ ] methodParams
  25. {
  26. evaluatorTypeを返します。 InvokeMember methodName、 System。Reflection。BindingFlags。InvokeMethodnull 、evaluator、methodParams ;
  27. }




ご覧のとおり、超自然的なものはありません。 コンパイラを作成し、それにコードを渡し、DLLを取得します。 リフレクションを使用して、目的のメソッドを実行します。



実行中のコード:





27行目は興味深いですが、これにより、コードが持つ権限を制限できます(動的だけでなく)。 .NETには、実行可能なコードのセキュリティを制御できるコードアクセスセキュリティメカニズムがあります。



ディスクへの書き込みを試みるときのセキュリティエラー:





コードの実行は非常に「無害」に見えるという事実にもかかわらず、これは非常にリソース集約的なプロセスであることを覚えておく価値があります。 たとえば、アプリケーションの現在のドメインでコードを実行すると(デモで行われたように)、アプリケーションの長時間の動作中にメモリが単純に終了する場合があります(.NETはドメインからアセンブリをアンロードできません)。



デモ:

Dyndllfunwf.zip



All Articles