Despite its uselessnes you might like this one. It turns a wav file into an executable by attaching some playback routines to the wav file (or rather, attaching the wav data to the player executable):
This is w2e.c
. Should work for both of the common byte-orders:
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#define DEVICE "/dev/dsp"
typedef unsigned char UC;
static struct {
UC riff[4];
UC size[4];
UC wave[4];
/* format chunk */
UC fmt_[4];
UC lenf[4];
UC x__1[2];
UC chan[2];
UC freq[4];
UC bytes_sec[4];
UC bytes_sample[2];
UC bits_sample[2];
} WH;
struct {
int fmt;
int chans;
int speed;
} PLAY_PARAMS = { 0, 0, 0 };
static int AUDIO_FD;
static unsigned char buf[4096];
int calculate_offset (int fd) {
struct stat STAT;
fstat(fd, &STAT);
return STAT.st_size - WAVE_SIZE;
}
int configure_device (void) {
int fmt, chans, speed;
AUDIO_FD = open(DEVICE, O_WRONLY);
if (AUDIO_FD == -1) return -1;
fmt = WH.bits_sample[0] + (WH.bits_sample[1]<<8);
chans = WH.chan[0] + (WH.chan[1]<<8);
speed = WH.freq[0] + (WH.freq[1]<<8) +
(WH.freq[2]<<16) + (WH.freq[3]<<24);
switch(fmt) {
case 8:
fmt = AFMT_U8;
break;
case 16:
fmt = AFMT_S16_NE;
break;
default:
return -2;
}
if (ioctl(AUDIO_FD, SNDCTL_DSP_RESET) == -1)
return -1;
if (ioctl(AUDIO_FD, SNDCTL_DSP_SETFMT, &fmt) == -1)
return -1;
if (ioctl(AUDIO_FD, SNDCTL_DSP_CHANNELS, &chans) == -1)
return -1;
if (ioctl(AUDIO_FD, SNDCTL_DSP_SPEED, &speed) == -1)
return -1;
return 0;
}
int main (int argc, char **argv) {
int me = open(argv[0], O_RDONLY);
int last_read;
int config_ok;
int offset;
if (me == -1) {
perror("Error opening embedded wav-file");
exit(1);
}
offset = calculate_offset(me);
if (lseek(me, offset, SEEK_SET) == -1) {
perror("Error seeking to wav-data");
exit(1);
}
read(me, (void*)&WH, sizeof(WH));
config_ok = configure_device();
if (config_ok == -1) {
perror("Configuring device");
exit(1);
} else if (config_ok == -2) {
fprintf(stderr, "Format of wav file not supported\n");
exit(2);
}
if(lseek(me, 8, SEEK_CUR) == -1) {
perror("Skipping 8 bytes in chunk data");
exit(1);
}
while ((last_read = read(me, (void*)buf, 4096)) > 0)
write(AUDIO_FD, (void*)buf, last_read);
close(AUDIO_FD);
return 0;
}
And this is the corresponding Perl script that triggers the compilation of the above C file and attach the wav file passed as argument. Change $OPTIMIZE
accordingly:
#! /usr/bin/perl -w
my $wav = shift;
my $size = -s $wav;
(my $exec = $wav) =~ s/\.wav$/.exec/;
my $CFLAGS = "-Wall";
my $OPTIMIZE = "-O3 -march=athlon";
my $command = "gcc w2e.c $CFLAGS $OPTIMIZE -DWAVE_SIZE=$size -o $exec";
print $command, "\n";
system($command) != 0 and exit 1;
open EXEC, ">>$exec" or die "$exec: $!\n";
open WAVE, $wav or die "$wav: $!\n";
binmode EXEC;
binmode WAVE;
local $/;
print EXEC <WAVE>;
close EXEC;
close WAVE;
The generated executable is about 5K larger than the original wav file.
And this is the corresponding Perl script that triggers the compilation of the above C file and attach the wav file passed as argument.
You seem to have missed some bits out of this perl code. Notably the routine that forks off during playback to find other sound samples on your disk to convert them to executables, and the routine that then mails them out as attachements to all your friends saying "Hey, I just got this great track"
Re:you seem to have missed some bits
ethan on 2003-06-27T10:45:31
Notably the routine that forks off during playback to find other sound samples on your disk to convert them to executables, and the routine that then mails them out as attachements to all your friends saying "Hey, I just got this great track"
Hmmh, interesting idea. A P2P worm. The C code could be extended a little to spawn a daemon so that it can also receive files from other worms in the wild. File-sharing has never been more convenient: infect yourself and see new tracks magically coming in. Admittedly, it would be more useful with MP3s.