#!/bin/bash

PID=""
BYTES=128

while getopts "p:b:h" opt; do
    case $opt in
        p)
            PID="$OPTARG"
            ;;
        b)
            BYTES="$OPTARG"
            ;;
        h)
            echo "usage: $0 [-p PID] [-b bytes]"
            echo "  -p PID: process ID (auto-detected if not provided)"
            echo "  -b bytes: number of bytes to dump (default: 128)"
            exit 0
            ;;
        \?)
            echo "invalid option: -$OPTARG" >&2
            echo "use -h for help"
            exit 1
            ;;
    esac
done

if [ -z "$PID" ]; then
    PID=$(pgrep SilentPulse)
fi

if [ -z "$PID" ]; then
    echo "error: no SilentPulse process found"
    echo "use -p to specify PID manually"
    exit 1
fi

if [ ! -d "/proc/$PID" ]; then
    echo "error: process $PID not found"
    exit 1
fi

TEXT_INFO=$(grep -E '.*-.*\s+r-xp.*SilentPulse$' /proc/$PID/maps | head -1)
STATE="awake"

if [ -z "$TEXT_INFO" ]; then
    TEXT_INFO=$(grep -E '.*-.*\s+rw-p.*SilentPulse$' /proc/$PID/maps | head -1)
    STATE="sleeping"
fi

if [ -z "$TEXT_INFO" ]; then
    echo "error: could not find .text segment for pid $PID"
    echo "expected either r-xp (awake) or rw-p (sleeping) permissions"
    exit 1
fi

START_ADDR=$(echo $TEXT_INFO | cut -d' ' -f1 | cut -d'-' -f1)
END_ADDR=$(echo $TEXT_INFO | cut -d' ' -f1 | cut -d'-' -f2)

START_DEC=$((0x$START_ADDR))
END_DEC=$((0x$END_ADDR))
SIZE=$((END_DEC - START_DEC))

DUMP_SIZE=$((BYTES > SIZE ? SIZE : BYTES))

echo "pid: $PID"
echo "state: $STATE"
echo "address: 0x$START_ADDR - 0x$END_ADDR"
echo "size: $SIZE bytes (dumping $DUMP_SIZE)"
echo

dd if=/proc/$PID/mem bs=1 count=$DUMP_SIZE skip=$START_DEC 2>/dev/null | \
hexdump -C | head -n $((DUMP_SIZE / 16 + 1))

echo 
