Strings: cómo extraer texto de archivos binarios en Windows

Última actualización: octubre 4, 2025
  • Empieza con strings (Sysinternals/GNU), FLOSS y filtros de codificación para descubrir texto útil.
  • Apóyate en PowerShell: Get-Content en bytes, Select-String, ADS y Get-AuthenticodeSignature.
  • Profundiza con pev/peframe, ssdeep, imphash y entropía para detectar packers u ofuscación.
  • Certutil, PEStudio y utilidades de esteganografía completan una triage rápida y fiable.

extraer cadenas de binarios en windows

Cuando abrimos un ejecutable de Windows por primera vez puede parecer un barullo de bytes, pero a menudo hay texto en claro esperando a ser descubierto: rutas, mensajes de error, nombres de DLL, manifiestos XML y más. Extraer esas cadenas rápido nos da contexto del binario sin tener que desensamblar ni ejecutar.

En esta guía práctica vas a ver cómo extraer cadenas en Windows y Linux con strings.exe y su homólogo GNU, cómo apoyarte en PowerShell (incluidos flujos NTFS), qué metadatos y firmas revisar, y qué hacer si el texto está ofuscado o camuflado con esteganografía. Además, integraremos técnicas de análisis PE (pev, peframe, ssdeep, imphash, entropía) y, como bonus, un compendio de trucos de manipulación de strings (incluido un apéndice con Julia) para procesar lo extraído con solvencia.

Qué son las cadenas en binarios y por qué importan

Una cadena es una secuencia de bytes interpretada con una codificación (ASCII, UTF‑8, UTF‑16/Unicode, etc.). En ficheros PE de Windows aparecen por todas partes: funciones importadas, mensajes, rutas, manifiestos XML, identificadores de certificados, e incluso el clásico «This program cannot be run in DOS mode». Saber leerlas te cuenta qué hace el programa y a qué llama.

Cadenas como LoadLibrary, GetProcAddress o IsDebuggerPresent sugieren carga dinámica de módulos y anti‑debug. Referencias a VeriSign/OCSP/CRL apuntan a firma digital. Aunque hay ruido y falsos positivos, una criba crítica da señales muy valiosas en triage.

Flujo de trabajo recomendado para no perder tiempo

Empieza siempre en estático: es rápido, seguro y clasificatorio. Calcula hashes (SHA‑256), identifica tipo/arquitectura (PE32/PE32+), aísla en VM y verifica que la muestra es idéntica entre entornos con el hash.

Confirmado que es PE, toca rascar strings. Si hay poco texto, intenta FLOSS para cadenas construidas en runtime. Complementa con PEStudio y ExifTool para metadata y con certutil para blobs Base64/hex, ASN.1 y hashes. PowerShell te servirá para leer como bytes y explorar Alternate Data Streams (ADS) en NTFS.

Windows: strings.exe, FLOSS y aliados

El camino corto es strings.exe de Sysinternals. Recorre el archivo y vuelca secuencias legibles. Úsalo como base y filtra la salida.

Ejemplo básico:

strings.exe binario.exe > cadenas.txt

Esperarás desde el stub DOS hasta listas de DLL importadas, manifiestos XML e indicios de PKI. El objetivo es separar grano de paja (mensajes propios, rutas/dominos, variables relevantes, endpoints de red o claves de configuración).

Si sospechas ofuscación o empaquetado, prueba FLOSS (FLARE/FireEye) para descubrir cadenas decodificadas en ejecución que strings.exe no puede ver. PEStudio te da importaciones, secciones, recursos, firma y entropía con un clic; ExifTool es comodín para metadatos.

Linux/WSL: comando strings y trucos útiles

En Linux (o WSL) tira del strings de GNU. Es rápido y flexible, ideal para primeras cribas en lotes de ficheros.

strings ejemplo.bin
strings -n 10 ejemplo.bin         # ignora cadenas cortas
strings -t x archivo.bin          # offsets en hex
strings archivo1.bin archivo2.bin | head -n 100
strings -e S archivo_win.bin      # fuerza UTF-16LE

Combinado con grep/awk puedes buscar patrones (URLs, rutas, extensiones, YARA-like). El ahorro de tiempo es brutal para clasificar muestras.

  ¿Qué es mejor un punto de equilibrio alto o bajo?

PowerShell para texto, bytes y Alternate Data Streams

PowerShell sirve para inspeccionar como texto o como bytes y ver flujos alternativos NTFS. Para archivos de texto grandes:

