#!/usr/bin/perl
#
# lit203conf - Show the config for Litmus 2.03
#
# Author: PinkFreud / Nightstar IRC Network
# Date  : 2003-12-14
#
# Based on information found on http://loonie.kewl.org/
#
$version = 1.0.3;
#
# Revision history:
#	1.0.0		Initial release
#	1.0.1		Supports modified AND byte (is this in the wild?)
#	1.0.2		Now allows specifying an offset (useful for
#			unpacked images)
#	1.0.3		Use default AND byte if offset is specified on the
#			commandline.  It's probably an unpacked image, so
#			the andoffset is almost certainly wrong...

sub usage {
  die "Usage: $0 <Litmus 2.03 exe> [offset]\n";
}
$#ARGV > -1 or usage;


sub readconf {
  my ($fh, $offset, $length) = @_;

  seek ($fh, $offset, 0);
  my $current_offset = tell ($fh);
  die
  "Uh oh, I tried to seek to $offset, but found myself at $current_offset instead.\n"
    unless $offset == $current_offset;
  
  my $bytesread = read ($fh, $data, $length);
  die
  "Whoops, tried to read $length bytes, but got $bytesread instead - truncated file?\n"
    unless $bytesread == $length;

  return $data;
}

sub deobfuscate {
  my ($num, @data) = @_;
  my ($data);
  my (@realdata);

  $num = hex $num;

  for $data (@data) {
    my ($tmp, $chr);
    for $chr (split (//, $data)) {
      $tmp .= chr (ord ($chr) + $num & 255);
    }
    push (@realdata, $tmp);
  }

  return (@realdata);
}


my $litmus = $ARGV[0];
my $andoffset = $#ARGV > 0 ? 0 : 0x45cd;
my $offset = $#ARGV > 0 ? eval $ARGV[1] : 0x5a00;
printf "Using offset 0x%x\n", $offset;
printf "Using andoffset 0x%x\n", $andoffset;

(-r $litmus) or die "$litmus not found, or not readable.  Exiting...\n";
(-s $litmus) == 36384 or
  warn "$litmus isn't 36384 bytes - possibly corrupt or not Litmus 2.03\n";

open (LITMUS, $litmus) or die "Failed to open $litmus: $!\n";
binmode (LITMUS);

my $num = sprintf "%02x", $andoffset == 0 ? 0x58 : 
  ord (readconf (*LITMUS, $andoffset, 1));
print "$num\n";
my $data1 = readconf (*LITMUS, $offset + 0, 99);
my $data2 = readconf (*LITMUS, $offset + 0x17e, 20);
my $data3 = readconf (*LITMUS, $offset + 0x1d0, 77);

close (LITMUS);

my ($nick, $key, $spass, $litmusver, $exe, $bpass, $server, $channel);

($nick, $key, undef, $spass, $litmusver, $exe) =
  unpack (Z19Z16Z5Z20A12Z25, $data1);
($bpass) = unpack (Z20, $data2);
($server, $channel) = unpack (Z39Z38, $data3);

warn
"We don't seem to be looking at Litmus 2.03 - things may not work as expected.\n" 
  unless $litmusver eq 'Litmus 2.03';

($nick, $bpass, $channel, $key, $server, $spass, $exe) =
  deobfuscate ($num, $nick, $bpass, $channel, $key, $server, $spass, $exe);

$ANDstat = $num eq 58 ? 'default' : 'modified!';

print <<_EOF_;
Version        : $litmusver
AND byte       : 0x$num [$ANDstat]
Nick prefix    : $nick
Bot password   : $bpass
Channel        : $channel
Channel key    : $key
Server         : $server
Server password: $spass
Bot filename   : $exe
_EOF_
