Skip to content

Instantly share code, notes, and snippets.

@p120ph37
Last active September 21, 2019 03:46
Show Gist options
  • Save p120ph37/2bf794a86eeab0445658 to your computer and use it in GitHub Desktop.
Save p120ph37/2bf794a86eeab0445658 to your computer and use it in GitHub Desktop.
Inject an eval into a running Perl process using GDB and temporarily capture STDERR.
#!/usr/bin/perl
use warnings;
use strict;
use threads;
use File::Temp;
use POSIX qw/mkfifo/;
my $pid = shift @ARGV;
my $eval = shift @ARGV || 'require Carp; local $Carp::CarpLevel = 1; Carp::cluck(\'Currently\');';
my $thread = $ENV{'GDB_THREAD'} || 'all';
my $gdb = $ENV{'GDB'} || '/usr/bin/gdb';
my $f = tmpnam();
$_ = umask(0); mkfifo($f, 0666) or die $!; umask($_);
async {
open(my $p, '<', $f);
unlink $f;
print <$p>;
}->detach();
$eval = "{open local(*STDERR), '>', '$f'; $eval}";
my $g = open(my $w, '|-', "$gdb -q -n -p $pid >/dev/null 2>&1") or die;
syswrite $w, 'thread apply '.$thread.' call Perl_sv_free(Perl_eval_pv(Perl_get_context(),"'.quotemeta($eval)."\",0))\ndetach\nquit\n";
waitpid($g, 0);
@p120ph37
Copy link
Author

Usage:
./perl_inject.pl 1234 'print STDERR "Current value of \$myglobal is $myglobal\n"'

  • Requires gdb to be installed, but does not require perl to have been built with debugging symbols.
  • Redirects STDERR for the duration of the eval, outputting it as STDOUT on the debugger's console rather than as part of the normal STDERR stream of the debugged process. This allows you to execute commands that output to STDERR even if the debugged process normally has STDERR directed somewhere inaccessible like /dev/null. This is accomplished via a temporary named pipe (fifo).
  • If no specific eval code is provided, displays a stacktrace of the process. (a Perl stack trace, not a C stacktrace. If you want a full C stacktrace, use the bt command in gdb.)
  • This script must be run with sufficient permissions to attach the debugger to the target process - generally, this means you either need to be root or the same user as the process in question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment