Título: [Ayuda] [Error] la operación aritmética ha provocado un desbordamiento Publicado por: **Aincrad** en 22 Junio 2019, 17:12 pm Hola, bueno vengo con un pequeño problema. bueno
Tengo un .exe que fue Pasado a Hex y Comprimido después Encryptado (Rijndael). Pero al momento de volverlo a la normalidad osea Desencryptar --- Descomprimir el string ---- pasar hex a bytes me produce el error: (https://i.ibb.co/Nrgr1jL/ddddd.png) Bueno este es el archivo que fue , Pasado a Hex , Comprimido el estring y encryptado : https://anonfile.com/0aI5lbw1n5/Digital_Signature_txt (https://anonfile.com/0aI5lbw1n5/Digital_Signature_txt) Bueno para revertirlo a .exe : Primero Desencryptamos, Segundo Descomprimimos el String, Tercero el String hex lo pasamos a Bytes : Código
y bueno me sale error de desbordamiento , como lo soluciono ? Título: Re: [Ayuda] [Error] la operación aritmética ha provocado un desbordamiento Publicado por: Serapis en 22 Junio 2019, 18:35 pm Debes asegurarte que el el método usado para obtener de vuelta el EXE partiendo de ese txt, sea exactamente la operación inversa a la que hiciste para pasarlo a txt (código que ahí omites).
Al final, para saber si esas conversiones son correctas debes tener el mismo hash para el ejecutable de origen que para el regresado. Pero como te sale un error (no aclaras si es puntual, solo para ese eejcutable y si te salen más con otros ejecutables). Con la imagen cortada del stacktrace, se alcanza a ver solo que falla la función "DecompressData", pero no se alcanza a ver la línea donde falla, y poco más... de lo que se alcanza a leer, parece que al crear un objeto falla el constructor, posiblemente porque precisa hacer alguna operación y el valor de algún parámetro supere el tipo esperado, etc... la ausencia de tales detalles, obliga a descargar el fichero copiar tu código y ejecutarlo para intentar ver que sucede (aunque es claro que es una operación aritmética, no queda claro el punto exacto y la causa original). A la noche saco un tiempito y reviso el código, y te cuento... Mientras puedes al menos si no porporcionas el ejecutable original, indicar su hash MD5 (por ejemplo), para comparar en caso de corregir el error?...o mejor aún, poner también el código que usaste para codificarlo (y así poder ver que una operación sea fielmente la inversa de la otra)? ...se pobaría con otro ejecutable en este caso. Título: Re: [Ayuda] [Error] la operación aritmética ha provocado un desbordamiento Publicado por: **Aincrad** en 22 Junio 2019, 23:40 pm Ocurre con todos los .exe, el error aritmetico se produce .
Código: ************** Texto de la excepción ************** Bueno , pienso que estoy haciendo todo correcto, aca de como paso el exe al txt. Código
En Si es esto : (https://i.ibb.co/mBgBGY6/Diagrama.png) Título: Re: [Ayuda] [Error] la operación aritmética ha provocado un desbordamiento Publicado por: Serapis en 23 Junio 2019, 23:08 pm He tenido un momento para mirar el código...
...pero agárrate que el mensaje va para largo, hay mucho que comentar. El error que tiene tu código está antes incluso d elo que emncionas, concretamente en la función: Código
Y más concretamente en la parte final, en el bloque Try...catch El punto exacto es en la línea: XcsX.Close() Genera un error y salta al bloque 'catch', pero como no 'cazas' nada, entonces sigue la ejecución, ahora devuelves 'UDecryptU' con el valor que tenía a la entrada... finalmente el código encuentra otro error al llegar a la línea que no señalas (ponía el número de línea, pero claro ese número corresponde a la posición que ocupa en tu editor, luego es información desfasada): Dim Buffer As Byte() = New Byte(msgLength - 1) {} El caso es que el error ni siqueira procede de dicha entrada (sigue siendo un texto, aunque NO CONTIENE el contenido que toca), el error (que aquí aparece) es que msglenght tiene un valor negativo, producto de usar el tipo Integer en vez de un UInteger. Es decir esta línea devuelve un valor negativo para mslenght: Dim msgLength As Integer = BitConverter.ToInt32(GZipBuffer, 0) Esta línea toma los 4 primeros bytes del array y los convierte a un entero con signo de 32 bits, luego es perfectamente normal que arroje un valor negativo... ya que un entero de 4 bytes, apenas el byte más alto sea un valor superior a 127, tormará como un negativo). Valor que luego usas para crear un array de dicho tamaño... como no se pueden crear arrays de cantidad negativa, te salta el error que logras ver (pero que ni es el único, ni empeiza ahí)... Me temo que quizás quiseras hacer: Dim msgLength As Integer = GZipBuffer.Length Es decir tomar el tamaño del array... En el bloque Try, como mínimo añade código para la captura de error, si no mejor omitirlo... Un simple ejemplo del añadido preciso. Código
...y como (ahora) en la devolución (si se da un error) la cadena puede estar vacía en la siguiente función precisas un 'if'... La función pués quedaría así... Código
Seguimos... el errror en el CriptoStream.close, se produce porque los datos tienen que estar 'alineados', esto es si quieres cifrar 10 bytes, debes añadir algunos bytes de padding necesarios para que tenga el mismo tamaño, que son los mismos que devueltos... el padding suele ser molesto porque a la vuelta (al decodificar), hay que tenerlo en cuenta e ignorar cuando sea el caso (en Base64 también hay padding, pero lo maneja intenamente la librería). Pero vamos, tu pon el código en 'Catch' (como mínimo lo que te he puesto), para que te señale el error y se pare justo en el primer punto donde se da un error. También veo que haces algo demasiado complejo para simplemente tomar un ejecutable y convertirlo a un fichero de texto plano, completamente legible aunque incomprensible... Un comentario más aún, es que el código es ... bueno me callo calificativos, la intención no es que molestar... pero si resulta engorroso, embrollado, no queda adecuadamente separadas las funciones y hay cosas demasiado pesadas que pueden simplificarse... Por ejemplo la función para convertir a hexadecimal, es muy rebuscada, además adolece a la entrada de duplicar su tamaño, culpa de la línea (en la función previa): Dim Buffer As Byte() = System.Text.Encoding.Unicode.GetBytes(Text) ...pués te va a intropducir un byte 0 por cada otro byte existente, luego además malogra la compresión que luego pretende llevarse a cabo. Otra aberración, es tomar un array de bytes, convertirlo a texto hexadecimal, y luego otra vez convertirlo a un array de bytes... mareas mucho los datos. He rescrito la function BytesToHex (además la he rebautizado) a algo más explícito, y he añadido una sobrecarga para, que partiendo de un array de bytes, obtener de él el array de bytes hexadecimales... Además acelera el cálculo, porque al crear la instancia se crean sendas tablas, luego basta usar la tabla para la conversión (y se evitan conversiones varias).... Las tablas se crean con el constructor de clase. Si te quedas solo con una, comenta la otra y el código correspondiente en el constructor. Añado las dos sobrecargas y debajo tu función 'ConvertToHex', para que compares... Para manejar más cómodamente cada parte, yo he metido el código de sendas partes en sendas clases, manejadas por sendos botones, y todo dentro del código de un formulario (desconozco si tienes algo de interfaz, pero para pruebas y elegir ficheros o rutas suele ser útil, aunque luego al compilar lo descartes y se quede en una dll, por ejemplo). Código
Ahora para aceptar los cambios (y poder usar esas funciones), se debe modificar la función que invoca a Convert y la función Compress Código Incluso aunque usaras la otra sobrecarga o tu función no uses el encoding Unicode, ya que duplica la cantidad de caracteres (en todo caso el ASCII) y el efecto de la compresión será menor... Para terminar como decía, más arriba creo que es demasiado laborioso para simplemente ocultar un ejecutable en texto plano... conversiones a hexadecimal, luego a base64, cifrar con rijndael, comprimir... ni que estuvieras escondiendo el tesoro del tío Gilito. En definitiva tienes cuando menos un par de errores y mucha morralla de código. ...y eso que no lo he revisado todo al completo... Yo veo más simple y igualmente complejo de descifrar, usar un cifrado XOR, y finalmente si lo quieres en texto plano, una conversión a base64 y listo. Me he puesto con ello y en poco más de 2 horas (mediando cena incluído), está funcional y operativo (y al menos en las prueas libre de errores) La función 'AmpliarClave' toma una clave de pocos caracteres y la convierte en una clave del tamaño que se quiera... bastante aleatoria, que ahora podrá usarse para un simple cifrado con XOR, pero inexpugnable, la solidez será la de la propia clave. Debe asegurarse como mínimo que no sean todas las letras iguales: "FFFFFFFFF", generaría una clave del largo pedido pero con el mismo carácter. Puede añadirse una fase 4, donde ahora a los bytes pares se les suma 1 (si llega a 255, pasa a valer 0) y a los bytes impares se les resta 1 (si llega a 0, vale 255), algo así rompe incluso dicha posibilidad. Esta función se puede complicar todo lo que se quiera, su contenido es una muestra. Ahora la función 'CifradoXor' para cifrar con XOR... ojo, no se toma la clave, si no la clave 'ampliada', que genera un tocho pseudoaleatorio y mas que apto, para cifrar. En el ejemplo se ha puesto para que se amplíe hasta 1Mb. en la práctica Finalmente solo faltarían las funciones que invocan a esas... en el ejemplo, la general que realiza ambas funciones. Si es para uso propio queda así más cómodo, en cambio si va a ser para que la usen terceros es preferible desmontarlo en dos funciones, 'Codificar' y 'Decodificar' Código Quitando las líneas de comentarios, son apenas 100 líneas de código para hacer lo que quieres, ambas partes y lo mejor, funciona bien... aunque quizás haya algún gazapo, pués lo he escrito 'al vuelo' y no lo he probado a fondo, solo con 3 ficheros y ya... También adjunto debajo el código de llamada, para mostrar su uso. Supuesto un botón... Código
Si al final se calcula el hash al fichero de origen (para el ejemplo yo he puesto un fichero dll que tenía a mano) y el 'decoded.data', si no hubo problemas debe ser el mismo... yo lo he probando y me funciona bien, y solo he perdido poco más o menos que 2 horas. El código es mucho más escueto, sencillo y consigue el mismo resultado. La fuerza de todo estará en tu "TontoElQueLoLea", que es la clave de cifrado... no precisa tanto rodeo. El fichero de entrada ocupa algo así como 145kb. el 'coded.txt' 194kb. y si lo comprimes (por ejemplo con winrar), sale por 72kb. OJO: Puestos a comprimir, es preferible que sea la primera operación, pués los ejecutables se prestan mejor a una compresión que un tocho codificado en base64 (que siempre aumenta de tamaño). Así si comprimo la dll original con winrar antes de nada se queda en 33kb. p.d.: editado para añadir la línea (comentada) siguiente. IO.File.WriteAllBytes(Application.StartupPath & "\key-" & Op.ToString & ".bin", key) Guarda a fichero la clave generada , para poder realizar luego un estudio de la aleatoriedad de la 'clave ampliada'... Al ejecutar el programa se crearían pués dos ficheros 'crypt/decrypt', que evidentemente serán idénticos. |