Modificar el array de byte[]

Iniciado por Meta, 30 Diciembre 2016, 02:42 AM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Tengo hecho un mini programa en consola C#.
Código (csharp) [Seleccionar]
using System;
using System.IO; // No olvidar.
using System.Diagnostics;

namespace Byte_Hex_ocultos_2
{
   class Program
   {

       byte[] rawData = {
   0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
   0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};

static void Main(string[] args)
       {
           Console.Title = "Imagen oculto.";
           new Program();
       }

       public Program()
       {
           Console.WriteLine("Escribiendo archivo desde el arreglo de bytes");
           File.WriteAllBytes("fotón.jpg", rawData);
           Console.WriteLine("¡Hecho! ¿Deseas ver la foto? Sí / No");
           string input = Console.ReadLine();

           if ((input == "Yes".ToLower()) || (input == "Y".ToLower()) ||
               (input == "Sí".ToLower()) || (input == "S".ToLower()))
           {
               Console.WriteLine("Mostrando imagen...");
               Process.Start("fotón.jpg");
               Console.WriteLine("Imagen cargada.");
           }

           else
           {
               Console.WriteLine("Saliendo...");
           }
       }
   }
}


Justo abajo hay un array tipo byte[] indicaco justo abajo.
Código (csharp) [Seleccionar]
byte[] rawData = {
   0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
   0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};


Estos son pocos byte para probar, en realidad pueden ser millones.
Quiero hacer de alguna manera, modificar a mi antojo cada byte[] del array, por ejemplo, hacerlo de forma básica para probar como curiosidad, lograr desplazar cada bit una vez a la derecha. Esto lo hará otro programa en C#. En el indicado arriba tiene que usar la misma fórmula pero al revés, los byte del array ahora tienen que moverlo a la izquierda una vez para que tengan su posición normal.

Así de paso no es tan fácil detectar lo que hay en el archivo de C#.

¿Alguna idea?

Les dejo el enlace de descarga del proyecto completo, solo tienes que ejecutarlo con Visual Community 2015 y pueden ver que foro tengo escondido, pueden mostrarlo por aquí si les pica la atención.

Descargar

Felices fiestas 2016.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

crack81

#1
Para mi que tu quieres guardar malware o alguna cosa rara en tu programa y parace  te estas haciendo una especie de shellcode para guardarlos y que estén cifrados  o alguna cosa rara  y descifrarlos  en tiempo de ejecución de tu "programa".

Bueno si eso o alguna otra a mi me da igual  :xD
Una alternativa "simple" es que le aplicas un xor a todo ese arreglo de bits y ya cuando lo quieres "descifrar" se lo vuelves a aplicar

Supongamos que a tu arreglo originalmente le aplicaste un xor 10 pues bastaria con le volvieras a aplicar ese xor 10  asi:

Código (csharp) [Seleccionar]
for (int i = 0; i < rawData.Length; i++)
{
   rawData[i] = (byte)(rawData[i] ^ 10);
}


Asi tu archivo o imagen seria restaurado a su estado original, quien tenga duda de la foto vea este enlace: https://i.gyazo.com/6762c171d0871999e12d04c5b627df69.png

PD: Aplicar desplazamiento de bit sin cuidado va a terminar dejando el archivo corrupto aunque se aplique el desplazamiento inverso.

Si C/C++ es el padre de los lenguajes entonces ASM es dios.

Meta

#2
Cita de: crack81 en 30 Diciembre 2016, 03:48 AM
Para mi que tu quieres guardar malware o alguna cosa rara en tu programa y parace  te estas haciendo una especie de shellcode para guardarlos y que estén cifrados  o alguna cosa rara  y descifrarlos  en tiempo de ejecución de tu "programa".

Que risas cogí.  ;-) Curiosidad como se hace, para lo que sospechas, hay ya hechos de forma fácil y muy eficiente. ;)
Eso si, quiero ocultar información dentro de otra información, nada de malware o lo que se te pase por la cabeza. ;)


Bueno si eso o alguna otra a mi me da igual  :xD
Una alternativa "simple" es que le aplicas un xor a todo ese arreglo de bits y ya cuando lo quieres "descifrar" se lo vuelves a aplicar

Supongamos que a tu arreglo originalmente le aplicaste un xor 10 pues bastaria con le volvieras a aplicar ese xor 10  asi:

Código (csharp) [Seleccionar]
for (int i = 0; i < rawData.Length; i++)
{
    rawData[i] = (byte)(rawData[i] ^ 10);
}


Asi tu archivo o imagen seria restaurado a su estado original, quien tenga duda de la foto vea este enlace: https://i.gyazo.com/6762c171d0871999e12d04c5b627df69.png

PD: Aplicar desplazamiento de bit sin cuidado va a terminar dejando el archivo corrupto aunque se aplique el desplazamiento inverso.



Muy buena lo del XOR. Quiero hacerlo al revés con tu código.
¿Cómo sería?

El programa me funciona tal como me lo haz contado.
Código (csharp) [Seleccionar]

using System;
using System.IO; // No olvidar.

namespace Byte_Hex_ocultos_6
{
    class Program
    {
byte[] rawData = {
    0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01,
    0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43
};       
static void Main(string[] args)
        {
            Console.Title = "Imagen oculto.";
            Program variable = new Program();
            variable.Cosas();
        }

        public void Cosas()
        {
            Console.WriteLine("Escribiendo archivo desde el arreglo de bytes");
            // ##############################################

            for (int i = 0; i < rawData.Length; i++)
            {
                rawData[i] = (byte)(rawData[i] ^ 10);
            }

            // ##############################################
            File.WriteAllBytes("fotón.jpg", rawData); // Crea un archivo nuevo.
            Console.WriteLine("¡Hecho! ¿Deseas ver la foto? Sí / No");
            string input = Console.ReadLine();

            if ((input == "Yes".ToLower()) || (input == "Y".ToLower()) ||
                (input == "Sí".ToLower()) || (input == "S".ToLower()))
            {
                Console.WriteLine("Mostrando imagen...");
                //Process.Start("fotón.jpg");
File.WriteAllBytes("fotón.jpg", rawData_XOR10); // Crea un archivo nuevo.
                Console.WriteLine("Imagen cargada.");
            }

            else
            {
                Console.WriteLine("Saliendo...");
            }
        }
    }
}



He puesto otra variable con elXOR 10 ya codificado en vez de poner la original, la foto,claro. Ya sería.
Código (csharp) [Seleccionar]
byte[] rawData_XOR10 = {
    0xF5, 0xD2, 0xF5, 0xEA, 0x0A, 0x1A, 0x40, 0x4C, 0x43, 0x4C, 0x0A, 0x0B,
    0x0B, 0x0B, 0x0A, 0x42, 0x0A, 0x42, 0x0A, 0x0A, 0xF5, 0xD1, 0x0A, 0x49,


Quiero probar el efecto contario, si no me equivoco..
Código (csharp) [Seleccionar]
    for (int i = 0; i < rawData_XOR10.Length; i++)
    {
        rawData_XOR10[i] = (byte)(rawData_XOR10[i] ^ -10);
    }


Lo de desplazamiento de byte tienes que tener en cuenta el bit de acarreo, por eso pasa lo que dices. No es lo mismo (0)11111111 que al desplazar un bit a la derecha (1)01111111. Es más complejo de lo que aparenta porque cada byte con su bit de acarreo y programarlo es más complicado de lo que uno pienza. Estoy acostumbrado al asm de los PIC.

Estoy haciendo pruebas gracias a ti y aprendiendo. ;)

Para curiosos.
https://msdn.microsoft.com/es-es/library/zkacc7k1.aspx
https://www.youtube.com/watch?v=tPfTZbEzcmM

Felices fiestas.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

crack81

#3
Hola a lo mejor no me he sabido explicar bien, cuando usas xor 10 no es necesario poner xor -10 basta con volver a poner xor 10 para hacer efecto.

Revista la documentacion sobre el operador xor https://es.wikipedia.org/wiki/Disyunci%C3%B3n_exclusiva aplica para cuaquier lenguaje de programacion

Ejemplo
Supongamos que usamos la letra A  el equivalente numerico en la tabla ASCII es el 65 cuando usamos el XOR lo que estamos haciendo es es convertir ese 65 a binario el cual seria

01000001

si le aplicamos el XOR 10 lo que estariamos haciendo seria esto

01000001  ===> 65
00001010  ===> 10
------------
01001011  ===> el cual seria el numero 11