# Lectura línea a línea
Get-Content -Path .\archivo.txt
# Todo el contenido en una sola cadena
Get-Content -Path .\archivo.txt -Raw
# Cola de logs
Get-Content .\archivo.txt -Tail 1

Si es binario, usa -AsByteStream + -Raw para obtener [byte[]]:

$bytes = Get-Content -Path .\binario.exe -AsByteStream -Raw
$bytes.Length

Para ADS en NTFS, lista y lee streams ocultos:

Get-Item -Path .\sospechoso.txt -Stream *
Get-Content -Path .\sospechoso.txt -Stream ':$DATA'
Get-Content -Path .\sospechoso.txt -Stream 'NewStream'

Usa -LiteralPath si hay caracteres especiales, y -Filter/Include/Exclude para afinar lotes. Te quita mucho trabajo repetitivo.

Firmas digitales, certutil y metadatos

Ver nombres de CA, URLs de CRL/OCSP o manifiestos sugiere que el binario puede estar firmado. Confirma con propiedades del archivo o con PowerShell:

Get-AuthenticodeSignature .\binario.exe

certutil es una navaja suiza para certificados y blobs:

certutil -hashfile binario.exe SHA256     # hash rápido
certutil -decode in.txt out.bin           # Base64 -> binario
certutil -decodehex in.hex out.bin       # Hex -> binario
certutil -asn firma.der                   # Estructura ASN.1

Que aparezcan referencias a certificados no garantiza validez de la firma; caducadas o revocadas harán que Windows no confíe. Esa discrepancia es indicio a considerar.

Esteganografía y texto que no se ve

No todo lo oculto está en PE: hay mensajes en documentos, imágenes o audio. En texto plano, ojo a espacios/tabs finales, caracteres invisibles Unicode y homoglifos. ZWSP-Tool detecta/limpia Zero-Width.

git clone https://github.com/TwistAtom/ZWSP-Tool.git
cd ZWSP-Tool && chmod +x install.sh && ./install.sh
zwsp-tool detect -P file.txt
zwsp-tool clean -P file.txt

En audio e imagen, mira espectrogramas, metadatos y LSB. Con binwalk detectas archivos pegados al final. stegseek/steghide ayudan con contraseñas; para análisis rápido, stegsolve/stegonline.

Más allá de strings: empaquetado, ofuscación y entropía

Si no sale nada útil, puede haber packers u ofuscación (UPX, XOR, cifrado simple). FLOSS ayuda con cadenas dinámicas y la entropía por secciones en PE delata compresión/cifrado. PEStudio y pev facilitan ver secciones sospechosas.

Análisis estático en Linux con pev y peframe

Para .bin/.exe en Linux, confirma tipo y arquitectura con xxd y file; 4D 5A indica ejecutable PE (MZ).

xxd -g 1 Folio-854500047700.bin | more
file Folio-854500047700.bin
file Folio-854500047700.bin --mime-type

Calcula hashes (md5sum, sha1sum, sha256sum) y usa pev para análisis PE:

sudo apt install pev
pehash Folio-854500047700.bin     # MD5, SHA1, SHA256, ssdeep, imphash

ssdeep compara similitud por fuzzy hashing y imphash (Mandiant) clasifica por IAT. Con strings extrae texto; para Unicode en Windows usa -el:

strings Folio-854500047700.bin
strings -el Folio-854500047700.bin | grep -E ".exe" --color

Identifica packers con pepack y revisa otras propiedades con pescan (entropía, timestamp, anti‑debug) y pesec (DEP/NX, ASLR):

pepack Folio-854500047700.bin -d userdb.txt
pescan -v Folio-854500047700.bin
pesec Folio-854500047700.bin

Para un informe más rico, peframe (Python) detecta packers, mutex, APIs, criptografía y soporta integración con VirusTotal.

sudo apt install git python3-pip libssl-dev swig
git clone https://github.com/guelfoweb/peframe.git
cd peframe && sudo python3 setup.py install
peframe Folio-854500047700.bin

PowerShell Select-String: buscar en texto y binarios

Select-String es el grep de PowerShell para buscar patrones (regex o texto simple) en archivos, cadenas u objetos. Devolverá MatchInfo con archivo, línea, número de línea, y puede mostrar contexto o solo booleanos.

  ¿Cuánto ruido son 45 decibelios?

Parámetros clave: -Pattern (regex o con -SimpleMatch), -Path/-LiteralPath, -InputObject, -Encoding (ascii, oem, unicode/UTF‑16 LE, utf8/utf8BOM/utf8NoBOM, utf32, big endian UTF‑16/UTF‑32, ansi), -CaseSensitive, -AllMatches, -Context (antes,después), -NotMatch, -Include/-Exclude, -List, -Quiet (True/False), -Raw (solo coincidencias), -Culture (CurrentCulture/Ordinal/Invariable).

Alias y notas: sls es el alias; FileInfo se trata como ruta y se busca en el contenido; a menudo conviene canalizar por Out-String si necesitas formateo previo. Es muy versátil.

# Búsqueda sensible a mayúsculas y simple
'Hello','HELLO' | Select-String -Pattern 'HELLO' -CaseSensitive -SimpleMatch

# En todos los .txt del directorio
Select-String -Path .\*.txt -Pattern 'Get-'

# Contexto 2 antes, 3 después
Select-String -Path .\Command.txt -Pattern 'Get-Computer' -Context 2,3

# Todas las coincidencias en cada línea
Select-String -Path "$PSHOME\en-US\*.txt" -Pattern 'PowerShell' -AllMatches

Extraer XML incrustado en un EXE (Unicode) con PowerShell

Si el EXE contiene XML en UTF‑16LE (Unicode), hay que leer como bytes y decodificar en LE para que aparezcan los delimitadores. Después se busca el bloque XML:

$bytes = Get-Content .\app.exe -AsByteStream -Raw
$text  = [System.Text.Encoding]::Unicode.GetString($bytes)
$match = [regex]::Match($text, "(?s)<\?xml.*?</[^>]+>")
if ($match.Success) {
  $xml = $match.Value
  [xml]$doc = $xml
  $doc.DocumentElement.Name
}

Si el XML está fragmentado o hay varios, usa RegexOptions.Singleline (con (?s)) y recorre EachMatch. Evita Select-String directo sobre bytes UTF‑16 sin decodificar, porque verás caracteres nulos intercalados.

