Devolver / transformar y luego devolver patrón con valores nulos

0

Estoy usando grep / sed para analizar un gran archivo binario lleno de nulos para algunos datos específicos. Esto está en un entorno de Windows usando gnuwin32.

Suponiendo que tuviera que devolver algunos datos de un archivo binario que se parecía a esto (representación hexadecimal):

42 9D E1 0A 01 FF FF FF FF FF FF FF 7F 00 FE FF FF 0A 01 E1 0A 01 C0 0B 00 4D 00
00 9C E1 0A 01 2C 41 38 B4 15 FB 49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00
32 00 33 00 2E 00 73 00 75 00 62 00 2E 00 64 00 6F 00 6D 00 61 00 69 00 6E 00 2E
00 73 00 74 00 61 00 2E 00 6F 00 72 00 67 00 2E 00 61 00 75

Pero solo coincide con esta parte de lo anterior:

49 00 4D 00 41 00 48 00 4F 00 53 00 54 00 31 00 32 00 33

¿Cómo lo haría exactamente usando grep y / o sed? La presencia de nulos hace algunas cosas malas, especialmente porque realmente necesito devolver los datos como parte de un analizador de archivos automatizado.

El siguiente grep se acerca a hacer lo que quiero:

grep -Prino ".{0,100}I\000M\000A\000H\000O\000S\000T\0001\0002\0003.{0,100}" "d:\dhcp.mdb"

Sin embargo, solo devuelve "coincidencias de archivo binario d: \ dhcp.mdb" en lugar del patrón coincidente, probablemente debido a los valores nulos. Si esto funcionara, una vez que tuviera 100 caracteres a cada lado, elegiría este subconjunto para lo que necesitaba al hacer coincidir también la dirección IP (que sigue un formato greppable) y el nombre de dominio (que siempre termina con 3 nulos)

Como es un archivo de base de datos, probablemente podría usar un método diferente, como interactuar realmente con la base de datos, pero creo que estoy bastante cerca de este método.

Al usar Sed, puedo ver datos de retorno de un archivo mucho más pequeño donde he pegado algunos de los datos relevantes:

sed -rn "/\I\x00M\x00A\x00H\x00O\x00S\x00T\x001\x002\x003/p" "D:\cruft\Hxma.txt"

Pero no estoy seguro de cómo devolver 100 caracteres antes y 100 caracteres después del partido, como en el grep anterior, y cuando lo ejecuto contra el archivo de base de datos de 12MB no devuelve nada (quitando la opción silenciosa para que imprima el el espacio de patrón muestra que obtiene ~ 10KB y luego aparentemente se da por vencido)

¿Alguien sabe cómo puedo proceder para resolver esto? Debo agregar que el formato real de los datos devueltos no es demasiado importante siempre que no se pierdan datos (aparte de los nulos, no los necesito en absoluto).

Si ayuda, el formato real de los datos de texto que quiero hacer coincidir parece ser unicode de 2 bytes, aunque algunos de los datos que necesito devolver junto con la coincidencia (es decir, los primeros 4 bytes que son una IP poco endian dirección) no está en unicode.

Bruno
fuente

Respuestas:

0

Le estás diciendo a grep qué buscar. El concepto de que no sabes lo que acabas de decirle a grep que busque es extraño y no lo sigo. El propósito de grep es buscar un patrón que le des; no para encontrar una cadena de la que ya conoces la ubicación. Creo que necesitas definir más claramente qué pieza de este rompecabezas te estás perdiendo.

Además, la mayoría de las bases de datos tienen herramientas de línea de comandos. Aunque MS no es una buena herramienta para sus bases de datos, hay un paquete llamado herramientas MDB que le permitirá utilizar SQL para buscar en la base de datos. Esta es seguramente una mejor manera de lograr lo que está tratando de hacer aquí.

Por último, si realmente quisiera buscar en un binario cadenas con grep, sugiero que use la herramienta de cadenas en el paquete binutils . Esto filtrará los caracteres no imprimibles antes de buscar los datos. También puede imprimir compensaciones prácticas (que es lo que normalmente desea en esta situación). Aquí hay una muestra de cómo se vería (esto buscará en el binario grep cualquier cadena que contenga la palabra 'obsoleto'):

strings -a -t x /bin/grep|grep deprecated

Como puede ver, esto será mucho menos propenso a errores. No he comprobado la velocidad de esto, pero estoy seguro de que dependerá mucho del contenido binario real de todos modos.

Actualizar

Acabo de darme cuenta de que estás trabajando en Windows. Systernals crea una versión de string.exe que es bastante similar al programa de cadenas de Linux.

strings.exe -a -o C:\GnuWin\bin\grep.exe|grep deprecated

Además, puede probar Jackcess para una herramienta MDB de línea de comandos que funcionará con cualquier sistema operativo compatible con JVM.

krowe
fuente
Solo para aclarar, no sé la ubicación de la cadena antes de comenzar, pero una vez que tengo la ubicación de la cadena, sé dónde están otros datos relevantes en relación con esa cadena. Así que coincido con un nombre de host en el archivo, luego obtengo una IP que aparece varios bytes antes del nombre de host y un nombre de dominio que aparece directamente después del nombre de host. Dicho esto, buscaré las herramientas MDB o el método binutils por ahora; si binutils me puede dar un índice, espero poder extraer caracteres no imprimibles alrededor de ese índice (en caso de que haya una IP como 10.225.157.0 que comenzaría con un valor nulo: 009DE10A)
Bruno
En línea con su actualización, lo anterior debería leer "perseguiré el Jackcess o el método de cadenas, ojalá la cadena pueda tirarse alrededor de no imprimible en caso de octeto = 0 en IP", etc.
Bruno