Linux Command Reference

strings

Synopsis

strings [OPTION]... [FILE]... strings -n MIN_LENGTH [FILE] strings -a [FILE] strings -t {d|o|x} [FILE]

Description

The strings command extracts printable character sequences (strings) from binary files. By default, it finds sequences of at least 4 printable ASCII characters terminated by a non-printable character. This seemingly simple utility is invaluable for examining compiled programs, libraries, firmware images, memory dumps, and any binary data that might contain embedded text.

Strings is a fundamental tool in security analysis, reverse engineering, malware investigation, forensics, and data recovery. It can reveal hardcoded passwords, API keys, URLs, error messages, debug strings, copyright notices, and other textual artifacts embedded in binary files. While strings doesn't execute or disassemble code, it provides quick insight into what a binary might do or contain. Modern forensics, incident response, and security research would be significantly more difficult without this essential utility. The command works on executables, libraries, core dumps, disk images, memory captures, and any file containing binary data mixed with text.

Key Concepts

Detailed Examples

Example 1

Basic String Extraction from Binaries

Extract readable strings from compiled executables to discover hardcoded text, error messages, function names, and other embedded information. This is the most common use case.
# Extract strings from a binary strings /bin/ls # Extract strings from a library strings /lib/x86_64-linux-gnu/libc.so.6 # Show strings with minimum length of 8 strings -n 8 /bin/bash # Extract strings from multiple files strings /usr/bin/* | head -50 # Count strings in a binary strings /bin/ls | wc -l # Find specific patterns strings /bin/ls | grep -i color # Look for URLs strings application.bin | grep -E 'https?://' # Find potential API keys (example pattern) strings app.exe | grep -E '[A-Za-z0-9]{32,}' # Extract and sort unique strings strings program.bin | sort -u # Look for version information strings /usr/bin/gcc | grep -i version # Find error messages strings application | grep -i error # Search for file paths strings binary | grep '^/' # Look for email addresses strings app | grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' # Practical: quick binary analysis echo "=== Binary Analysis: /bin/ls ===" echo "Total strings: $(strings /bin/ls | wc -l)" echo "Long strings (>20 chars): $(strings -n 20 /bin/ls | wc -l)" echo "" echo "Interesting strings:" strings /bin/ls | grep -E '(error|warning|invalid|failed|permission)' | head -5
Output:
# From /bin/ls: /lib64/ld-linux-x86-64.so.2 libc.so.6 stdout error invalid option cannot access Permission denied --color --time-style GNU coreutils # Binary analysis output: === Binary Analysis: /bin/ls === Total strings: 847 Long strings (>20 chars): 142 Interesting strings: cannot access %s: %s error reading directory invalid argument Permission denied invalid option
Note:

Default minimum length is 4 characters. Increase with -n to reduce noise. Common patterns: URLs (http://), paths (/usr/, C:\), error messages, version strings. strings reveals what text is embedded in binaries without executing them - safe for malware analysis.

Example 2

Displaying Offsets

Show byte offsets where strings are found using -t option. Essential for forensics, debugging, and understanding file structure. Helps locate specific strings in large files.
# Show decimal offsets strings -t d /bin/ls | head -10 # Show hexadecimal offsets (most common) strings -t x /bin/ls | head -10 # Show octal offsets strings -t o /bin/ls | head -10 # Combine with longer minimum length strings -n 10 -t x /bin/bash | head -20 # Find specific string and show offset strings -t x /bin/ls | grep "color" # Show offsets for potential secrets strings -t x application.bin | grep -i password # Locate version string strings -t x /usr/bin/gcc | grep -i "gcc version" # Export with offsets for analysis strings -t x suspicious.exe > strings_with_offsets.txt # Find string at specific offset (reverse lookup) # If we know offset 0x1234, verify what's there strings -t x binary | grep "^1234" # Compare string locations between files diff <(strings -t x file1.bin) <(strings -t x file2.bin) # Practical: forensic analysis cat > analyze_binary.sh << 'EOF' #!/bin/bash BINARY="$1" echo "String Location Analysis: $BINARY" echo "==================================" echo "" echo "High-offset strings (likely in data section):" strings -t x "$BINARY" | awk '$1 > "10000"' | head -10 echo "" echo "Low-offset strings (likely in header/code):" strings -t x "$BINARY" | awk '$1 < "1000"' | head -10 echo "" echo "Suspicious patterns with locations:" strings -t x "$BINARY" | grep -iE '(password|secret|key|token|api)' | head -10 EOF chmod +x analyze_binary.sh ./analyze_binary.sh /bin/ls
Output:
# Decimal offsets (-t d): 792 /lib64/ld-linux-x86-64.so.2 1024 GNU 1536 libc.so.6 2048 stdout # Hexadecimal offsets (-t x): 318 /lib64/ld-linux-x86-64.so.2 400 GNU 600 libc.so.6 800 stdout a20 --color b40 --time-style # Finding specific string: a20 --color a28 --color=auto # Analysis output: String Location Analysis: /bin/ls ================================== High-offset strings (likely in data section): 14a20 cannot access %s 14b30 error reading %s 15040 invalid option Low-offset strings (likely in header/code): 318 /lib64/ld-linux-x86-64.so.2 400 GNU 600 libc.so.6
Note:

The -t flag shows offsets: d=decimal, x=hexadecimal, o=octal. Hexadecimal is most common for binary analysis. Offsets help locate strings in hex editors or disassemblers. Low offsets often contain headers/metadata, high offsets contain data. Use offsets to correlate strings with specific file sections.

Example 3

Scanning Entire File vs Data Sections

By default, strings only scans initialized data sections of object files. Use -a to scan the entire file including code sections, headers, and uninitialized areas.
# Default: scan only data sections strings /bin/ls | wc -l # Scan entire file with -a strings -a /bin/ls | wc -l # Compare the difference echo "Data sections only: $(strings /bin/ls | wc -l)" echo "Entire file: $(strings -a /bin/ls | wc -l)" # Scan entire binary file strings -a suspicious.bin > all_strings.txt # Find strings only in code sections (entire file minus data sections) comm -13 \ <(strings /bin/bash | sort) \ <(strings -a /bin/bash | sort) \ > code_section_strings.txt # Scan disk image or memory dump (always use -a) strings -a disk.img | grep -i password # Scan partition strings -a /dev/sda1 | grep -E 'filename|document' | head -20 # Data recovery from corrupted file strings -a corrupted_file.doc | grep -A 5 -B 5 "important data" # Memory dump analysis strings -a memory_dump.raw | grep -i "malware" # Scan entire core dump strings -a core.12345 > core_strings.txt # Compare scanning methods cat > compare_scan.sh << 'EOF' #!/bin/bash FILE="$1" echo "Scan Comparison: $FILE" echo "====================" DATA_COUNT=$(strings "$FILE" | wc -l) FULL_COUNT=$(strings -a "$FILE" | wc -l) DIFF=$((FULL_COUNT - DATA_COUNT)) echo "Data sections only: $DATA_COUNT strings" echo "Entire file: $FULL_COUNT strings" echo "Additional in code sections: $DIFF strings" echo "" echo "Sample strings only in code sections:" comm -13 \ <(strings "$FILE" | sort | head -100) \ <(strings -a "$FILE" | sort | head -100) \ | head -5 EOF chmod +x compare_scan.sh ./compare_scan.sh /bin/ls # Clean up rm -f compare_scan.sh code_section_strings.txt
Output:
# Default vs -a comparison: Data sections only: 847 Entire file: 1523 # Detailed comparison: Scan Comparison: /bin/ls ==================== Data sections only: 847 strings Entire file: 1523 strings Additional in code sections: 676 strings Sample strings only in code sections: __cxa_finalize __errno_location __fprintf_chk __libc_start_main __stack_chk_fail # From disk image: important_document.pdf mypassword123 confidential_report.docx backup_2025.tar.gz # Memory dump: malware.exe C:\Windows\Temp\ http://malicious-site.com/ Process injection detected
Note:

Default strings scans only initialized data sections (.data, .rodata) of object files. The -a flag scans the entire file including code (.text), headers, and all sections. Always use -a for: disk images, memory dumps, unknown file types, data recovery, and forensic analysis. ELF/PE aware vs raw scanning.

Example 4

Encoding and Character Set Options

Extract strings in different encodings including ASCII, UTF-16 (common in Windows binaries), and other character sets. Essential for analyzing cross-platform binaries.
# Default: 7-bit ASCII strings program.exe # Include 8-bit characters (extended ASCII) strings -e S program.exe # UTF-16 little-endian (Windows binaries) strings -e l program.exe # UTF-16 big-endian strings -e b program.exe # Extract all encoding types strings -e s program.exe # 7-bit strings -e S program.exe # 8-bit strings -e l program.exe # UTF-16 LE strings -e b program.exe # UTF-16 BE # Combine all encodings { strings -e s program.exe strings -e S program.exe strings -e l program.exe strings -e b program.exe } | sort -u > all_strings.txt # Windows executable analysis (UTF-16 common) strings -e l windows_app.exe | grep -i error # Look for Unicode strings strings -e l app.dll | head -20 # Mixed encoding analysis cat > extract_all_encodings.sh << 'EOF' #!/bin/bash FILE="$1" echo "Encoding Analysis: $FILE" echo "========================" echo "" echo "ASCII (7-bit) strings:" strings -e s "$FILE" | wc -l echo "Extended ASCII (8-bit) strings:" strings -e S "$FILE" | wc -l echo "UTF-16 LE strings:" strings -e l "$FILE" | wc -l echo "UTF-16 BE strings:" strings -e b "$FILE" | wc -l echo "" echo "Sample UTF-16 LE strings:" strings -e l "$FILE" | head -10 EOF chmod +x extract_all_encodings.sh # Analyze Windows PE file ./extract_all_encodings.sh windows_program.exe # Find Unicode URLs strings -e l app.dll | grep -E 'https?://' # Extract localized strings (often UTF-16) strings -e l localized_app.exe | \ grep -E '[\x80-\xFF]' | \ head -20 # Compare ASCII vs UTF-16 content echo "ASCII unique strings:" strings -e s binary | sort -u | wc -l echo "UTF-16 LE unique strings:" strings -e l binary | sort -u | wc -l # Clean up rm -f extract_all_encodings.sh all_strings.txt
Output:
# Encoding options: -e s : 7-bit ASCII (default for most Unix tools) -e S : 8-bit extended ASCII -e l : UTF-16 little-endian (Windows) -e b : UTF-16 big-endian # Windows executable analysis: Encoding Analysis: windows_program.exe ======================== ASCII (7-bit) strings: 234 Extended ASCII (8-bit) strings: 267 UTF-16 LE strings: 1847 UTF-16 BE strings: 12 Sample UTF-16 LE strings: Microsoft Corporation Windows Error Reporting Error accessing file Invalid parameter File not found Access denied System.dll kernel32.dll # UTF-16 LE URLs from DLL: http://www.microsoft.com/ https://update.windows.com/ https://login.live.com/
Note:

Windows binaries typically use UTF-16 LE (-e l). Unix/Linux binaries use ASCII (-e s/S). Use -e l for .exe, .dll files. Combine multiple encodings to catch all strings. UTF-16 doubles the minimum length needed (8 bytes = 4 characters). Always check UTF-16 when analyzing Windows malware or applications.

Example 5

Security Analysis and Malware Investigation

Use strings for initial security analysis of unknown binaries, looking for suspicious patterns, network indicators, file operations, and potential malicious behavior.
# Quick triage of suspicious binary cat > security_triage.sh << 'EOF' #!/bin/bash BINARY="$1" echo "=========================================" echo "Security Triage: $(basename "$BINARY")" echo "=========================================" echo "" echo "=== Network Indicators ===" echo "IP addresses:" strings -a "$BINARY" | \ grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' | \ sort -u | head -10 echo "" echo "URLs:" strings -a "$BINARY" | \ grep -oE 'https?://[a-zA-Z0-9./?=_%:-]*' | \ head -10 echo "" echo "Domain names:" strings -a "$BINARY" | \ grep -oE '[a-zA-Z0-9.-]+\.(com|net|org|edu|gov)' | \ sort -u | head -10 echo "" echo "=== File Operations ===" strings -a "$BINARY" | \ grep -iE '(CreateFile|OpenFile|WriteFile|DeleteFile|CopyFile)' | \ head -5 echo "" echo "=== Registry Operations (Windows) ===" strings -a "$BINARY" | \ grep -iE '(RegOpenKey|RegSetValue|RegDeleteKey|HKEY_)' | \ head -5 echo "" echo "=== Process Operations ===" strings -a "$BINARY" | \ grep -iE '(CreateProcess|OpenProcess|TerminateProcess|inject)' | \ head -5 echo "" echo "=== Suspicious Keywords ===" strings -a "$BINARY" | \ grep -iE '(password|admin|root|exploit|payload|shell|cmd\.exe)' | \ head -10 echo "" echo "=== Crypto/Encoding ===" strings -a "$BINARY" | \ grep -iE '(base64|encrypt|decrypt|crypto|cipher|AES|RSA)' | \ head -5 echo "" echo "=== User Agents ===" strings -a "$BINARY" | \ grep -i "User-Agent:" | head -3 EOF chmod +x security_triage.sh # Run triage on binary ./security_triage.sh suspicious.exe # Look for hardcoded credentials strings -a app.exe | grep -iE '(password|passwd|pwd).{0,20}[:=]' # Find potential C2 (Command & Control) servers strings -a malware.bin | \ grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+' | \ sort -u # Extract Windows API calls strings -a suspicious.dll | \ grep -E '^[A-Z][a-z]+[A-Z][a-zA-Z]*$' | \ sort -u | \ head -20 # Find file paths (potential targets) echo "=== Potential Target Files ===" strings -a ransomware.exe | grep -E '\.(doc|pdf|jpg|xlsx|ppt)' | head -10 # Look for persistence mechanisms strings -a malware.exe | \ grep -iE '(startup|run|service|schedule|task)' | \ head -10 # Extract environment variables accessed strings -a binary | \ grep -E '%[A-Z_]+%|$[A-Z_]+' | \ sort -u # Find debug/error messages strings -a app.exe | \ grep -iE '^(error|warning|debug|info):' | \ head -10 # Create full report cat > malware_analysis.sh << 'EOF' #!/bin/bash SAMPLE="$1" REPORT="${SAMPLE}.strings_report.txt" { echo "Strings Analysis Report" echo "Sample: $SAMPLE" echo "Date: $(date)" echo "MD5: $(md5sum "$SAMPLE" | awk '{print $1}')" echo "======================================" echo "" echo "ALL STRINGS:" strings -a "$SAMPLE" echo "" echo "UTF-16 STRINGS:" strings -a -e l "$SAMPLE" } > "$REPORT" echo "Report saved: $REPORT" EOF chmod +x malware_analysis.sh # Clean up rm -f security_triage.sh malware_analysis.sh
Output:
========================================= Security Triage: suspicious.exe ========================================= === Network Indicators === IP addresses: 192.168.1.100 10.0.0.5 172.16.0.1 URLs: http://malicious-site.com/payload https://command-control.net/api http://download.badsite.org/update Domain names: malicious-site.com command-control.net update-server.org === File Operations === CreateFileA WriteFile DeleteFileW CopyFileA === Registry Operations (Windows) === RegOpenKeyEx RegSetValueEx HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run === Process Operations === CreateProcess OpenProcess Process injection complete shellcode === Suspicious Keywords === admin password123 cmd.exe shell exploit payload backdoor === Crypto/Encoding === base64_encode AES_encrypt decrypt_data
Warning:

Never execute unknown binaries! Use strings for static analysis only. Strings can reveal malicious intent but sophisticated malware may obfuscate strings. This is initial triage - not comprehensive analysis. Always use in isolated environment. Combine with other tools (file, objdump, IDA) for full analysis.

Example 6

Data Recovery and Forensics

Extract readable text from corrupted files, disk images, memory dumps, or damaged storage media. strings can recover data when traditional methods fail.
# Recover text from corrupted document strings -a corrupted_document.docx | grep -v "^.$" > recovered_text.txt # Extract data from disk image strings -a -n 8 disk.img | grep -i "confidential" > recovered_data.txt # Scan partition for deleted files sudo strings -a /dev/sda1 | \ grep -E '\.(txt|doc|pdf)' | \ head -20 # Memory dump analysis strings -a memory.dmp | \ grep -E 'password|username|email' | \ sort -u > credentials_found.txt # Recover email addresses from damaged drive sudo strings -a /dev/sdb | \ grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | \ sort -u > recovered_emails.txt # Extract URLs from browser cache strings -a cache_file | \ grep -oE 'https?://[^ ]+' | \ head -50 # Recover phone numbers strings -a data.bin | \ grep -oE '\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}' | \ sort -u # Find credit card numbers (for forensics only!) strings -a suspicious.img | \ grep -oE '\b[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\b' | \ head -10 # Carve files from raw partition cat > carve_strings.sh << 'EOF' #!/bin/bash DEVICE="$1" OUTPUT_DIR="strings_carved" mkdir -p "$OUTPUT_DIR" echo "Carving strings from $DEVICE" # Extract potential filenames sudo strings -a "$DEVICE" | \ grep -E '\.(txt|doc|pdf|jpg|png|exe)$' | \ sort -u > "$OUTPUT_DIR/filenames.txt" # Extract email content sudo strings -a "$DEVICE" | \ grep -i "From:" -A 20 | \ head -100 > "$OUTPUT_DIR/email_fragments.txt" # Extract source code fragments sudo strings -a "$DEVICE" | \ grep -E '(function|class|import|include)' | \ head -100 > "$OUTPUT_DIR/code_fragments.txt" echo "Results in $OUTPUT_DIR/" EOF chmod +x carve_strings.sh # Recover data from USB drive # sudo ./carve_strings.sh /dev/sdc1 # Extract metadata from image files in disk strings -a photo.jpg | \ grep -iE '(Camera|Model|DateTime|GPS|Software)' | \ head -20 # Find remaining fragments of deleted file strings -a -t x disk.img | \ grep "important document" | \ awk '{print $1}' # Shows hex offsets # Timeline analysis from logs on damaged drive sudo strings -a /dev/sda | \ grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2}' | \ sort -u | \ head -50 # Recover configuration data strings -a damaged_config.bin | \ grep -E '(server|host|port|database|username)' > recovered_config.txt # Clean up rm -f carve_strings.sh recovered_*.txt
Output:
# Recovered text from corrupted Word doc: Project Timeline Q1 Goals and Objectives Budget Allocation Team Assignments Critical Deliverables # From disk image: confidential_report_2025.pdf C:\Users\John\Documents\Confidential\ Project_Secret_Files\ password_list.txt # Email addresses recovered: john.doe@company.com admin@internal.net support@vendor.org contact@client.com # URLs from cache: https://banking.com/login https://email.company.com/inbox https://drive.company.com/files https://internal-wiki.net/projects # Metadata from image: Camera Make: Canon Camera Model: EOS 5D Mark IV DateTime: 2025:12:14 10:30:45 GPS Latitude: 42.3601 GPS Longitude: -71.0589 Software: Adobe Photoshop CS6
Warning:

Scanning raw devices requires root/admin privileges. Always work on images, not live systems when possible. strings recovers fragments, not complete files. Results may contain sensitive data - handle appropriately. For professional forensics, use dedicated tools (Autopsy, EnCase) alongside strings. Never modify original evidence!

Example 7

Firmware and Embedded System Analysis

Extract information from firmware images, embedded system binaries, and IoT device software. Useful for security research and reverse engineering of embedded devices.
# Analyze router firmware strings -a -n 6 firmware.bin | head -100 # Find hardcoded credentials strings -a firmware.bin | \ grep -iE '(admin|root|password|default)' | \ grep -E '.{4,}[:=]' | \ head -20 # Extract version information strings -a firmware.bin | \ grep -iE 'version|v[0-9]+\.[0-9]+|build' | \ head -10 # Find filesystem paths strings -a firmware.bin | \ grep '^/' | \ sort -u | \ head -30 # Look for web interface strings strings -a firmware.bin | \ grep -E '(\.html|\.js|\.css|\.php)' | \ head -20 # Extract potential backdoor indicators cat > analyze_firmware.sh << 'EOF' #!/bin/bash FIRMWARE="$1" echo "Firmware Analysis: $(basename "$FIRMWARE")" echo "==========================================" echo "" echo "=== Device Information ===" strings -a "$FIRMWARE" | \ grep -iE '(vendor|manufacturer|model|device)' | \ head -10 echo "" echo "=== Network Services ===" strings -a "$FIRMWARE" | \ grep -iE '(telnet|ssh|http|ftp|tftp)' | \ sort -u | \ head -10 echo "" echo "=== Default Credentials ===" strings -a "$FIRMWARE" | \ grep -iE '(user.*pass|admin.*pass|default)' | \ head -10 echo "" echo "=== Listening Ports ===" strings -a "$FIRMWARE" | \ grep -oE ':[0-9]{2,5}' | \ sort -u | \ head -15 echo "" echo "=== Command Injection Risks ===" strings -a "$FIRMWARE" | \ grep -E '(system\(|exec\(|popen\(|sh -c)' | \ head -10 echo "" echo "=== Encryption/Keys ===" strings -a "$FIRMWARE" | \ grep -iE '(key|cert|rsa|aes|encrypt)' | \ head -10 echo "" echo "=== Update Mechanism ===" strings -a "$FIRMWARE" | \ grep -iE '(update|upgrade|download|http.*/fw)' | \ head -10 EOF chmod +x analyze_firmware.sh ./analyze_firmware.sh router_firmware.bin # Extract bootloader strings strings -a firmware.bin | \ grep -iE '(u-boot|bootloader|grub|loader)' | \ head -15 # Find kernel version strings -a firmware.bin | \ grep -E 'Linux version [0-9]' # Look for BusyBox commands strings -a firmware.bin | \ grep -E '^(ls|cat|echo|mount|ifconfig|ping)$' | \ sort -u # Extract debug messages strings -a firmware.bin | \ grep -iE '^(DEBUG|INFO|ERROR|WARN):' | \ head -20 # Find manufacturer URLs strings -a firmware.bin | \ grep -oE 'https?://[a-zA-Z0-9.-]+' | \ sort -u # IoT device analysis cat > iot_analysis.sh << 'EOF' #!/bin/bash DEVICE_BIN="$1" echo "IoT Device Binary Analysis" echo "==========================" # Extract Wi-Fi related strings echo "" echo "=== Wi-Fi Configuration ===" strings -a "$DEVICE_BIN" | \ grep -iE '(ssid|wpa|wifi|wireless|802\.11)' | \ head -10 # Cloud connectivity echo "" echo "=== Cloud Services ===" strings -a "$DEVICE_BIN" | \ grep -iE '(aws|azure|mqtt|cloud|iot)' | \ head -10 # API endpoints echo "" echo "=== API Endpoints ===" strings -a "$DEVICE_BIN" | \ grep -E '/api/|/v[0-9]+/' | \ head -15 EOF chmod +x iot_analysis.sh # Extract configuration file paths strings -a firmware.bin | \ grep -E '\.(conf|cfg|ini|config)$' | \ sort -u # Clean up rm -f analyze_firmware.sh iot_analysis.sh
Output:
Firmware Analysis: router_firmware.bin ========================================== === Device Information === Manufacturer: Acme Networks Model: WRT-5000 Device Type: Wireless Router Hardware Version: 1.2 === Network Services === telnetd httpd sshd ftpd :80 :23 :22 === Default Credentials === admin:admin root:password default username: admin default password: 12345 === Listening Ports === :22 :23 :80 :443 :8080 :8443 === Command Injection Risks === system(cmd) popen("/bin/sh", "r") exec /bin/sh === Update Mechanism === http://firmware.acme.com/updates/ check_for_update() download_firmware /tmp/firmware_upgrade.bin # Bootloader strings: U-Boot 2019.07 Booting kernel Loading from NAND flash Boot command: bootm # Kernel version: Linux version 4.9.0 (builder@buildhost)
Note:

Firmware often contains: default credentials, debug interfaces, hardcoded keys, update URLs, backdoors. Use -a for firmware (not ELF format). Increase -n to 6-8 to reduce noise. Look for: telnet/SSH access, web interfaces, cloud endpoints, encryption keys. Common findings: default admin:admin, debug ports, insecure update mechanisms.

Example 8

Comparing Binaries and Version Analysis

Use strings to compare different versions of binaries, identify changes, track updates, and detect modifications or tampering.
# Compare strings between two versions diff <(strings binary_v1.0) <(strings binary_v2.0) # Show only new strings in v2 comm -13 \ <(strings binary_v1.0 | sort) \ <(strings binary_v2.0 | sort) # Show only removed strings from v1 comm -23 \ <(strings binary_v1.0 | sort) \ <(strings binary_v2.0 | sort) # Create detailed comparison cat > compare_versions.sh << 'EOF' #!/bin/bash FILE1="$1" FILE2="$2" echo "Binary Comparison" echo "=================" echo "File 1: $FILE1" echo "File 2: $FILE2" echo "" STRINGS1=$(mktemp) STRINGS2=$(mktemp) strings "$FILE1" | sort > "$STRINGS1" strings "$FILE2" | sort > "$STRINGS2" TOTAL1=$(wc -l < "$STRINGS1") TOTAL2=$(wc -l < "$STRINGS2") COMMON=$(comm -12 "$STRINGS1" "$STRINGS2" | wc -l) NEW=$(comm -13 "$STRINGS1" "$STRINGS2" | wc -l) REMOVED=$(comm -23 "$STRINGS1" "$STRINGS2" | wc -l) echo "Statistics:" echo " $FILE1: $TOTAL1 strings" echo " $FILE2: $TOTAL2 strings" echo " Common: $COMMON strings" echo " New in $FILE2: $NEW strings" echo " Removed from $FILE1: $REMOVED strings" echo "" echo "New strings in $FILE2:" comm -13 "$STRINGS1" "$STRINGS2" | head -20 echo "" echo "Removed strings from $FILE1:" comm -23 "$STRINGS1" "$STRINGS2" | head -20 rm "$STRINGS1" "$STRINGS2" EOF chmod +x compare_versions.sh ./compare_versions.sh app_v1.exe app_v2.exe # Detect tampering cat > detect_tampering.sh << 'EOF' #!/bin/bash ORIGINAL="$1" SUSPECT="$2" echo "Tampering Detection Analysis" echo "============================" # Compare string counts ORIG_COUNT=$(strings "$ORIGINAL" | wc -l) SUSP_COUNT=$(strings "$SUSPECT" | wc -l) echo "Original strings: $ORIG_COUNT" echo "Suspect strings: $SUSP_COUNT" # Look for suspicious additions echo "" echo "Suspicious new strings:" comm -13 \ <(strings "$ORIGINAL" | sort) \ <(strings "$SUSPECT" | sort) | \ grep -iE '(backdoor|hack|inject|malware|trojan)' | \ head -10 # Check for removed security strings echo "" echo "Missing security-related strings:" comm -23 \ <(strings "$ORIGINAL" | grep -iE '(verify|auth|secure|encrypt)' | sort) \ <(strings "$SUSPECT" | grep -iE '(verify|auth|secure|encrypt)' | sort) | \ head -10 EOF chmod +x detect_tampering.sh # Track version changes cat > version_tracker.sh << 'EOF' #!/bin/bash BINARY="$1" echo "Version Information Extraction" echo "==============================" # Extract version strings echo "Version strings:" strings "$BINARY" | \ grep -iE 'v?[0-9]+\.[0-9]+(\.[0-9]+)?|version' | \ head -10 # Extract build information echo "" echo "Build information:" strings "$BINARY" | \ grep -iE '(build|compiled|date|time)' | \ head -10 # Extract copyright/author echo "" echo "Copyright/Author:" strings "$BINARY" | \ grep -iE '(copyright|author|company|\(c\))' | \ head -10 EOF chmod +x version_tracker.sh ./version_tracker.sh /usr/bin/gcc # Compare library versions for lib in /lib/x86_64-linux-gnu/libc*.so*; do echo "=== $(basename $lib) ===" strings "$lib" | grep -i "version" | head -3 echo "" done # Find modified system binaries cat > find_modified.sh << 'EOF' #!/bin/bash # Compare installed binary with package version BINARY="/bin/ls" PACKAGE_FILE="/var/cache/apt/archives/coreutils*.deb" if [ ! -f "$PACKAGE_FILE" ]; then echo "Package file not found" exit 1 fi # Extract package binary mkdir -p /tmp/pkg_extract dpkg-deb -x "$PACKAGE_FILE" /tmp/pkg_extract 2>/dev/null PKG_BINARY="/tmp/pkg_extract/bin/ls" echo "Comparing $BINARY with package version" diff <(strings "$BINARY" | sort) <(strings "$PKG_BINARY" | sort) || \ echo "Binaries differ!" rm -rf /tmp/pkg_extract EOF chmod +x find_modified.sh # Clean up rm -f compare_versions.sh detect_tampering.sh version_tracker.sh find_modified.sh
Output:
Binary Comparison ================= File 1: app_v1.exe File 2: app_v2.exe Statistics: app_v1.exe: 1234 strings app_v2.exe: 1456 strings Common: 1123 strings New in app_v2.exe: 333 strings Removed from app_v1.exe: 111 strings New strings in app_v2.exe: New feature: Cloud sync Enable telemetry Send usage data api.newservice.com Updated to version 2.0 Removed strings from app_v1.exe: Legacy mode Old API endpoint Deprecated function # Tampering detection: Tampering Detection Analysis ============================ Original strings: 2341 Suspect strings: 2389 Suspicious new strings: backdoor_init inject_payload disable_security_check Missing security-related strings: verify_signature authenticate_user secure_connection # Version information: Version strings: GCC version 11.4.0 Build: 20230917 Built for x86_64-linux-gnu
Note:

Use comm to compare sorted string lists: -12 shows common, -13 shows unique to file2, -23 shows unique to file1. String comparison reveals: new features, removed functionality, version changes, potential tampering. Always compare same encoding types. Useful for: patch analysis, malware variants, backdoor detection, integrity checking.

Example 9

Advanced Filtering and Pattern Matching

Combine strings with grep, awk, sed, and other tools for sophisticated pattern matching, filtering, and data extraction from binary files.
# Extract only long strings (reduce noise) strings -n 20 binary.exe # Find strings matching specific pattern strings binary | grep -E '^[A-Z][a-z]+[A-Z][a-zA-Z]*$' # CamelCase # Extract IPv4 addresses strings -a binary | \ grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' | \ sort -u # Find base64 encoded data strings binary | \ grep -E '^[A-Za-z0-9+/]{20,}={0,2}$' # Extract hex strings strings binary | \ grep -E '^[0-9A-Fa-f]{32,}$' # Find UUIDs strings binary | \ grep -E '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' # Extract Windows registry paths strings binary | \ grep 'HKEY_' | \ grep -E 'HKEY_(LOCAL_MACHINE|CURRENT_USER|CLASSES_ROOT)' # Find SQL queries strings app.exe | \ grep -iE '^(SELECT|INSERT|UPDATE|DELETE|CREATE)' | \ head -10 # Extract file extensions strings binary | \ grep -oE '\.[a-z]{2,4}$' | \ sort | uniq -c | sort -rn # Advanced pattern extraction cat > extract_patterns.sh << 'EOF' #!/bin/bash BINARY="$1" echo "Pattern Extraction: $(basename "$BINARY")" echo "=======================================" # Email addresses echo "" echo "=== Email Addresses ===" strings -a "$BINARY" | \ grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | \ sort -u | head -10 # URLs echo "" echo "=== URLs ===" strings -a "$BINARY" | \ grep -oE 'https?://[a-zA-Z0-9./?=_%:-]+' | \ sort -u | head -10 # IP:Port combinations echo "" echo "=== IP:Port ===" strings -a "$BINARY" | \ grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{2,5}' | \ sort -u # Windows file paths echo "" echo "=== Windows Paths ===" strings -a "$BINARY" | \ grep -E '^[A-Za-z]:\\' | \ head -10 # Unix file paths echo "" echo "=== Unix Paths ===" strings -a "$BINARY" | \ grep -E '^/[a-z]+/' | \ head -10 # Function names (likely) echo "" echo "=== Potential Functions ===" strings -a "$BINARY" | \ grep -E '^[a-z_][a-z0-9_]*\(' | \ head -15 # Error codes echo "" echo "=== Error Messages ===" strings -a "$BINARY" | \ grep -iE '^(error|exception|fatal)' | \ head -10 EOF chmod +x extract_patterns.sh ./extract_patterns.sh application.exe # Statistical analysis cat > string_stats.sh << 'EOF' #!/bin/bash BINARY="$1" echo "String Statistics: $(basename "$BINARY")" echo "======================================" TOTAL=$(strings "$BINARY" | wc -l) UNIQUE=$(strings "$BINARY" | sort -u | wc -l) echo "Total strings: $TOTAL" echo "Unique strings: $UNIQUE" echo "Duplicate ratio: $(awk "BEGIN {printf \"%.2f%%\", (1-$UNIQUE/$TOTAL)*100}")" echo "" echo "Length distribution:" strings "$BINARY" | \ awk '{print length}' | \ sort -n | \ uniq -c | \ tail -20 echo "" echo "Most common strings:" strings "$BINARY" | \ sort | \ uniq -c | \ sort -rn | \ head -10 echo "" echo "Longest strings:" strings "$BINARY" | \ awk '{print length, $0}' | \ sort -rn | \ head -5 EOF chmod +x string_stats.sh ./string_stats.sh /bin/bash # Context extraction strings -a binary | \ grep -B 2 -A 2 "interesting_string" # Filter by character class strings binary | \ grep '^[A-Z][A-Z_]*$' # ALL_CAPS constants strings binary | \ grep '^[a-z][a-z_]*$' # all_lowercase # Exclude common noise strings binary | \ grep -v -E '^(and|the|for|with|from|that|this|have|been)$' # Clean up rm -f extract_patterns.sh string_stats.sh
Output:
Pattern Extraction: application.exe ======================================= === Email Addresses === admin@company.com support@vendor.net info@example.org === URLs === http://api.service.com/v1/ https://update.company.net/check https://login.example.com/auth === IP:Port === 192.168.1.100:8080 10.0.0.5:443 172.16.0.1:22 === Windows Paths === C:\Windows\System32\ C:\Program Files\Application\ C:\Users\Public\Documents\ === Unix Paths === /usr/bin/ /etc/config/ /var/log/ === Potential Functions === main() init_application( process_data( connect_to_server( validate_input( # String statistics: String Statistics: bash ====================================== Total strings: 3456 Unique strings: 2891 Duplicate ratio: 16.35% Length distribution: 100 4 150 5 200 6 250 7 300 8 Most common strings: 15 bash 12 error 10 invalid 8 cannot 7 command Longest strings: 156 bash: command not found: very long error message...
Note:

Combine strings with grep/awk for powerful pattern extraction. Common patterns: email regex, IP addresses, UUIDs, paths, URLs. Use -o with grep to extract only matching parts. Statistics reveal: duplicate strings (possible compression/optimization), length distribution, common patterns. Filter noise with grep -v to exclude common words.

Example 10

Complete Binary Analysis Framework

A comprehensive binary analysis system using strings as the foundation. Production-ready framework for automated analysis, reporting, and threat detection.
#!/bin/bash # File: binary_analyzer.sh # Comprehensive binary analysis using strings set -euo pipefail # ============================================ # Configuration # ============================================ readonly ANALYSIS_DIR="./analysis_results" readonly MIN_STRING_LENGTH=6 readonly MAX_REPORT_ITEMS=50 # ============================================ # Initialize # ============================================ mkdir -p "$ANALYSIS_DIR" # ============================================ # Logging # ============================================ log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" } # ============================================ # String Extraction # ============================================ extract_strings() { local binary="$1" local output_dir="$2" log "Extracting strings from $(basename "$binary")" # ASCII strings strings -a -n "$MIN_STRING_LENGTH" "$binary" \ > "$output_dir/strings_ascii.txt" # UTF-16 strings (Windows) strings -a -e l -n "$MIN_STRING_LENGTH" "$binary" \ > "$output_dir/strings_utf16.txt" # With offsets strings -a -t x -n "$MIN_STRING_LENGTH" "$binary" \ > "$output_dir/strings_with_offsets.txt" log "Extracted $(wc -l < "$output_dir/strings_ascii.txt") ASCII strings" log "Extracted $(wc -l < "$output_dir/strings_utf16.txt") UTF-16 strings" } # ============================================ # Pattern Detection # ============================================ detect_patterns() { local strings_file="$1" local output_dir="$2" log "Detecting patterns..." # Network indicators grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' "$strings_file" | \ sort -u > "$output_dir/ip_addresses.txt" 2>/dev/null || true grep -oE 'https?://[a-zA-Z0-9./?=_%:-]+' "$strings_file" | \ sort -u > "$output_dir/urls.txt" 2>/dev/null || true grep -oE '[a-zA-Z0-9.-]+\.(com|net|org|io|edu|gov)' "$strings_file" | \ sort -u > "$output_dir/domains.txt" 2>/dev/null || true # Email addresses grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' "$strings_file" | \ sort -u > "$output_dir/emails.txt" 2>/dev/null || true # File paths grep -E '^[A-Za-z]:\\|^/' "$strings_file" | \ sort -u > "$output_dir/file_paths.txt" 2>/dev/null || true # Registry keys grep 'HKEY_' "$strings_file" | \ sort -u > "$output_dir/registry_keys.txt" 2>/dev/null || true log "Pattern detection complete" } # ============================================ # Threat Analysis # ============================================ analyze_threats() { local strings_file="$1" local output_dir="$2" log "Analyzing potential threats..." local threats_found=0 { echo "# Threat Analysis Report" echo "# Generated: $(date)" echo "" # Suspicious keywords echo "## Suspicious Keywords" if grep -iE '(password|passwd|pwd|secret|key|token|api_key)' "$strings_file" > /dev/null; then echo "⚠ Potential credential strings found:" grep -iE '(password|passwd|pwd|secret|key|token|api_key)' "$strings_file" | \ head -$MAX_REPORT_ITEMS ((threats_found++)) fi echo "" # Malicious indicators echo "## Malicious Indicators" if grep -iE '(backdoor|rootkit|keylog|inject|exploit|payload|shell)' "$strings_file" > /dev/null; then echo "🔴 CRITICAL: Malicious indicators detected:" grep -iE '(backdoor|rootkit|keylog|inject|exploit|payload|shell)' "$strings_file" | \ head -$MAX_REPORT_ITEMS ((threats_found++)) fi echo "" # Cryptographic operations echo "## Cryptographic Operations" if grep -iE '(encrypt|decrypt|cipher|crypto|aes|rsa|base64)' "$strings_file" > /dev/null; then echo "ℹ Cryptographic operations detected:" grep -iE '(encrypt|decrypt|cipher|crypto|aes|rsa|base64)' "$strings_file" | \ head -$MAX_REPORT_ITEMS fi echo "" # Network operations echo "## Network Operations" if grep -iE '(socket|connect|listen|send|recv|http|ftp)' "$strings_file" > /dev/null; then echo "ℹ Network operations detected:" grep -iE '(socket|connect|listen|send|recv|http|ftp)' "$strings_file" | \ head -$MAX_REPORT_ITEMS fi echo "" # Process operations echo "## Process Operations" if grep -iE '(CreateProcess|exec|spawn|fork|kill)' "$strings_file" > /dev/null; then echo "ℹ Process operations detected:" grep -iE '(CreateProcess|exec|spawn|fork|kill)' "$strings_file" | \ head -$MAX_REPORT_ITEMS fi echo "" # Summary echo "## Summary" echo "Threat indicators found: $threats_found" if [ $threats_found -gt 0 ]; then echo "⚠ THIS BINARY REQUIRES DETAILED ANALYSIS" else echo "✓ No obvious malicious indicators (does not guarantee safety)" fi } > "$output_dir/threat_analysis.txt" log "Threat analysis complete: $threats_found indicators" } # ============================================ # Statistical Analysis # ============================================ generate_statistics() { local strings_file="$1" local output_dir="$2" log "Generating statistics..." local total=$(wc -l < "$strings_file") local unique=$(sort -u "$strings_file" | wc -l) { echo "# Statistical Analysis" echo "======================" echo "" echo "Total strings: $total" echo "Unique strings: $unique" echo "Duplicate ratio: $(awk "BEGIN {printf \"%.2f%%\", (1-$unique/$total)*100}")" echo "" echo "## Length Distribution (top 10)" awk '{print length}' "$strings_file" | \ sort -n | uniq -c | sort -rn | head -10 echo "" echo "## Most Common Strings (top 20)" sort "$strings_file" | uniq -c | sort -rn | head -20 echo "" echo "## Longest Strings (top 10)" awk '{print length, $0}' "$strings_file" | \ sort -rn | head -10 } > "$output_dir/statistics.txt" log "Statistics generated" } # ============================================ # Report Generation # ============================================ generate_report() { local binary="$1" local output_dir="$2" log "Generating comprehensive report..." local report="$output_dir/ANALYSIS_REPORT.txt" { echo "========================================" echo "BINARY ANALYSIS REPORT" echo "========================================" echo "" echo "File: $binary" echo "Analyzed: $(date)" echo "File Size: $(stat -c%s "$binary" 2>/dev/null || stat -f%z "$binary") bytes" echo "MD5: $(md5sum "$binary" 2>/dev/null | awk '{print $1}' || md5 "$binary" | awk '{print $NF}')" echo "SHA256: $(sha256sum "$binary" 2>/dev/null | awk '{print $1}' || shasum -a 256 "$binary" | awk '{print $1}')" echo "" echo "========================================" echo "THREAT ANALYSIS" echo "========================================" cat "$output_dir/threat_analysis.txt" echo "" echo "========================================" echo "NETWORK INDICATORS" echo "========================================" echo "IP Addresses: $(wc -l < "$output_dir/ip_addresses.txt" 2>/dev/null || echo 0)" if [ -s "$output_dir/ip_addresses.txt" ]; then head -20 "$output_dir/ip_addresses.txt" fi echo "" echo "URLs: $(wc -l < "$output_dir/urls.txt" 2>/dev/null || echo 0)" if [ -s "$output_dir/urls.txt" ]; then head -20 "$output_dir/urls.txt" fi echo "" echo "Domains: $(wc -l < "$output_dir/domains.txt" 2>/dev/null || echo 0)" if [ -s "$output_dir/domains.txt" ]; then head -20 "$output_dir/domains.txt" fi echo "" echo "========================================" echo "STATISTICS" echo "========================================" cat "$output_dir/statistics.txt" echo "" echo "========================================" echo "FILES GENERATED" echo "========================================" ls -lh "$output_dir" } > "$report" log "Report generated: $report" echo "" cat "$report" } # ============================================ # Main Analysis Function # ============================================ analyze_binary() { local binary="$1" if [ ! -f "$binary" ]; then log "Error: File not found: $binary" return 1 fi local basename=$(basename "$binary") local output_dir="$ANALYSIS_DIR/${basename}_$(date +%Y%m%d_%H%M%S)" mkdir -p "$output_dir" log "=========================================" log "Starting analysis: $basename" log "Output directory: $output_dir" log "=========================================" # Extract strings extract_strings "$binary" "$output_dir" # Detect patterns detect_patterns "$output_dir/strings_ascii.txt" "$output_dir" # Analyze threats analyze_threats "$output_dir/strings_ascii.txt" "$output_dir" # Generate statistics generate_statistics "$output_dir/strings_ascii.txt" "$output_dir" # Generate report generate_report "$binary" "$output_dir" log "=========================================" log "Analysis complete" log "=========================================" } # ============================================ # Main # ============================================ main() { if [ $# -eq 0 ]; then echo "Usage: $0 <binary_file>" echo "" echo "Comprehensive binary analysis using strings" echo "Results saved to: $ANALYSIS_DIR" exit 1 fi analyze_binary "$1" } main "$@"
Script execution output:
[2025-12-14 20:00:00] ========================================= [2025-12-14 20:00:00] Starting analysis: suspicious.exe [2025-12-14 20:00:00] Output directory: ./analysis_results/suspicious.exe_20251214_200000 [2025-12-14 20:00:00] ========================================= [2025-12-14 20:00:00] Extracting strings from suspicious.exe [2025-12-14 20:00:01] Extracted 2456 ASCII strings [2025-12-14 20:00:01] Extracted 1834 UTF-16 strings [2025-12-14 20:00:01] Detecting patterns... [2025-12-14 20:00:02] Pattern detection complete [2025-12-14 20:00:02] Analyzing potential threats... [2025-12-14 20:00:02] Threat analysis complete: 2 indicators [2025-12-14 20:00:02] Generating statistics... [2025-12-14 20:00:03] Statistics generated [2025-12-14 20:00:03] Generating comprehensive report... [2025-12-14 20:00:03] Report generated: ./analysis_results/.../ANALYSIS_REPORT.txt ======================================== BINARY ANALYSIS REPORT ======================================== File: suspicious.exe Analyzed: Sun Dec 14 20:00:03 EST 2025 File Size: 2456832 bytes MD5: a1b2c3d4e5f6... SHA256: 1a2b3c4d5e6f... ======================================== THREAT ANALYSIS ======================================== ## Suspicious Keywords ⚠ Potential credential strings found: admin_password= api_key_secret default_token ## Malicious Indicators 🔴 CRITICAL: Malicious indicators detected: backdoor_init() inject_shellcode keylogger_start ## Summary Threat indicators found: 2 ⚠ THIS BINARY REQUIRES DETAILED ANALYSIS ======================================== NETWORK INDICATORS ======================================== IP Addresses: 5 192.168.1.100 10.0.0.5 172.16.0.1 URLs: 8 http://command-control.net/api https://malicious-site.com/payload ======================================== FILES GENERATED ======================================== strings_ascii.txt strings_utf16.txt strings_with_offsets.txt ip_addresses.txt urls.txt domains.txt threat_analysis.txt statistics.txt ANALYSIS_REPORT.txt
Note:

This production framework provides comprehensive binary analysis: string extraction (multiple encodings), pattern detection (IPs, URLs, emails), threat analysis (malware indicators), statistical analysis, and detailed reporting. Suitable for: malware triage, security analysis, forensics, reverse engineering. Always combine with other tools for complete analysis. Automate with cron for continuous monitoring.

Tips & Best Practices

Default Minimum is 4 Characters
strings looks for sequences of at least 4 printable characters by default. Increase with -n to reduce noise: -n 8 for cleaner output, -n 6 is a good balance. Longer minimums miss shorter strings.
Always Use -a for Unknown Files
Default scans only data sections of object files. Use strings -a to scan entire file for: firmware, disk images, memory dumps, unknown binaries, or any non-ELF/PE file.
Check UTF-16 for Windows Binaries
Windows executables often use UTF-16 encoding. Use strings -e l for little-endian UTF-16. You'll miss important strings if you only check ASCII on Windows binaries.
Show Offsets with -t x
Use strings -t x to show hexadecimal offsets. Essential for forensics and correlating strings with hex editor or disassembler. Helps locate specific strings in large files.
Combine with grep for Pattern Matching
Pipe strings through grep to find specific patterns: URLs, IPs, emails, file paths. Example: strings binary | grep -E 'https?://'. Much faster than manual searching.
Never Execute Unknown Binaries
strings is non-invasive and safe - it only reads files. Perfect for malware analysis because it doesn't execute code. Always use strings before considering execution in sandboxes.
Sort and Unique for Analysis
Use strings binary | sort -u to remove duplicates and organize output. Easier to spot patterns and anomalies. Use uniq -c | sort -rn to find most common strings.
Compare Binaries with comm
Use comm to compare strings from different binary versions: comm -13 <(strings v1 | sort) <(strings v2 | sort) shows new strings. Great for patch analysis and tamper detection.
strings Shows Intent, Not Capability
Finding a string like "delete_files" doesn't prove the binary does it - only that the text exists. Use with disassemblers/debuggers for complete analysis. strings is triage, not proof.