Conversión entre cadenas y binario en UWP (C#)

En apps UWP puedes convertir strings a binario con CryptographicBuffer y elegir codificación (UTF16BE/LE, UTF8). Ejemplo de referencia:

public void ConvertData(){
  // Create a string to convert.
  String strIn = "Input String";
  // Convert to UTF16BE
  IBuffer buffUTF16BE = CryptographicBuffer.ConvertStringToBinary(strIn, BinaryStringEncoding.Utf16BE);
  // Convert to UTF16LE
  IBuffer buffUTF16LE = CryptographicBuffer.ConvertStringToBinary(strIn, BinaryStringEncoding.Utf16LE);
  // Convert to UTF8
  IBuffer buffUTF8    = CryptographicBuffer.ConvertStringToBinary(strIn, BinaryStringEncoding.Utf8);
}

Esto te ayuda a detectar la codificación correcta cuando inspeccionas recursos incrustados o construyes pruebas controladas.

Leer binarios y extraer campos (x, y, z) con Python

Si conoces el layout (por ejemplo cabecera «INICIAN PARÁMETROS», seguido de id, x, y, z, lado, superficie…), puedes buscar las cadenas delimitadoras y luego parsear con struct o con regex si el bloque textual está en claro.

import re
from pathlib import Path

p = Path('archivo.bin').read_bytes()
# Prueba decodificar como UTF-8 y, si falla o salen NUL, usar UTF-16LE
try:
    t = p.decode('utf-8', errors='ignore')
except:
    t = p.decode('utf-16le', errors='ignore')

m = re.search(r'INICIAN PAR[ÁA]METROS.*?FINALIZAN PAR[ÁA]METROS', t, re.S)
if m:
    bloque = m.group(0)
    # Extrae x, y, z como floats (adaptar a tu formato real)
    nums = re.findall(r'\b-?\d+(?:\.\d+)?\b', bloque)
    # Heurística: id, x, y, z, lado, idsup...
    if len(nums) >= 4:
        _id, x, y, z = nums[0], float(nums[1]), float(nums[2]), float(nums[3])
        print(x, y, z)

Si no hay texto en claro, y el formato es binario estructurado, usa struct.unpack con el endian y tipos correctos (ej.: <i f f f …). Si has convertido a CSV con una herramienta, ya puedes cargar con csv/ pandas y trabajar a nivel de columnas.

Trabajar con cadenas: guía exprés y apéndice de Julia

Tras extraer texto, necesitarás manipularlo: concatenar, dividir, normalizar mayúsculas, buscar/ sustituir y leer/escribir a disco. A modo de apunte ex profeso, Julia ofrece una caja de herramientas muy completa que ilustra bien los conceptos.

Creación/transformación: string(x) devuelve la representación canónica; parse(T, «…») hace lo inverso; repr conserva el formato mostrado; @sprintf controla el formateo; concatenas con * o repeat/^; join/split unen y separan; variantes para rutas joinpath/splitdir/splitext/splitdrive.

string(3000, base=2)        # "101110111000"
string(1, pad=3)            # "001"
parse(Int, "30", base=16) # 48

Mayúsculas/minúsculas y espacios: uppercase/lowercase/titlecase, y chomp/chop/strip/lstrip/rstrip, lpad/rpad para alinear. Súper útil al limpiar dumps de strings.

uppercase("hola")           # "HOLA"
strip("  texto  ")          # "texto"
lpad("id", 5)              # "   id"

Indexado y Unicode: en UTF‑8, length cuenta caracteres y ncodeunits unidades de código; con acentos no siempre coinciden. Usa eachindex, nextind/prevind/lastindex y isvalid para índices correctos cuando recortes por posiciones. Es clave si recortas offsets devueltos por GNU strings.

texto = "código"
length(texto)       # 6
ncodeunits(texto)   # 7
# Tercera letra con nextind
texto[1:nextind(texto, 0, 3)]  # "cód"

Búsqueda y reemplazo con regex: findfirst/findlast/findnext/findprev, occursin/startswith/endswith y replace. Capturas con match/eachmatch; sustituciones con s»…» y backrefs (\1 o \g<nombre>). Fundamental para localizar URLs, rutas o pares clave‑valor.

m = match(r"#(\d+)#", "ABC #123#")
# replace con captura
replace("Hola, don Pepito. Adiós, don José", r"(Hola|Adiós)" => s"¡\1!")

Lectura/escritura de texto: read/readlines, open/close con bloque do, y formateo con print/println/@printf. Maneja errores con try/finally para cerrar archivos; flush si necesitas forzar buffer. Buenas prácticas al procesar lotes grandes.

open("archivo.txt", "w") do io
  @printf(io, "Hash: %s\n", "...")
end

Secuencias de escape y raw strings: escape_string/unescape_string y el prefijo raw evitan pelearte con backslashes o el símbolo $. Útil para rutas Windows y regex complejas.

  ¿Cuáles son las palabras que le gustan a Natsuki?

Casos prácticos frecuentes

Extraer manifiesto XML incrustado en EXE: decodifica en Unicode LE, busca con regex y parsea con [xml] en PowerShell. Si hay varios bloques, recógelos con [regex]::Matches.

Detectar endpoints/URLs: usa GNU strings/strings.exe, filtra con grep/Select-String patrones de http(s):// y valida con regex robustas. Muy directo para IOC.

Desofuscar cadenas ligeras: FLOSS identifica rutinas de decodificación simple; si ves XOR constante, saca la key por frecuencia y aplica al blob; certutil -decode ayuda con Base64; -decodehex para hex.

Identificar empaquetado: picos de entropía y secciones con nombres sospechosos; pepack con bases de firmas facilita la detección; si es UPX, intenta desempaquetar y repite extracción de strings.

Checklist operativo (rápido y efectivo)

1) Identificación del archivo (xxd, file), 2) Hashes (sha256sum/certutil), 3) strings (Sysinternals y GNU, con filtro de longitud y encoding), 4) FLOSS si sospechas runtime, 5) Metadatos (PEStudio, ExifTool) y firma (Get-AuthenticodeSignature), 6) certutil para blobs y ASN.1, 7) ADS con PowerShell, 8) pev/peframe para señales fuertes (imphash, ssdeep, entropía, APIs, packers).

Con este flujo tendrás en minutos una visión clara de lo visible, lo ofuscado, qué metadatos cuadran y qué pistas seguir con sandbox o depuración si hace falta.

Notas finales sobre CSV y datos estructurados

Si el binario original no se deja abrir y has logrado convertir a CSV, ya puedes analizar x, y, z con Python/pandas o PowerShell (Import-Csv). Valida encoding (UTF‑8/UTF‑16) para evitar caracteres fantasma y normaliza separadores según región.

Dominar la extracción de cadenas y señales colaterales te permite clasificar binarios, descubrir configuración y encontrar IOCs sin tocar un depurador. Combinando strings, PowerShell, certutil y el ecosistema de análisis PE en Linux tendrás una ruta de trabajo sólida y repetible, con margen para casos duros gracias a FLOSS, herramientas de estego y lectura de ADS.