ese 11 seria el numero "cifrado" si quisieramos obtener el valor original valdria tomar el equivalente del 11 en binario y volver a aplicar el XOR 10

01001011   ===>11
00001010   ===>10
-------------
01000001 ===== Nos regresa el 65 ===> A

si te fijas nos regreso el valor original


Esto mismo aplicalo a arreglo de bytes o string  que al final siguen siendo numeros y tiene un funcionamiento similar


Tablas ASCII http://www.elcodigoascii.com.ar/
Aqui un ejemplo mas detallado sobre los operadores de bit http://www.conoce3000.com/html/espaniol/Libros/PascalConFreePascal/Cap03-06-Operadores%20para%20digitos%20binarios%20(bits%20-%20digitos%20binarios).php        

cabe aclarar que esta orientado al lenguaje Object Pascal pero la teoria aplica para cualquier lenguaje.








Si C/C++ es el padre de los lenguajes entonces ASM es dios.

Meta

#4
Buenas:

Muy buena explicación. Funciona a la perfección.

Muchas gracias mi muy distinguido amigo. ;)
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Meta

Hola de nuevo:

Urgando en mi grupo de amigos con esto.
Código (csharp) [Seleccionar]
    for (int i = 0; i < rawData.Length; i++)
    {
        rawData[i] = (byte)(rawData[i] ^ 10);
    }


En el cual estoy agradecido porque funciona de maravilla. Si hago un programa para cifrar de C# una foto, usando el mismo efecto puede desemcriptarlo.


  • Hago tres programas de C#.
  • Programa 1 de C# para cifrar cualquier archivo, es este caso una imagen.
  • Meto la escriptación en el .hex de Arduino ya explicado atrás.
  • Programa 2 de C# capturo los datos de Arduino por el puerto serie/USB.
  • Programa 3 de C# lo desemcripta.

Cuidado una cosa, al menos no he caido antes y lo comento por aquí mismo. ;)
Si cifra una imagen con el programa 1 de C#, lo cifra, si lo vuelve hacer, se descompila y se recupera la imagen. MEnudo fallo y no me di cuenta.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Meta

Hola de nuevo:

He hecho este programa. Arduino ulsa un botón y este programa de C# lo descodifica como dijeron arriba. Como puedes ver, el archivo viene desde Arduino por el puerto serie/USB.

¿Existe la manera de usar la descodificación de la foto?

