Ir al contenido

Nm Commands

nm displays symbol information from binary files, object files, and libraries. It shows symbols including function names, variable names, and addresses. This tool is essential for understanding binary structure, debugging, and reverse engineering.

Installation

Linux/Ubuntu

sudo apt update
sudo apt install binutils

macOS

# Pre-installed
nm /usr/bin/ls

Basic Symbol Display

List Symbols

# Display symbols from executable
nm /usr/bin/ls

# Display symbols with addresses
nm /bin/bash

# Display from object file
nm object.o

# Display from shared library
nm /usr/lib/libc.so.6

# Display from static library
nm /usr/lib/libz.a

# Show symbol count
nm /usr/bin/ls | wc -l

Output Formatting

# Short format (default)
nm /usr/bin/ls

# Long format with addresses
nm -l /usr/bin/ls

# Symbols sorted by address
nm -n /usr/bin/ls

# Symbols sorted by value
nm -v /usr/bin/ls

# Print with column formatting
nm /usr/bin/ls

# Display file format
nm -f posix /usr/bin/ls

Symbol Types and Filtering

Symbol Type Display

# Show symbol type indicators
nm /usr/bin/ls

# Demangle C++ symbols
nm -C /usr/lib/libstdc++.so

# Demangled output (readable names)
nm -C application

# Show dynamic symbols only
nm -D /lib/libc.so.6

# Show external symbols
nm -g /usr/bin/ls

# Show debug symbols
nm -a /usr/bin/ls

# Show all symbols including debug
nm -a /usr/bin/bash | head -50

Symbol Categories

# Show only undefined symbols
nm -u /usr/bin/ls

# Show only defined symbols
nm -g /usr/bin/ls

# Show only external symbols
nm -e /usr/bin/ls

# Show only local symbols
nm -l /usr/bin/ls

# Show only weak symbols
nm /usr/bin/ls | grep 'w\|W'

# Combined types
nm -e /usr/bin/ls | grep -E 't|T'

Binary File Analysis

Executable Analysis

# Find exported functions
nm /usr/bin/application | grep ' T '

# Find imported functions
nm -u /usr/bin/application

# Find undefined references
nm -u /usr/bin/bash | head -20

# Find data symbols
nm /usr/bin/ls | grep ' [bdD] '

# Find weak symbols
nm /usr/bin/ls | grep -E 'w|W'

# Find thread-local symbols
nm /usr/bin/ls | grep 't'

# Find common symbols
nm /usr/bin/ls | grep 'C'

Library Analysis

# List exported functions from library
nm /usr/lib/libc.so.6 | grep ' T ' | head -20

# Find conflicting symbols
nm /usr/lib/libc.so.6 | grep ' [TW] ' | wc -l

# Check library dependencies
nm -D /usr/lib/libssl.so | grep ' U ' | head -20

# Find library entry point
nm /usr/lib/libc.so.6 | grep -E 'entry|_init'

# Display all library symbols
nm /usr/lib/libz.a | wc -l

# Static library members
ar t /usr/lib/libz.a | while read obj; do
  echo "=== $obj ==="
  nm --format=bsd /usr/lib/libz.a 2>/dev/null | head
done

Symbol Information and Analysis

Finding Specific Symbols

# Find specific function
nm /usr/bin/ls | grep printf

# Case-insensitive search
nm /usr/bin/ls | grep -i malloc

# Find symbols matching pattern
nm /usr/bin/bash | grep -E '^[0-9a-f]+.*main'

# Find imported malloc
nm -u /usr/bin/application | grep malloc

# Find symbol by partial name
nm /usr/bin/ls | grep -E 'str.*cpy'

# Find main function
nm /usr/bin/ls | grep -E '\smain$'

# Find constructor symbols
nm /usr/bin/application | grep -E '_init|_fini|_ZN'

Symbol Information Details

# Get symbol size
nm -S /usr/bin/ls | head -20

# Show symbol sizes
nm -S /usr/bin/bash | grep -E ' [0-9a-f]+ [0-9a-f]+ T '

# Print in BSD format
nm --format=bsd /usr/bin/ls

# Print in POSIX format
nm --format=posix /usr/bin/ls

# Format with addresses and sizes
nm -nSr /usr/bin/bash | head -20

# Detailed symbol listing
nm --defined-only -S /usr/bin/ls | sort -k2 -rn | head

Comparison and Analysis

Comparing Binaries

# Compare symbols in two binaries
diff <(nm /usr/bin/ls | sort) <(nm /usr/bin/file | sort)

# Find new symbols
comm -23 <(nm new_binary | sort) <(nm old_binary | sort)

# Find removed symbols
comm -13 <(nm new_binary | sort) <(nm old_binary | sort)

# Find common symbols
comm -12 <(nm /bin/ls | sort) <(nm /bin/cat | sort)

