#!/system/bin/sh

# ==UserScript==
# @name         mkshrc
# @namespace    https://github.com/hyugogirubato/KeyDive
# @version      2024.04.21
# @description  Make an advanced shell environment for Android devices
# @author       hyugogirubato
# @match        Android
# ==/UserScript==


# Set environment variables based on device properties
export HOSTNAME=$(getprop ro.boot.serialno)
export USER=$(id -u -n)
export LOGNAME=$USER
export TMPDIR=${TMPDIR:-/data/local/tmp}


# Find the architecture of the Android device using CPU ABI
find_arch() {
  # Source: https://github.com/Magisk-Modules-Repo/busybox-ndk/blob/master/customize.sh#L314C1-L334C2
  local abi=$(getprop ro.product.cpu.abi)
  case $abi in
    arm64*) ARCH='arm64' ;;
    arm*) ARCH='arm' ;;
    x86_64*) ARCH='x86_64' ;;
    x86*) ARCH='x86' ;;
    mips64*) ARCH='mips64' ;;
    mips*) ARCH='mips' ;;
    *) echo "Unknown architecture: $abi" >&2; return 1 ;;
  esac
}


# Initialize the architecture
find_arch

# Define and verify the path to the BusyBox binary
busybox='/sbin/.magisk/busybox/busybox'
if [ ! -f "$busybox" ]; then
  busybox="$TMPDIR/busybox"

  # Source: https://github.com/Magisk-Modules-Repo/busybox-ndk
  url="https://raw.githubusercontent.com/Magisk-Modules-Repo/busybox-ndk/master/busybox-$ARCH"
  [ -f '/sys/fs/selinux/enforce' ] && url+='-selinux'
  curl -fs -o "$busybox" "$url" || { echo "Failed to download BusyBox from $url" >&2; return 1; }

  # Ensure BusyBox binary is executable
  chmod 755 "$busybox"
  chown shell:shell "$busybox"
fi

# Create aliases for BusyBox commands
for bin in $($busybox --list); do
  if [ "$bin" != 'man' ]; then
    alias "$bin"="$busybox $bin" 2>/dev/null
  fi
done

# Handle Frida installation if Magisk is not installed
if [ ! -d '/sbin/.magisk/' ]; then
  frida="$TMPDIR/frida-server"

  if [ ! -f "$frida" ]; then
    # Source: https://github.com/frida/frida
    version='16.2.1'
    url="https://github.com/frida/frida/releases/download/$version/frida-server-$version-android-$ARCH.xz"
    curl -fsL -o "$frida.xz" "$url" || { echo "Failed to download Frida from $url" >&2; return 1; }
    $busybox xz -d "$frida.xz"
  fi

  # Ensure Frida binary is executable
  chmod 755 "$frida"
  chown shell:shell "$frida"
  alias 'frida-server'="$frida"
elif [ ! -d '/sbin/.magisk/modules/magisk-frida' ]; then
  echo 'Install Frida using: https://github.com/ViRb3/magisk-frida'
fi

# Enhance command output with color support if available
if ls --color=auto >/dev/null 2>&1; then
  alias ls='ls --color=always'
  alias grep='grep --color=auto'
  alias fgrep='fgrep --color=auto'
  alias egrep='egrep --color=auto'
  alias logcat='logcat -v color'
  alias ip='ip -c'
fi

# Define commonly used aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias ipa='ip a'
alias rm='rm -rf'

# Display directory tree
tree() {
  # Source: https://stackoverflow.com/questions/18014779/similar-command-to-linux-tree-command-in-adb-shell
  find "${1:-.}" -print | sort | sed 's;[^/]*/;|---;g;s;---|; |;g'
}

# Custom find command that displays colored results
cfind() {
  if ls --color=auto >/dev/null 2>&1; then
    find "${1:-.}" -print0 | xargs -0 ls -d1 --color=auto
  else
    echo 'Unsupported XTerm environment' >&2; return 1
  fi
}

# Simulate 'man' command
man() {
  [ -z "$1" ] && { echo -e "What manual page do you want?\nFor example, try 'man ls'." >&2; return 1; }
  "$1" --help
}

# Define a sudo-like function
sudo() {
  if [ "$(id -u)" -eq 0 ]; then
    "$@"
  elif command -v su >/dev/null 2>&1; then
    su -c "$*"
  else
    echo 'su binary not found' >&2; return 127
  fi
}

# Stop frida-server if it's running without Magisk
frida-stop() {
  if [ -d '/sbin/.magisk/' ]; then
    echo 'Use Magisk to stop Frida' >&2; return 1
  else
    local pid=$(pgrep -f frida-server)
    if [ ! -z "$pid" ]; then
      sudo kill -9 $pid || { echo 'Failed to stop Frida' >&2; return 1; }
    fi
  fi
}

# Check the status of the frida-server
frida-status() {
  local pid=$(pgrep -f frida-server)
  [ -z "$pid" ] && echo 'Frida not running' ||  echo "Frida PID: $pid"
}

# Start frida-server if it's not already running and Magisk is not installed
frida-start() {
  local pid=$(pgrep -f frida-server)
  if [ -z "$pid" ]; then
    if [ -d '/sbin/.magisk/' ]; then
      echo 'Use Magisk to start Frida' >&2; return 1
    else
      command -v setenforce >/dev/null 2>&1 && sudo setenforce 0 >/dev/null 2>&1
      sudo frida-server -D "$@" || { echo 'Failed to start Frida' >&2; return 1; }
    fi
  else
    echo 'Frida already running'
  fi
}