elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el ttwitter! de elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Ayuda con Scaneer Hexadecimal
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda con Scaneer Hexadecimal  (Leído 369 veces)
**Aincrad**


Desconectado Desconectado

Mensajes: 506



Ver Perfil
Ayuda con Scaneer Hexadecimal
« en: 3 Agosto 2018, 02:12 »

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
C:\Users\S4LXenox\Desktop\eicartest.exe
C:\Users\S4LXenox\Desktop\parite.exe

y con un boton escaneo cada archivo  del listbox :

code del boton:

Código
  1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  2.        listv.Items.Clear()
  3.        For abc = 0 To ListBox1.Items.Count - 1
  4.  
  5.             Scan(ListBox1.Items(a).ToString)
  6.  
  7.        Next abc
  8.    End Sub


Y aquí la Función de scaneo hex:

Código
  1.  
  2.  
  3. Dim xml = <?xml version="1.0"?>
  4.              <signatures>
  5.                  <signature>
  6.                      <name>Eicar-Test-Signature</name>
  7.                      <hex>58354f2150254041505b345c505a58353428505e2937434329377d2445494341522d5354414e4441</hex>
  8.                  </signature>
  9.                  <signature>
  10.                      <name>Hybris.Gen</name>
  11.                      <hex>f649e7cc1e00d37e7f3bc85fff3486ac6de91433aa3a39ef1b114d37b534b8323f6ff67132638a3fe2f2afb4aaf9b7e3b4669bb3cab028298aab533c5d73546cdd396fd58c2c7734c50bca68eb709b889a086fb3db5f8ae533a4d5816e8c5f560983695efa14e291c204b1316e657773</hex>
  12.                  </signature>
  13. </signatures>
  14.  
  15. Private Sub Scan(ByVal dir As String)
  16.  
  17.  
  18.        Dim myStreamReader As StreamReader = Nothing
  19.        myStreamReader = File.OpenText(dir)
  20.        InputString = myStreamReader.ReadToEnd()
  21.        ArrayHold = Encoding.Default.GetBytes(InputString)
  22.  
  23.        Do
  24.            IndexEnd = Index + 9
  25.  
  26.            For x As Integer = Index To IndexEnd
  27.  
  28.                If x > UBound(ArrayHold) Then
  29.                    tempStr = tempStr
  30.                Else
  31.                    tStr = UCase(Convert.ToString(ArrayHold(x), 16))
  32.  
  33.                    If tStr.Length < 2 Then tStr = "0" & tStr
  34.  
  35.                    Str.Append(tStr)
  36.                    tempStr = tempStr & Chr(ArrayHold(x))
  37.  
  38.                End If
  39.            Next
  40.  
  41.            Index = Index + 10
  42.        Loop While IndexEnd < UBound(ArrayHold)
  43.        For Each signature As XElement In xml.Root.Elements
  44.            If InStr(1, Str.ToString, signature.<hex>.Value, vbTextCompare) Then
  45.                listv.Items.Add(signature.<name>.Value)
  46.                If listv.Items.Count > 0 Then
  47.                    Label1.Text = "Virus"
  48.                Else
  49.                    Label1.Text = "No Virus"
  50.                End If
  51.            End If
  52.        Next
  53.  
  54.    End Sub



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!


En línea


NEBIRE


Desconectado Desconectado

Mensajes: 2.337