C#:
Código (csharp) [Seleccionar]
using System;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace Recibir_archivo_desde_Arduino_consola_06
{
    class Program
    {
        static int cantidadBytes;
        static StringBuilder sb = new StringBuilder();

        static void Main(string[] args)
        {
            string COM = "";

            // Tamaño ventana consola.
            Console.WindowWidth = 55; // X. Ancho.
            Console.WindowHeight = 18; // Y. Alto.
            Console.Title = "Recoger foto desde Arduino y crearlo en el disco duro"; // Título de la ventana.

            // Crear un nuevo objeto SerialPort con la configuración predeterminada.
            SerialPort Puerto_serie = new SerialPort();

            // Configuración.
            Console.Write(@"
Introduzca un número para seleccionar puerto COM.
Por ejemplo el 4, sería COM4.

Puerto: ");
            COM = Console.ReadLine(); // Escribir el número del puerto.
            Console.Clear();

            Puerto_serie.PortName = "COM" + COM; // Número del puerto serie.


            Puerto_serie.BaudRate = 115200; // Baudios. 115200.
            Puerto_serie.Parity = Parity.None; // Paridad.
            Puerto_serie.DataBits = 8; // Bits de datos.
            Puerto_serie.StopBits = StopBits.One; // Bits de parada.
            Puerto_serie.Handshake = Handshake.None; // Control de flujo.

            // Establecer la lectura / escritura de los tiempos de espera.
            Puerto_serie.ReadTimeout = -1; // 500.
            Puerto_serie.WriteTimeout = -1; // 500.

            try
            {
                Puerto_serie.Open(); // Abrir el puerto serie.
            }

            catch (IOException)
            {
                Console.ForegroundColor = ConsoleColor.Red; // Texto en rojo.
                Console.CursorVisible = false;
                Console.SetCursorPosition(16, 6);
                Console.WriteLine(@"El puerto " + Puerto_serie.PortName + @" no existe
                o no lo encuentra.");
                Console.ReadKey(); // Pulse cualquier tecla para salir.
            }

            catch (UnauthorizedAccessException e)
            {
                Console.WriteLine(e);
            }
            Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

            Console.WriteLine("Esperando datos desde Arduino... \n");
            Console.ReadKey();
            Puerto_serie.Close(); // Cerrar puerto.
        }

        private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                SerialPort sp = (SerialPort)sender;
                string indata = sp.ReadExisting();
                string[] data = indata.Split('A');
                cantidadBytes = int.Parse(data[0]);


                switch (data[1].ToString())
                {
                    case "1":
                        Console.WriteLine("Tamaño: " + cantidadBytes + " Bytes.");
                        Console.WriteLine("Foto: " + data[1] + ". Tipo de archivo: JPG");
                        break;

                    case "2":
                        Console.WriteLine("Tamaño: " + cantidadBytes + " Bytes.");
                        Console.WriteLine("Foto: " + data[1] + ". Tipo de archivo: PNG.");
                        break;

                    default:
                        Console.WriteLine("Cosas raras en 'data': " + data.ToString()); // Por si hal algún error.
                        break;
                }

                int contador = 0;
                byte[] datosArray = new byte[cantidadBytes];

                //byte[] miBuffer = Encoding.ASCII.GetBytes("OK1");
                //sp.Write(miBuffer, 0, miBuffer.Length); // Envía OK1 a Arduino.

                switch (indata)
                {
                    case "17729A1":
                        Thread.Sleep(100); // Retardo.
                        byte[] miBuffer = Encoding.ASCII.GetBytes("OK1"); // Codificación ASCII.
                        sp.Write(miBuffer, 0, miBuffer.Length); // Envía OK1 al puerto serie.
                        break;

                    case "2065A2":
                        Thread.Sleep(100); // Retardo.
                        byte[] miBuffer2 = Encoding.ASCII.GetBytes("OK2"); // Codificación ASCII.
                        sp.Write(miBuffer2, 0, miBuffer2.Length); // Envía OK2 al puerto serie.
                        break;

                    default:
                        Console.WriteLine("Cosas raras en 'indata': " + indata.ToString()); // Por si hal algún error.
                        break;
                }

                while (true)
                {

                    contador += sp.Read(datosArray, contador, datosArray.Length - contador);

                    Console.SetCursorPosition(10, 6);
                    Console.Write("Datos recibidos:  {0}", contador + " Bytes.");
                    Console.WriteLine("                   ");

                    if ((contador == cantidadBytes) && (contador == 17729))
                    {
                        Mensaje1();
                        File.WriteAllBytes("fotón.jpg", datosArray); // Crear archivo en el disco duro.
                        Mensaje2();
                        Process.Start("fotón.jpg"); // Ejecutar visualizador de imágenes.
                        Mensaje3();
                        break; // Garantiza que el ciclo termine.
                    }

                    if ((contador == cantidadBytes) && (contador == 2065))
                    {
                        Mensaje1();
                        File.WriteAllBytes("fotón.png", datosArray); // Crear archivo en el disco duro.
                        Mensaje2();
                        Process.Start("fotón.png"); // Ejecutar visualizador de imágenes.
                        Mensaje3();
                        break; // Garantiza que el ciclo termine.
                    }
                }

                void Mensaje1()
                {
                    Console.WriteLine();
                    Console.WriteLine("Creando archivo al disco duro...");
                }

                void Mensaje2()
                {
                    Console.WriteLine();
                    Console.WriteLine("Archivo creado. Ejecutando imagen.");
                }

                void Mensaje3()
                {
                    Console.WriteLine();
                    Console.WriteLine("Imagen ejecutada.");
                    Console.WriteLine();
                    Console.WriteLine("Cabecera recibida: " + indata + "\n");
                    Console.ForegroundColor = ConsoleColor.Yellow; // Letras amarillas.
                    Console.WriteLine("FIN DE PROGRAMA.");
                    Console.ForegroundColor = ConsoleColor.Gray; // Letras grises otra vez.
                }
            }

            catch (FormatException)
            {
                // System.FormatException: 'La cadena de entrada no tiene el formato correcto.'
            }
        }
    }
}


Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/