Cómo validar longitud de matriz de bytes recibidos, que no está terminada en nulo?
-
25-09-2019 - |
Pregunta
Tengo código de un C \ C ++ que recibe una estructura sobre la red, de esta forma:
struct DataStruct
{
int DataLen;
BYTE* Data;
}
El código que tengo carreras en Data
en un bucle de veces DataLen
y procesa los datos.
... El problema:
Después de que el código de vino a los expertos en seguridad para los ensayos de penetración, se preparó una falsa aplicación que envía esta estructura con DataLen
más grande que la longitud real de Data
. Este causas, por supuesto, una excepción de acceso violación.
Entonces, la pregunta es - ¿cómo puedo validar la longitud real de la Data
recibido? ¿Es posible sin cambiar la estructura?
Gracias de antemano.
Solución
Nice! Me gustaría que mi compañía tenía un departamento de esa manera.
Siempre que se recibe datos de la red, la red IO informa del número de bytes realmente registra en el búfer, si usó read(2)
, recv(2)
o boost::asio::async_read
o cualquier otra cosa que he visto. caso de uso típico cuando hay un "número de bytes a seguir" en el encabezado de la estructura de datos, es llamar a leer varias veces / recv / etc hasta que la transmisión de muchos bytes (o hasta que se produjo el error), y sólo entonces se debe construir y devolver su DataStruct (o informe de errores).
Otros consejos
Usted sabe cuánto bytes que ha recibido, por lo que sólo compararlo con DataLen
.
Es imposible sin cambiar la estructura. Los datos recibidos de socket TCP / IP es corriente normal. Lógicamente, no se divide en paquetes. paquete físico puede contener uno o más instancias DataStruct, una instancia DataStruct se puede dividir a dos o más físicos paquetes. estructura de la información actual sólo se puede utilizar si no hay errores de comunicación o paquetes inválidos.
La corrupción es fácil si usted no tiene ninguna limitación intrínseca.
Algunos mecanismos de protección serían:
- Trate de
realloc()
la memoria intermedia, dentro de un cierto tamaño aceptable (siData
es dinámica) - Excepciones son los amigos: uso
SIGSEGV
ensignal(2)
,signal(7)
ysetjmp(2)
hacer algo de utilidad try / catch estructura de código. Ver Combinando setjmp () / longjmp ( ) y Señales para una rápida introducción sobre este tema. Usosigaction(2)
para ir más profundo (por conseguir la dirección defectuosa;).