Ver Perfil
Re: Ayuda con Scaneer Hexadecimal
« Respuesta #1 en: 3 Agosto 2018, 18:34 »

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
  1.    tStr = UCase(Convert.ToString(ArrayHold(x), 16)) ' <--- lee del array y hace 2 conversiones (toString y Ucase)
  2.    If tStr.Length < 2 Then tStr = "0" & tStr  ' <---- si la longitud es menor de 2 antecedes un 0, esto es reconstruyes la cadena
  3.    Str.Append(tStr)   ' <---- reconstruyes str con append
  4.    tempStr = tempStr & Chr(ArrayHold(x))  ' <--- reconstruyes tempstr y haces una conversióna string desde array (con la función chr).
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 (o buffer si lees a tramos, por eso es también más eficiente leer el fichero de una sola vez si no excesivamente grande y si los hay (demasiado grandes), dejarlos apara el final y solo en estos ser ineficientes leyendo en búferes más manejables por si la memoria disponible es crítica))... Lógicamente si un fichero solo tendrá 1 o 2 firmas positivas, no se notará en exceso el beneficio (para ese 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
  1. Structure DatosDeFirmas
  2.    ByteInicial as byte
  3.    Firma() as byte
  4.    Name as string       ' solo si lo precisas, si los patrones tienen alguna info que precise ser volcada a texto (como pondré de ejemplo)...
  5. End Structure
  6.  
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
  1.    dim tblBusqueda(0 to ArrayFirmas.lenght+1) as int32
  2.    dim j as int32, k as int32
  3.    dim ptInicio as int32
  4.  
  5.    'tblBusqueda(ArrayFirmas.lenght+1) = 0  añadir un índice más nos evitará desbordamientos y chequeos para evitarlo. Sol oprecisaremos una condición para el bucle
  6.  
  7.    ptInicio= -1  ' para forzar ya con el índice 0 la asignación de valores.
  8.  
  9.    For k = 0 to Arrayfirmas.lenght -1
  10.        if (Arrayfirmas(k).ByteInicial<> ptInicio) then
  11.            ptInicio =  Arrayfirmas(k).ByteInicial  
  12.            j= k
  13.        end if
  14.  
  15.        tblBusqueda(k) = j
  16.    next
  17.  
 

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
  1.    ' Cuando se genera el array de estructuras de firmas, debe calcularse este valor...
  2.    dim firmamaslarga as byte   ' cantidad de bytes que tiene la firma más larga que contiene el xml...
  3.    ' si este valor tuviera la posibilidad de ser mayor que byte, decláralo como short...
  4.    ' y hay otras partes en le código que deben  cambiarse también de tipo de forma consecuente.
  5.  
  6. private sub BuscarPatronEnFile(byref Ruta as string)
  7.   dim k as int32
  8.   dim pt as int32
  9.   dim fileOrg() as byte
  10.  
  11.   fileOrg = leerFichero(ruta) 'se omite esta parte y cualquier posible error de lectura, eso ya lo pones tú...  
  12.  
  13.    ' bucle principal de búsqueda una vez leído un fichero...
  14.    for k= 0 to fileOrg.length - firmamaslarga ' para evitar desbordamientos de bufer, ni el uso de 'try... que ralenticen la operación de forma innecesaria.
  15.         pt= tblBusqueda( fileOrg(k))
  16.         k += BuscarPatron(fileOrg, k , pt)      ' típicamente sumará 0 si no encontró patrón de virus....
  17.    next
  18. End sub


5 - La función que busca el patrón recorriendo dos arrays de bytes...
Código
  1.  
  2. ' declárese de tipo short si firmamaslarga  se declaró como short
  3. private function BuscarPatron(byref Origen() as byte, byval Index as int32, byval IxFirma as int32)  as byte
  4.    dim j as byte, i as byte ' short para ambos si firmamaslarga  se declaró como short
  5.    dim k as int32
  6.    dim f as int32 = IxFirma
  7.  
  8.    do
  9.        j = Arrayfirmas(ixFirma).Firma.Lenght
  10.        for i = 1 to j-1 ' el byte 0, nos trajo aquí, coincide, luego no requiere 're-visarlo'.
  11.            if (origen(index+i) <> Arrayfirmas(ixFirma).Firma(i) then exit for
  12.        next
  13.  
  14.        if (i=j) then  ' si se llegó hasta el final del array  implica que se encontró el patrón
  15.            ' Añadir patrón encontrado
  16.            listv.Items.Add(Arrayfirmas(ixFirma).Name)
  17.            Label1.Text = listv.Items.Count.ToString & " Virus"      
  18.  
  19.            ' en teoría al encontrar una firma en los siguientes 'j' bytes, si se encontró carece de sentido buscar un patrón un byte más allá del punto de inicio de un patrón hallado, por eso se sale y se avanza esos bytes en el fichero de origen.
  20.            Return j  ' -1? prueba...
  21.        end if
  22.  
  23.        ixFirma +=1
  24.    loop while (tblBusqueda(ixFirma).ByteInicial  = f)  ' esto es mientras la firma siguiente comience también por el mismo byte...
  25.  
  26.    ' ixFirma podría desbordar el array, pero como añadimos un ítem más al array, no será el caso
  27.    ' y la condición (solo una) del bucle es suficiente, para delimitar el fin de búsqueda.
  28.    ' Aquí es donde tiene sentido lo que se ponía más arriba...
  29.    'tblBusqueda(ArrayFirmas.lenght+1) = 0  añadir un índice más nos evitará desbordamientos   y chequeos para evitarlo. Solo precisaremos una condición para el bucle
  30.  
  31.    return 0
  32. end sub
  33.  

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
  1.    If x > UBound(ArrayHold) Then
  2.        tempStr = tempStr  ' A = A es perder el tiempo, imagina que hiciéramos lo mismo con cada variable... y cuántas veces lo tendríamos que hacer?... 0 veces está bien.
  3.    Else
  4.        '...
  5.    end if
  6.  

Mejor así:
Código
  1.    If x <= UBound(ArrayHold) Then
  2.        '...
  3.    'else  ' no cambia nada que actualmente no sea lo que es... luego no precisa código para "else".
  4.    end if
  5.  

--- 3 El siguiente código, también resulta un poco redundante...
Código
  1.        For Each signature As XElement In xml.Root.Elements
  2.            If InStr(1, Str.ToString, signature.<hex>.Value, vbTextCompare) Then
  3.                listv.Items.Add(signature.<name>.Value)
  4.                If listv.Items.Count > 0 Then
  5.                    Label1.Text = "Virus"
  6.                Else
  7.                    Label1.Text = "No Virus"
  8.                End If
  9.            End If
  10.        Next
  11.  

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
  1.        For Each signature As XElement In xml.Root.Elements
  2.            If InStr(1, Str.ToString, signature.<hex>.Value, vbTextCompare) Then
  3.                listv.Items.Add(signature.<name>.Value)                
  4.            End If
  5.        Next
  6.  
  7.        If listv.Items.Count > 0 Then
  8.            Label1.Text = "Virus"
  9.        Else
  10.            Label1.Text = "No Virus"
  11.        End If
  12.  

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
  1.        Label1.Text = "No Virus"
  2.        For Each signature As XElement In xml.Root.Elements
  3.            If InStr(1, Str.ToString, signature.<hex>.Value, vbTextCompare) Then
  4.                listv.Items.Add(signature.<name>.Value)
  5.                Label1.Text = listv.Items.Count.ToString & " Virus"                                
  6.            End If
  7.        Next
  8.  



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...


« Última modificación: 5 Agosto 2018, 17:34 por NEBIRE » En línea

**Aincrad**


Desconectado Desconectado

Mensajes: 506



Ver Perfil
Re: Ayuda con Scaneer Hexadecimal
« Respuesta #2 en: 5 Agosto 2018, 00:20 »

Gracias! lo probare!  :D
En línea


Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
AYUDA (editor hexadecimal)
Ingeniería Inversa
imperio 2 1,898 Último mensaje 4 Enero 2008, 18:37
por karmany
ayuda con hexadecimal
Software
nevirus 3 1,167 Último mensaje 27 Junio 2011, 12:49
por APOKLIPTICO
MOVIDO: ayuda con hexadecimal
Criptografía
APOKLIPTICO 0 1,766 Último mensaje 27 Junio 2011, 12:49
por APOKLIPTICO
[AYUDA][PYTHON] Leer y guardar archivos .exe de forma hexadecimal en python???
Scripting
Noxware 3 3,085 Último mensaje 22 Agosto 2014, 09:33
por Eleкtro
[PYTHON][AYUDA] Tutorial 3.x y modificar offsets (hexadecimal) ?
Scripting
PedroDJavier 4 2,039 Último mensaje 28 Noviembre 2014, 17:49
por PedroDJavier
Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines