Título: Ayuda con Scaneer Hexadecimal Publicado por: **Aincrad** en 3 Agosto 2018, 02:12 am Bueno como dice el titulo. necesito ayuda con un escaner hex. Bueno pondré el code y de ultimo mis preguntas!
Bueno tengo un Listbox con el sig directorio de archivos: Código: C:\Users\S4LXenox\Desktop\Ransomware Wannacry - copia.exe y con un boton escaneo cada archivo del listbox : code del boton: Código
Y aquí la Función de scaneo hex: Código
Bueno ahora mis dudas: 1) Cuando Utilizo el OPENFILEDIALOG En el botón y selecciono un virus el sacanner funciona y lo detecta! , Pero cuando coloco el directorio del virus en el listbox asi como puse arriba , el scanner no detecta nada! como corrigo eso? 2) Cuando intento escanear un archivo de mas de 10 mb tarda muchísimo! aunque eso se puede arreglar con un BackgrounWorker y asi no se pegue la app, pero no hay manera de hacer el escaneo hex mas rapido? Bueno eso es todo, Gracias de antemano! Título: Re: Ayuda con Scaneer Hexadecimal Publicado por: Serapis en 3 Agosto 2018, 18:34 pm De entrada no dejas claro si los ficheros tienen algún formato específico o no, es adecir asumo que son tal cual señalan sus extensiones (si .exe porque es un ejecutable, etc...)
Los ejecutables típicamente no son muy grandes (es difícil encontrar uno mayor de 100Mb.), así que lee todo el contenido del fichero de una sola tacada en un array de bytes. Puedes limitar la lectura si no precisas buscar en todo el fichero, si no solo hasta cierto punto (obviamente solo si hay una razón para ello), o también puedes desestimar ficheros más grandes de x tamaño (para leerlos al final, cuando acabes con los más pequeños), pasándolos a una segunda lista... Si el fichero debe analizarse al completo incluso aunque se haya encontrado una signatura de virus, leerlo completo de una vez es más eficaz, pero si tras un hallazgo puede descartarse seguir buscando en el fichero, con ficheros grandes, por el contrario, sería más eficaz leer buffer a buffer (por ejemplo 1-4Mb. en cualquier caso siempre que operes con ficheros múltiplo de 64kb.), y si tras encontrar un positivo ignoras el resto del fichero y saltas al siguiente... pués así evitas más lecturas d elas necesarias. Tu problema de rendimiento, se debe a que te emperras en operar con texto, strings, caracteres y conversiones inútiles de texto de forma constante y reconstrucción de cadenas. Lee bytes y evita conversiones y reconstrucción de cadenas, es decir opera con array de bytes. Por ejemplo, este código es muy deficiente de cara al rendimiento: Código Es un código cansinom machacante con cada byte leído... Realizas múltiples operaciones por cada byte leído en el fichero, que resultan innecesarias si lo planteas correctamente, además "detrás-debajo", hay más trabajo aún del que te imaginas, Append y '&' son concatenaciones que reconstruyen de nuevo la cadena. Esto es ,buscan memoria libre (del tamaño preciso) y crean una nueva cadena copiando todo el contenido previo y poniendo detrás (ahora que hay espacio libre) el contenido que se concatena... esto por cada byte leído de un fichero, es una enorme pérdida de eficiencia... Claro, que según se ve, en el primer bucle tu objetivo es preparar la entrada conforme a un xml, para luego hacer una búsqueda de cada valor del xml sobre la entrada preparada... es decir, inicialmente el panteamiento estaría bien si fuera solo para un único fichero y no muy grande... pero no es el caso. Aquí también puede optimizarse mucho (lo del xml), porque esto (obviando todo el trabajo previo, es decir al margen del mismo), resulta ineficiente... ya que si ordenaras las "signaturas" en el xml, cada vez que haya un positivo, implica que el punto donde se localiza en 'str', puede pasar a ser el punto de inicio de la siguientes signaturas... del mismo fichero Esto lo vamos a ver más ampliamente detallado debajo, así que tacho para evitar desviarte hacia derroteros no necesarios... Para que esto mejore notablemente el rendimiento, ambos bucles deben ser fusionados en uno solo... pero no tan simple como eso... ya que es preferible cambiar el planteamiento. Por tanto, lo mejor es tratar primero las signaturas en el xml. Habría que 'preparalas' y ordenarlas alfabéticamente... Es decir el tratamiento individualizado, debe hacerse al XML (y no al revés), en vez de a cada fichero (vamos es más rápido hacer una conversión sobre 1 único fichero (el xml), que a 200 ficheros de incluso varios Mb. a hexadecimal)... Dicho de otro modo, ignora que sea un xml, por mucho que NET tenga funciones óptimas de procesarlos, están pensados para otras cosas, no precisamente para ficheros binarios... de hecho, la idea de los xml, es procesar texto pero que un observador todavía pueda modificarlo manualmente ...por que lo puede ver y entender... aquí en cambio, se va a hacer tabajo 'sucio' donde no se deja nada a la acción externa, luego el xml, está bien para el mantenimiento de firmas, pero para la búsqueda sobre ficheros es preferible su 'reconversión a binario', y no al revés (convertir en hexadecimal todos los ficheros donde se quiere buscar)... una vez hecha esa conversión es cuando procede ordenar las entradas... ...y a partir de ahí, y estando ordenado, y colocadas las entradas en una estructura que aloja arrays de bytes, se busca el primer byte de la entrada, en el fichero de origen... Más aún conviene meter en un único array el primer byte de cada firma (sin repetición), así puede RECORRERSE EL FICHERO FICHERO DE ORIGEN UNA ÚNICA vez para buscar todas las firmas (que cumplan una "condición"), al mismo tiempo ... y con esto llegamos a lo más óptimo que puede llegarse... Puede darse el caso que haya tantas firmas que prácticamente todos los bytes (del 0 al 255), sean el byte inicial de alguna firma... De hecho vamos a dar por cierto que sea así, dado el caso de miles de firmas... conviene estudiar el caso para optimizar según uno u otro caso (pero consideremos el 2º)... En cualquier caso debe haber una estructura tal que así (Y YA VAMOS ORDENANDO LAS IDEAS): 1 - La primera acción al abrir la aplicación, es leer el xml, reconvertir las firmas a ASCII (desde hexadecimal si así están) y desmontarlo en un array de esta estructura... Código Sea un array de 8.000 firmas de dicha estructura (ya generado a partir del xml, lo cual se hace una única vez, es decir solo procesamos con estúpidas conversiones un único fichero, esas 8.000 firmas..., incluso aunque no sea de modo eficiente, es un solo fichero una sola vez, y salvo que sea un fichero gigante, no tendrá pérdida de rendimiento significativo generarlo incluso de forma deficiente)... Eso queda a tu esfuerzo... es manejo de texto básico. 2 - Una vez generado el array de estructuras, debe reordenarse por el campo 'firma' (que es un array de bytes)... OJO: no hablamos de ordenar el array Firma, sino el array de estructuras considerando el campo 'firma'. En realidad resulta más sencillo primero reconvertir las firmas a cadenas de texto ASCII, luego ordenar dicho array (de strings), y ya ordenado trasvasarlo al array de estructura. Y para no verse obligado a mantener una asociación del índice de la firma antes y después de ordenar, puedes concatenar el 'name' tras la firma, así el cambio de orden transporta consigo el resto de datos, y luego, al trasvasarlo a la estructura firma= Getbytes(x,n) y name tomará la subcadena del final... Entonces al caso, añadir otro campo llamado Size que señale cuantos caracteres (bytes) consta la firma, resulta útil para varias cosas... 3 - Array de estructuras de la que a su vez se debe crear una tabla de búsqueda... y ahí radica la potencia de búsqueda, ya que solo precisará buscarse ciertas firmas, las que coincidan con ese byte inicial. Y todo se opera a nivel de byte con byte sobre dos arrays... esto será muy rápido... Ésta es la última parte del tratamiento del array de firmas... crear un índice de búsqueda... Básicamente creamos una tabla, del mismo tamaño que el array de firmas (+1) y le indicamos a cada item, que la primera firma que empieza por un byte concreto empieza en el índice x... esto implica que todas las firmas que empiecen por el mismo byte, estarán contiguos (porque las ordenamos previamente), y por tanto en el nuevo array tblBusqueda, apuntan al índice de la firma de la primera firma que comienza con ese byte, resumiendo todas las firmas que empiezan por el mismo byte comparten el índice de la primera firma que empeiza por ese byte, así sabremos cuando terminar de buscar otra firma... Código
un pequeño code de como sería en este punto, la búsqueda usando dicho tabla... - 4 Es decir el bucle principal de búsqueda una vez leído un fichero... Código
5 - La función que busca el patrón recorriendo dos arrays de bytes... Código
No haré todo el código... pero lo principal está hecho... 3 - El código para crear la tabla de búsqueda, 4 - El código para buscar patrones a lo largo de un archivo. 5 - el código para buscar los patrones que puedan ser derivados del byte actual en el fichero (a falta de los cambios que tu precises). Lo que te falta pués, tu mayor trabajo es operar el xml, para: 1 - extraer de él, las firmas convertidas a la estructura indicada y que 2 - luego deben ser reordenadas en el array de firmas... Dentro del punto 4, falta también la lectura del fichero de origen para volcarlo en un array de bytes... Es decir, te he aclarado, la forma a seguir para que el rendimiento sea lo más óptimo posible a la hora de buscar... es posible otras optimizaciones pero son de menor importancia, y en todo caso, habría que verlo una vez tuvieras el código... La solución ahora podría tener más líneas de código, y quizás resulte más oscuro o menos elegante, pero sin duda será 100 veces más rápido que lo que ahora mismo tienes y que solo valdría para una pequeña cantidad de firmas... - Algunos comentarios aparte: Una dudosa es que cuando encuentras una firma, sobre el texto preparado, parece bastar y no se sigue buscando si aparece más veces. Debe uno decidir si esto es conforme o no, y si lo es conviene dejar comentario del caso, por sí a futuro, relees el código y encuentras este 'defecto', que pueda observarse que es conforme y así fue decidido, y no que fue por omisión... Esto cae en lo mismo que si sobre un fichero se encuentra un patrón de visrtus, es necesario buscar más patrones de otros virus ???... quizás como en lo reciñén comentado una vez encontrado un patrón de virus sobre un fichero, pueda saltarse al siguiente y dejar comentario pertienente al caso... Como un falso positivo siempre se puede dar, parece razonable seguir buscando más patrones distintos de virus sobre el fichero, cuantos más patrones hallados en un fichero, más difícil será que se trate de un falso positivo... - Luego hay cosas menores que pueden ser mejoradas.... --- 0 No veo declaraciones de tipo para diferentes variables: IndexEnd, Index, tStr , tempStr... --- 1 En cambio la veo para x in situ... las declaraciones in situ, son muy ´´utiles para variables que aparecen una sola vez, en un solo sitio... pero al ser un bucle, no es precisamenrte el mejor caso donde tiene sentido su forma de hacerlo, es decir en este caso es mejor declaralo al comienzo de la función. --- 2 Esto resulta redundante: Código
Mejor así: Código
--- 3 El siguiente código, también resulta un poco redundante... Código
Si se encuentra un patrón, se añade, luego la cuenta ya será como mínimo 1 nunca más cero, luego huelga preguntar cada vez si es 0. Puede ponerse fuera del bucle... Así: Código
Bien es cierto que si un fichero fuera excesivamente grande la aparición de una firma, no se haría notar hasta completar la búsqueda por completo (con ejecutables esto sería tan poco tiempo, que no merece la pena, pero bueno supongamos un fichero gigante)... si quiere indicarse el momento exacto cuando aparece (para mantener más puntualmente informado al usuario), podría modificarse así: Código
p.d.: He eliminado o tachado un par de comentarios que se podrían prestar a confusión y recalcado puntos y puesto en negrita, que por ser texto plano, puede no dárseles la importancia debida y pasarse por alto. Nota: Cuando uno escribe código sobre la marcha no repara demasiado a veces en las partes que pueden precisar un "x-1", así que no se descarta esas posibilidades de error, que sin embargo son fáciles de acometer con el entorno de desarrollo abierto... Título: Re: Ayuda con Scaneer Hexadecimal Publicado por: **Aincrad** en 5 Agosto 2018, 00:20 am Gracias! lo probare! :D
|