Stop CodeDom generated executables being detected as a virus - c#

So when i generate a C# program using CodeDom and scan it online it comes up as being a virus. How do I stop this?
This is the code i am using to generate it:
string Output = "Out.exe";
string[] fileArray = { "source.cs", "AssemblyInfo.cs" };
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
parameters.ReferencedAssemblies.Add("System.dll");
CompilerResults results = codeProvider.CompileAssemblyFromFile(parameters, fileArray);
if (results.Errors.Count > 0)
{
foreach (CompilerError CompErr in results.Errors)
{
MessageBox.Show(
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine);
}
}
else
{
MessageBox.Show("Success!");
}
This is the code i'm using for the generated exe
using System;
using System.Text;
namespace Out
{
class Program
{
static void Main(string[] args)
{
System.Text.StringBuilder sbMessage = new System.Text.StringBuilder();
Console.WriteLine(sbMessage.Append("the result of adding (1+2) is " + (1 + 2).ToString()));
System.Console.ReadLine();
}
}
}
So when I scan the generated file, its getting detected as a virus as showen in the VirusTotal link https://www.virustotal.com/en/file/d19cb8ad9c9de9da50a29acab91b53d10327b3023aa1a32c367d17c0c50fd28c/analysis/1434772258/

Related

How to save generated exe in Run-Time Compilation