# Symbols only in first file
nm /usr/bin/binary1 | sort > sym1.txt
nm /usr/bin/binary2 | sort > sym2.txt
diff sym1.txt sym2.txt | grep '^<'

Symbol Statistics

# Count symbols by type
nm /usr/bin/ls | awk '{print $3}' | sort | uniq -c

# Count function symbols
nm /usr/bin/bash | grep -c ' T '

# Count data symbols
nm /usr/bin/bash | grep -c ' [bdD] '

# Count undefined symbols
nm -u /usr/bin/bash | wc -l

# Largest symbols by size
nm -S /usr/bin/ls | sort -k2 -rn | head -10

# Count symbols by category
nm /usr/bin/ls | grep ' U ' | wc -l  # undefined
nm /usr/bin/ls | grep ' [TW] ' | wc -l  # exported
nm /usr/bin/ls | grep ' [twr] ' | wc -l  # local

Advanced Operations

Dynamic Symbol Extraction

# Export function list
nm /usr/bin/application | grep ' T ' | awk '{print $3}' > functions.txt

# Export imported functions
nm -u /usr/bin/application | awk '{print $2}' > imported.txt

# Create call graph input
nm -u /usr/bin/binary | sed 's/.*/undefined: &/'

# Generate symbol report
{
  echo "Defined symbols:"
  nm /usr/bin/binary | grep ' T '
  echo "Undefined symbols:"
  nm -u /usr/bin/binary
} > symbol_report.txt

C++ Symbol Analysis

# Demangle C++ symbols
nm -C /usr/lib/libstdc++.so | head -20

# Find C++ class methods
nm -C /usr/lib/libstdc++.so | grep '::' | head

# Show name mangling
echo "nm -C vs nm:"
nm /usr/lib/libstdc++.so | head -1
nm -C /usr/lib/libstdc++.so | head -1

# Analyze template instantiation
nm -C application | grep '<'

# Find virtual methods
nm -C library | grep vtable

Security Analysis

# Check for weak functions
nm -D /usr/lib/libc.so.6 | grep -w w

# Find exported system functions
nm /bin/ls | grep -E 'exec|system|fork'

# Check for debug symbols
nm /usr/bin/ls | grep -c '^\|.*\S'

# Find suspicious symbols
nm /usr/bin/binary | grep -iE 'hack|backdoor|steal'

# List all imports
nm -u /usr/bin/binary | awk '{print $2}' | sort -u

# Find hardcoded paths
strings /usr/bin/binary | nm /usr/bin/binary

Performance and Bulk Operations

Batch Processing

# Analyze all binaries in /bin
for f in /bin/*; do
  [ -x "$f" ] && echo "=== $f ===" && nm "$f" | wc -l
done

# Find symbol across all libraries
for lib in /usr/lib/*.so*; do
  [ -f "$lib" ] && nm "$lib" 2>/dev/null | grep -q malloc && echo "$lib"
done

# Generate symbol inventory
find /usr/lib -name "*.so*" -exec sh -c '
  echo "=== {} ==="
  nm {} 2>/dev/null | wc -l
' \;

# Find symbols in all object files
find . -name "*.o" -exec nm {} +

Text Processing

# Extract just symbol names
nm /usr/bin/ls | awk '{print $NF}'

# Extract addresses and names
nm -n /usr/bin/ls | awk '{print $1, $NF}'

# Get symbols sorted by address
nm -n /usr/bin/ls | awk '{print $1 " " $NF}' | column -t

# Create symbol map
nm /usr/bin/application | awk '{print $NF "\t" $1}' > symbol_map.txt

# Export for scripting
nm /usr/bin/ls | awk '{print "symbol: " $NF " type: " $2}' > parsed.txt

Troubleshooting and Tips

# Check if file has symbols
nm /usr/bin/ls > /dev/null 2>&1 && echo "Has symbols"

# Verify binary format
file /usr/bin/ls
nm /usr/bin/ls | head

# Check symbol stripping
nm /usr/bin/ls | wc -l
strings /usr/bin/ls | wc -l

# Compare symbol counts before/after optimization
nm original | wc -l
nm optimized | wc -l

# Find symbol conflicts
nm /usr/lib/libA.so /usr/lib/libB.so | grep -E '^\|'

Best Practices

  • Use -C to demangle C++ symbols for readability
  • Use -S to see symbol sizes for optimization analysis
  • Use -D for dynamic symbols in shared libraries
  • Compare symbol lists between versions to track changes
  • Export symbol lists for documentation
  • Use -u to find unresolved dependencies
  • Check for undefined symbols before deployment
  • Document exported symbols for API stability
  • Monitor symbol growth in optimization cycles
  • Use symbol analysis for security audits

Last updated: 2026-03-30