2009-06-08 10 views
7

Tengo un programa que lee en una matriz de caracteres. Necesito que el valor de la cadena en la memoria sea igual al hex 0x01020304, que son todos caracteres no ASCII. Entonces la pregunta es, ¿cómo paso caracteres no ASCII en una variable literal de cadena en tiempo de ejecución?Cómo inyectar caracteres no ASCII en un literal de cadena en C/C++

+0

Esta no es una pregunta C o C++, es una pregunta terminal. Tendrás que averiguar cómo hacerlo con tu terminal específico. 0x03 puede resultar especialmente problemático ya que enviarlo a menudo provoca la finalización del proceso. – Don

+0

@ Don: un 0x03 directo entregado al terminal de control puede, pero dependiendo del método de entrada de datos (como escribir valores a través del teclado) puede que no. La pregunta es un poco vaga sobre cómo el OP espera recibir información. –

Respuesta

17

Usa una secuencia de escape. Asegúrate de poner los caracteres en el orden correcto.

"\x01\x02\x03\x04" 

Editar:. Si usted necesita para poner la secuencia en un array de caracteres existente, basta con asignarle en

char s[4]; 

// ... later ... 
s[0] = 0x01; 
s[1] = 0x02; 
s[2] = 0x03; 
s[3] = 0x04; 

No intente asignar el número echando s a (int32_t *), la matriz de caracteres no tiene la alineación correcta.

+1

Eso funcionaría si estuviera codificando los valores en mi programa, pero necesito poder ingresarlos en tiempo de ejecución. Lo siento si la pregunta no fue lo suficientemente específica. –

+1

Ben, por favor actualice su pregunta en consecuencia. – avakar

2

Bueno, ¿estás seguro de que necesitas una cadena literal?

Estos son todos bastante similares:

const char* blah = "test"; 
char blah[] = "test"; 
char blah[] = { 't','e','s','t',0 }; 

ciertamente se podría utilizar la tercera forma para sus necesidades con bastante facilidad.

3

Probablemente el más fácil, en C, es utilizar la notación de escape hexadecimal: "\x01\x02\x03\x04". (Sin las x, los valores están en octal, lo que no es tan popular o comprensible en la actualidad.)

Alternativamente,

char x[] = {1, 2, 3, 4, 0}; 

debería funcionar (nótese que la terminación nula tiene que ser incluido en la inicialización Me gusta esto).

+0

Eso funcionaría si estuviera codificando los valores en mi programa, pero necesito poder ingresarlos en tiempo de ejecución. Lo siento si la pregunta no fue lo suficientemente específica. –

+0

Entonces, ¿cuál es tu pregunta? ¿Cómo lograr que ingresen al programa? (Esto probablemente significará más describir su entorno). ¿Cómo moverlos una vez en el programa? –

2

Necesito que el valor de la cadena en la memoria sea igual a hexadecimal 0x01020304, que son todos los caracteres no ASCII.

tenga cuidado Cómo se disponen de 4 bytes en la memoria contigious dependerá si el sistema es grande-endian o little-endian. Si te importa cómo funciona el campo de 32 bits, simplemente poner cosas en una cadena literal no funcionará.

Por ejemplo:

Usted podría intentar, como avakar sugiere:

char cString[5] = "\x01\x02\x03\x04"; 

o incluso sólo hacer

cString[0] = 0x01; 
cString[1] = 0x02; 
... 

pero si espera que el diseño físico real en la memoria a tener sentido :

// assuming unsigned int is 32 bits 
unsigned int* cStringAlias = rentirpret_cast<int*>(&cString[0]); 
std::cout << (*cStringAlias) 

Tenga cuidado, la salida diferirá dependiendo de si el byte más significativo se coloca en la ubicación 0 o la ubicación 3.

La salida podría ser

0x01020304 

o

0x04030201 

Para más información, leer sobre endianess.

1

Guarde la fuente en UTF8 y trate todas las cadenas como UTF-8 (o use algo de la línea StringFromUTF()).

Cada vez que no trabaja en una página de códigos universal (sí, UTF-8 no es realmente una página de códigos ...) está solicitando problemas.

0

Es posible que desee intentar usar std::hex:

int temp; 
char sentMessage[10]; 
     for(int i = 0; i < 10; ++i) 
     { 
      std::cin >> std::hex >> temp; 
      sentMessage[i] = temp; 
     } 

A continuación, introducir el valor hexadecimal de cada personaje, por ejemplo. 01 11 7F AA

0

Puede usar std::wcin y std::wcout para soporte unicode para la consola. Sin embargo, no estoy seguro si son parte del estándar.

1

Al escribir código C, puede utilizar memcpy() para copiar datos binarios:

memcpy(dest + offset, src, 4); 

Si src es una cadena, que presumiblemente lo consigue en el orden correcto. Si se trata de un número entero (por ejemplo, uint32_t) y se necesita un orden de bits específica, puede que tenga que invertir el orden de los bytes antes de hacer memcpy():

uint32_t src; 

... 

swap((unsigned char *) &src, 0, 3); 
swap((unsigned char *) &src, 1, 2); 

donde intercambio() se define por tú. Debe hacer esto solo si el endianness de la máquina no coincide con la endianidad de salida deseada.

Puede descubrir la endianidad observando ciertas definiciones establecidas por el compilador o la biblioteca C. Al menos en glibc (Linux), endian.h proporciona tales definiciones, y byteswap.h también proporciona funciones de byte-swapping.

1

Como está hablando de inyección, le daré una pista (Esto es útil para una inyección de código que explota una vulnerabilidad de desbordamiento de búfer, para fines académicos) ... Debe configurar su terminal para aceptar unicode (en mi Mac podrías escribirlos por defecto).Así que escribe, por ejemplo, cosas como ∫, cuando ingresa un carácter unicode, no toma solo un byte en la memoria como un carácter normal, se necesitarán más bytes (puede ser de dos, tres o cuatro bytes), así que si tiene un gama

char v[4]; 

y si se utiliza

gets(v); //insecure function to read 

y entrar en este ∫ los 4 bytes que toma V en la memoria se llena de estos valores (en decimal):

-30 
-120 
-85 
0 

Si ve alguna de esas posiciones únicas, ninguna de ellas es ASCII imprimible, podría tratarse de algún código que podría obtenerse en la memoria y hacer que el programa lo ejecute pirateándolo cambiando un directorio de retorno en la pila también explotando el mismo desbordamiento de búfer vulnerabilidad que permite get(). (para obtener el código abra su programa en un editor HEX para ver cómo se ve todo cuando se compila).

lo que sólo tiene que encontrar los caracteres Unicode correctos que coinciden con lo que necesita mediante la impresión en un archivo

En este enlace cualquiera puede hacerse una idea de cómo la memoria se asigna en la pila http://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/

(Parece que @Ben ya no tiene una cuenta, pero para cualquiera que esté aprendiendo programación segura que lo necesite)

Cuestiones relacionadas