I am trying to save to Desktop generated code by CSharpProvider to Desktop. How can I do that?
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
textBox2.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, textBox1.Text);
if (results.Errors.Count > 0)
{
textBox2.ForeColor = Color.Red;
foreach (CompilerError CompErr in results.Errors)
{
textBox2.Text = textBox2.Text +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
//Successful Compile
textBox2.ForeColor = Color.Blue;
textBox2.Text = "Success!";
//If we clicked run then launch our EXE
if (ButtonObject.Text == "Run") Process.Start(Output);
}
I don't want to run it just save it.
I have solved it . Changed the out.exe to c:\out.exe.

Loop through a string array and pass its elements to a method

I have a c# console application that copies files from different directories on the network and place them in one single location on the server (Win Server 2008 R2). When I run the application, I get "File not found - System.String[] 0 File(s) copied." message.
static void Main(string[] args)
{
string[] srcPath =
{
#"\\sharedloc1\HR\Org Docs",
#"\\sharedloc2\MKT\Org Docs"
};
string desPath = #"C:\Users\James\Desktop\my docs";
foreach (string d in srcPath)
{
xcopy(srcPath, desPath + #"\");
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
private static void xcopy(string[] SrcLoc, string FnlLoc)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "copyFiles";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "\"" + SrcLoc + "\"" + " " + "\"" + FnlLoc + "\"" + #" /d /y";
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch (Exception exp)
{
throw exp;
}
}
We have around 15 directories to loop through.
This is the problem:
foreach (string d in srcPath)
{
xcopy(srcPath, desPath + #"\");
}
You should be using d inside the foreach:
foreach (string d in srcPath)
{
xcopy(d, desPath + #"\");
}
You then need to change the xcopy method to take in a string instead of a string[].
When you do the following:
startInfo.Arguments = "\"" + SrcLoc + "\"" + " " + "\"" + FnlLoc + "\"" + #" /d /y";
You are converting the String[] to a String (the runtime will call .ToString() on SrcLoc). This is how it ends up with System.String[] in your process arguments.
Also, this block of code does nothing except destroy the stack trace.
catch (Exception exp)
{
throw exp;
}
If you want to re-throw and error, you should just do throw;.

Compiling and Executing single lines of code

I am creating a /kind of/ custom compiler for a project. What I am doing is having users enter lines of code into either a textbox, or they can import some from text files.
I've been trying to test this for the last few days, with no results. I have a class, called Pressure, where I have a public method called 'emit' which simply shows a text box, like so...
public void emit()
{
MessageBox.Show("HOORA!");
}
and I have a text file named "testCompile.txt" as follows:
PressureTransducer pt = new PressureTransducer(0,0);
pt.emit();
which, when inserted into VS compiles just fine, as it should. Afterwards, I try to compile the file like so...
String sourceName = #"C:\Users\Devic\Desktop\CompileTester\testCompile.txt";
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = true;
//cp.OutputAssembly = null;
cp.GenerateInMemory = true;
cp.TreatWarningsAsErrors = false;
CompilerResults cr = provider.CompileAssemblyFromFile(cp,
sourceName);
if (cr.Errors.Count > 0)
{
// Display compilation errors.
Console.WriteLine("Errors building {0} into {1}",
sourceName, cr.PathToAssembly);
foreach (CompilerError ce in cr.Errors)
{
Console.WriteLine(" {0}", ce.ToString());
Console.WriteLine();
}
}
else
{
// Display a successful compilation message.
Console.WriteLine("Source {0} built into {1} successfully.",
sourceName, cr.PathToAssembly);
}
but VS gives me the error:
c:\Users\Devic\Desktop\CompileTester\testCompile.txt(1,29) : error CS1518: Expected class, delegate, enum, interface, or struct
The thread 0x1290 has exited with code 0 (0x0).
Any ideas as to what is going on?
You need to encapsulate the code from your text file into a usable class and method.
Below is code I've been using for a few years that allows C# scripts to run within my app and it even passes in a user defined variable. I had other parameters being passed in within my code to let the script writer have full access to other existing class instances, but I stripped those out as they are unique to my software. You could do the same if you want to provide access to any existing classes or forms in your app.
To use your class PressureTransducer you will need to ensure the DLL which declares that type is properly referenced and the namespace is included in the using section of the Fake code encapsulation. However I have a section built in to automatically reference all assemblies currently referenced by your running program, so that usually takes care of everything automatically.
Also, this takes the code in as a string for the source code and generates the assembly into memory, so there is no disk access - it runs very fast.
NOTE: There is use of an obsolete function in there, codeProvider.CreateCompiler();, but it's still working for me. I probably should update it eventually though.
private static object RunCSharpCode(string CSharpCode, bool ShowErrors, string StringParameter)
{
try
{
#region Encapsulate Code into a single Method
string Code =
"using System;" + Environment.NewLine +
"using System.Windows.Forms;" + Environment.NewLine +
"using System.IO;" + Environment.NewLine +
"using System.Text;" + Environment.NewLine +
"using System.Collections;" + Environment.NewLine +
"using System.Data.SqlClient;" + Environment.NewLine +
"using System.Data;" + Environment.NewLine +
"using System.Linq;" + Environment.NewLine +
"using System.ComponentModel;" + Environment.NewLine +
"using System.Diagnostics;" + Environment.NewLine +
"using System.Drawing;" + Environment.NewLine +
"using System.Runtime.Serialization;" + Environment.NewLine +
"using System.Runtime.Serialization.Formatters.Binary;" + Environment.NewLine +
"using System.Xml;" + Environment.NewLine +
"using System.Reflection;" + Environment.NewLine +
"public class UserClass" + Environment.NewLine +
"{" + Environment.NewLine +
"public object UserMethod( string StringParameter )" + Environment.NewLine +
"{" + Environment.NewLine +
"object Result = null;" + Environment.NewLine +
Environment.NewLine +
Environment.NewLine +
CSharpCode +
Environment.NewLine +
Environment.NewLine +
"return Result;" + Environment.NewLine +
"}" + Environment.NewLine +
"}";
#endregion
#region Compile the Dll to Memory
#region Make Reference List
Assembly[] FullAssemblyList = AppDomain.CurrentDomain.GetAssemblies();
System.Collections.Specialized.StringCollection ReferencedAssemblies_sc = new System.Collections.Specialized.StringCollection();
foreach (Assembly ThisAssebly in FullAssemblyList)
{
try
{
if (ThisAssebly is System.Reflection.Emit.AssemblyBuilder)
{
// Skip dynamic assemblies
continue;
}
ReferencedAssemblies_sc.Add(ThisAssebly.Location);
}
catch (NotSupportedException)
{
// Skip other dynamic assemblies
continue;
}
}
string[] ReferencedAssemblies = new string[ReferencedAssemblies_sc.Count];
ReferencedAssemblies_sc.CopyTo(ReferencedAssemblies, 0);
#endregion
Microsoft.CSharp.CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
System.CodeDom.Compiler.ICodeCompiler CSharpCompiler = codeProvider.CreateCompiler();
System.CodeDom.Compiler.CompilerParameters parameters = new System.CodeDom.Compiler.CompilerParameters(ReferencedAssemblies);
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.IncludeDebugInformation = false;
parameters.OutputAssembly = "ScreenFunction";
System.CodeDom.Compiler.CompilerResults CompileResult = CSharpCompiler.CompileAssemblyFromSource(parameters, Code);
#endregion
if (CompileResult.Errors.HasErrors == false)
{ // Successful Compile
#region Run "UserMethod" from "UserClass"
System.Type UserClass = CompileResult.CompiledAssembly.GetType("UserClass");
object Instance = Activator.CreateInstance(UserClass, false);
return UserClass.GetMethod("UserMethod").Invoke(Instance, new object[] { StringParameter });
#endregion
}
else // Failed Compile
{
if (ShowErrors)
{
#region Show Errors
StringBuilder ErrorText = new StringBuilder();
foreach (System.CodeDom.Compiler.CompilerError Error in CompileResult.Errors)
{
ErrorText.Append("Line " + (Error.Line - 1) +
" (" + Error.ErrorText + ")" +
Environment.NewLine);
}
MessageBox.Show(ErrorText.ToString());
#endregion
}
}
}
catch (Exception E)
{
if (ShowErrors)
MessageBox.Show(E.ToString());
}
return null;
}
You might consider looking at the new Roslyn compiler. You pass a string to the Execute method in the script engine class and it will execute the code on-the-fly.
public class CSharpScriptEngine
{
private static Script _previousInput;
private static Lazy<object> _nextInputState = new Lazy<object>();
public static object Execute(string code)
{
var script = CSharpScript.Create(code, ScriptOptions.Default).WithPrevious(_previousInput);
var endState = script.Run(_nextInputState.Value);
_previousInput = endState.Script;
_nextInputState = new Lazy<object>(() => endState);
return endState.ReturnValue;
}
}
See this article for credit and a complete implementation.

Add additional References when compliling code at runtime

I found this program ( http://support.microsoft.com/kb/304655 ) where i compile the code during runtime, It works for code that uses the reference,
using System;
Following is the the code for the program that compiles code during runtime,
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
textBox2.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = icc.CompileAssemblyFromSource(parameters, textBox1.Text);
if (results.Errors.Count > 0)
{
textBox2.ForeColor = Color.Red;
foreach (CompilerError CompErr in results.Errors)
{
textBox2.Text = textBox2.Text +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
//Successful Compile
textBox2.ForeColor = Color.Blue;
textBox2.Text = "Success!";
//If we clicked run then launch our EXE
if (ButtonObject.Text == "Run") Process.Start(Output);
}
And Following is the code i need to compile at runtime,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
namespace Tsubame
{
class Program
{
static void Main(string[] args)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(#"url");
// Create Client
WebClient client = new WebClient();
// Assign Credentials
client.Credentials = new NetworkCredential("user", "pass");
//Grab Data
var data = client.DownloadString(#"url");
JObject o = JObject.Parse(data);
string getFristRow = Convert.ToString(o["Body"][0]["RowId"]);
string encaplulateStart = "\\\"";
string encaplulateEnd = "\\\":";
List<string> _matches = new List<string>();
_matches = Regex.Matches(getFristRow, #"(?<=" + encaplulateStart + ").*(?=" + encaplulateEnd + ")")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
foreach (string head in _matches)
{
Console.WriteLine(head);
}
Console.ReadLine();
}
}
}
But when I input this gives the error code,
Error Number: CS0234
For the references other than System. May I please know how to add additional references during runtime so that it can compile sucessfully :) Thank you very much :)
You need to add the references in CompilerParameters using CompilerParameters.ReferencedAssemblies:
var parameters = CompilerParameters
{
GenerateExecutable = true,
OutputAssembly = Output,
ReferencedAssemblies = {
"System.dll",
"System.Core.dll",
// etc
}
};
(Of course you don't have to use object initializer syntax to set this up, but it makes it neater IMO.)

Constant error in compiler using C#'s provided objects

I have used the built in C# methods to write a compiler, like the following:
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
this.RadTextBox1.Text = string.Empty;
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, RadTextBox1.Text);
if (results.Errors.Count > 0)
{
RadTextBox2.ForeColor = Color.Red;
foreach (CompilerError CompErr in results.Errors)
{
RadTextBox2.Text = RadTextBox2.Text +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
//Successful Compile
RadTextBox2.ForeColor = Color.Blue;
Guid guid = Guid.NewGuid();
string PathToExe = Server.MapPath(Path.Combine(#"\Compiled" , Output));
FileStream fs = System.IO.File.Create(PathToExe);
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(RadTextBox1.Text);
}
Response.WriteFile(PathToExe);
When I run this code and write a Main method (such as the code sample in http://msdn.microsoft.com/en-us/library/ms228506(VS.80).aspx, I get this error:
Line number 0, Error Number: CS5001, 'Program 'c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Out.exe' does not contain a static 'Main' method suitable for an entry point;
The code above is used as the basis of a compiler on my site (not yet live). So you type in code and generate an .exe assembly. But when I enter code into the textbox for code writing (Radtextbox1), even with a main method, I get the error.
What gives?
Thanks
The entry point function is special: you can't just add a method called "main" to the assembly. Instead you must add an instance of the CodeEntryPointMethod type to one of your classes.
See http://blogs.msdn.com/bclteam/archive/2005/10/01/475768.aspx for more information on some of the limitations of using the CodeEntryPointMethod.

Categories