miércoles, 14 de mayo de 2008

Decodificando películas que piden utilizar DomPlayer

DompPayer es un reproductor de vídeo comercial que cuesta 3 dólares y que, hasta donde nos han contado, instala spyware (a través de otro reproductor alternativo denominado 3wPlayer) al comprar una licencia fuera del país que DomPlayer.com determine. Existen una buena cantidad de vídeos en las redes entre iguales (P2P o peer-to-peer), muchos de estos interesantes, que inexplicablemente fueron codificados por alguien para obligar a los incautos a instalar y utilizar DomPlayer. Desde Windows se puede utilizar una herramienta de Wildman Productions, denominada 3wdecoder.exe, la cual requiere .Net para Windows. Desde Linux es posible decodificar estás películas con un sencillo guión en perl. Éste se utiliza de la siguiente forma.

Procedimientos:

Se copia el siguiente contenido dentro de un fichero denominado decoder.pl.

# Turn of output buffer
$|++;
# The key for XOR decryption
my $key = 'UIERYQWORTWEHLKDNKDBISGLZNCBZCVNBADFIEYLJ' . chr(0);
print "Reading from \"$ARGV[0]\":\n";
$insize = -s $ARGV[0];
# Open the bogus AVI file
open(IN, $ARGV[0]) or die $!;
binmode IN;
# Read Header to check
read(IN, $buffer, 4);
if ($buffer ne 'RIFF') {
print " ERROR: \"$ARGV[0]\" is not an AVI\n";
close IN;
exit(1);
}
# Get Length of the unencrypted movie
read(IN, $buffer, 4);
$offset = unpack 'L', $buffer;
print " End of the unencrypted movie is at byte offset $offset\n";
# Jump to the read offset
seek(IN, $offset, 0);
# The next 4 or 8 Bytes seem to be either an unsinged long
# or an unsigned quad. This is another offset to jump
# over some filler bytes. Right now I can't really tell if
# it's 4 or 8 bytes, because I only have 1 file to test with.
# I assume it's a quad.
# low word
read(IN, $buffer, 4);
$offlo = unpack 'L', $buffer;
# high word
read(IN, $buffer, 4);
$offhi = unpack 'L', $buffer;
# Calculate offset
$offset = $offhi * 4294967296 + $offlo;
print " Offset after the unencrypted movie is $offset\n";
seek(IN, $offset, 0);
# Then there seem to be another 100 filler bytes
# with value 0xff. Jump over those too, to get
# to the offset where the real movie starts.
printf " Adding extra filler bytes, final offset is %s\n", $offset+100;
seek(IN, 100, 1);
# Update the size
$insize -= $offset+100;
# Open a file for writing the decrypted data to
print "Decrypting to \"$ARGV[1]\":\n";
open(OUT, ">$ARGV[1]");
binmode OUT;
truncate OUT, 0;
$bytes = 0;
$klen = length($key);
# Read key length bytes, decrypt them and
# write them to the output file untill you reach
# the end of the file
while ( read(IN, $buffer, $klen) ) {
$buffer ^= $key;
print OUT $buffer;
$bytes += $klen;
# print the status
printf "\r %d written (% .1f %%)", $bytes, ($bytes / $insize * 100);
}
# Close both files
close OUT;
close IN;
print "\n\nDONE!\n";

Una vez creado decoder.pl, se utiliza de la siguiente forma desde cualquier terminal, y asumiendo que el vídeo a decodificar está en el directorio de trabajo actual:

perl decoder.pl pelicula_codificada.avi pelicula.avi

Luego de unos minutos, se obtendrá como resultado un vídeo que se puede visualizar con cualquier reproductor de vídeo desde Linux (Mplayer, Xine, Totem, VLC, etc.).

Fuentes: Edril Padayhag y Go iT expert.