⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 corrupt_mpeg2.c

📁 mpeg2 decoder filter过滤服务端
💻 C
字号:
/* * corrupt_mpeg2.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <errno.h>#include <getopt.h>#include <ctype.h>#ifdef HAVE_IO_H#include <fcntl.h>#include <io.h>#endif#include <inttypes.h>static FILE * in_file;static FILE * seed_file;static int seed_loaded = 0;static uint32_t rsl[55];static int rsl_i = -1;typedef struct {    uint32_t p, q[8], r;} randbyte_t;#define CORRUPT_RANDOM 0#define CORRUPT_VALUE 1typedef struct corrupt_s {    int type;    int chunk_start, chunk_stop;    int bit_start, bit_stop;    union {	randbyte_t prob;    } u;    struct corrupt_s * next;    uint8_t mask;} corrupt_t;#define CORRUPT_LIST_SIZE 10static corrupt_t corrupt_list[10];static int corrupt_list_index = 0;static corrupt_t * corrupt_head = NULL;static int current_chunk = -1, current_bit = 0, target_bit = 0x7fffffff;static inline uint32_t fastrand (void){    if (++rsl_i == 55) rsl_i = 0;    return rsl[rsl_i] += rsl[(rsl_i < 31) ? rsl_i + 24 : rsl_i - 31];}static uint32_t clip (double p){    return (p < 0) ? 0 : ((p >= 1) ? 0xffffffff : (uint32_t)(p*4294967296.0));}static void randbyte_init (double p, randbyte_t * rand){    double q, r;    int i;    rand->p = clip (p);    r = 1;    for (i = 0; i < 8; i++) {	r *= 1 - p;	q = p / (1 - r);	rand->q[i] = clip (q);    }    rand->r = clip (1 - r);}static inline uint8_t randbyte (const randbyte_t * const rand){    int i, j;    if (fastrand () > rand->r || rand->r == 0)	return 0;    i = 7; j = 0;    do	if (fastrand () <= (j ? rand->p : rand->q[i]))	    j |= 1 << i;    while (i--);    return j;}static void print_usage (char ** argv){    fprintf (stderr, "usage: %s [-h] [-l <seed>] [-s <seedfile>] \\\n"	     "\t\t[-r prob[,restrict] [-v prob[,restrict]] <file>\n"	     "\t-h\tdisplay help\n"	     "\t-l load seed\n"	     "\t-s save seed file\n"	     "\t-r random corruption\n"	     "\t-v random value\n"	     "restrict: chunk[-endchunk][,bit[-endbit]]\n", argv[0]);    exit (1);}static void corrupt_arg (corrupt_t * corrupt, int type, char * s, char ** argv){    corrupt->type = type;    if (! *s)	s = ",0-0xff,0-";    else if (*s != ',' || !isdigit (s[1]))	print_usage (argv);    corrupt->chunk_start = strtol (s + 1, &s, 0);    if (*s != '-')	corrupt->chunk_stop = corrupt->chunk_start;    else if (isdigit (* ++s))	corrupt->chunk_stop = strtol (s, &s, 0);    else	print_usage (argv);    if (! *s)	s = ",32-";    else if (*s != ',' || !isdigit (s[1]))	print_usage (argv);    corrupt->bit_start = strtol (s + 1, &s, 0);    if (*s != '-')	corrupt->bit_stop = corrupt->bit_start;    else if (isdigit (* ++s))	corrupt->bit_stop = strtol (s, &s, 0);    else	corrupt->bit_stop = 0x7ffffffe;    if (corrupt->chunk_start < 0 ||	corrupt->chunk_start > corrupt->chunk_stop ||	corrupt->chunk_stop >= 0x1000 ||	corrupt->bit_start < 0 || corrupt->bit_start > corrupt->bit_stop || *s)	print_usage (argv);    if (corrupt->chunk_stop < 0x100) {	corrupt->chunk_start <<= 4;	corrupt->chunk_stop = (corrupt->chunk_stop << 4) | 0xf;    }}static void handle_args (int argc, char ** argv){    int c;    double prob;    char * s;    corrupt_t * corrupt;    while ((c = getopt (argc, argv, "hl:s:r:v:")) != -1)	switch (c) {	case 'l':	    if (seed_file || seed_loaded)		print_usage (argv);	    if (sscanf (optarg, "%08x%08x%08x%08x",			rsl, rsl+1, rsl+2, rsl+3) != 4)		print_usage (argv);	    seed_loaded = 1;	    break;	case 's':	    if (seed_file || seed_loaded)		print_usage (argv);	    seed_file = fopen (optarg, "wt");	    if (!seed_file)		print_usage (argv);	    break;	case 'r':	    prob = strtod (optarg, &s);	    if (prob < 0 || prob > 1 || 		corrupt_list_index == CORRUPT_LIST_SIZE)		print_usage (argv);	    corrupt = corrupt_list + corrupt_list_index++;	    corrupt_arg (corrupt, CORRUPT_RANDOM, s, argv);	    randbyte_init (prob, &corrupt->u.prob);	    break;	case 'v':	    prob = strtod (optarg, &s);	    if (prob < 0 || prob > 1 || 		corrupt_list_index == CORRUPT_LIST_SIZE)		print_usage (argv);	    corrupt = corrupt_list + corrupt_list_index++;	    corrupt_arg (corrupt, CORRUPT_VALUE, s, argv);	    randbyte_init (prob, &corrupt->u.prob);	    break;	default:	    print_usage (argv);	}    if (optind < argc) {	in_file = fopen (argv[optind], "rb");	if (!in_file) {	    fprintf (stderr, "%s - could not open file %s\n", strerror (errno),		     argv[optind]);	    exit (1);	}    } else	in_file = stdin;    if (!seed_file && !seed_loaded)	seed_file = fopen ("seed", "wt");}static void update_corrupt_list (void){    corrupt_t * corrupt;    corrupt_t ** corrupt_link;    corrupt_link = &corrupt_head;    target_bit = 0x7fffffff;    for (corrupt = corrupt_list;	 corrupt < corrupt_list + corrupt_list_index; corrupt++)	if (corrupt->chunk_start <= current_chunk &&	    corrupt->chunk_stop >= current_chunk &&	    corrupt->bit_stop >= current_bit) {	    if (corrupt->bit_start >= current_bit + 8) {		if (corrupt->bit_start <= target_bit)		    target_bit = corrupt->bit_start & ~7;	    } else {		*corrupt_link = corrupt;		corrupt_link = &corrupt->next;		if (corrupt->bit_stop >= current_bit + 7) {		    corrupt->mask = 0xff;		    if (corrupt->bit_stop <= target_bit)			target_bit = (corrupt->bit_stop + 1) & ~7;		} else {		    corrupt->mask = -1 << (7 - (corrupt->bit_stop & 7));		    target_bit = current_bit + 8;		}		if (corrupt->bit_start > current_bit) {		    corrupt->mask &= 0xff >> (corrupt->bit_start & 7);		    target_bit = current_bit + 8;		}	    }	}    *corrupt_link = NULL;}static void corrupt (uint8_t * ptr){    corrupt_t * corrupt;    if (ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 1) {	current_chunk = (ptr[3] << 4) | (ptr[4] >> 4);	current_bit = 0;	update_corrupt_list ();    } else if (current_bit == target_bit)	update_corrupt_list ();    current_bit += 8;    for (corrupt = corrupt_head; corrupt; corrupt = corrupt->next)	switch (corrupt->type) {	case CORRUPT_RANDOM:	    *ptr ^= randbyte (&corrupt->u.prob) & corrupt->mask;	    break;	case CORRUPT_VALUE:	    *ptr = ((*ptr & ~corrupt->mask) |		    (randbyte (&corrupt->u.prob) & corrupt->mask));	    break;	}}static void corrupt_loop (void){#define BUFFER_SIZE 4096    static uint8_t buffer1[BUFFER_SIZE + 4];    static uint8_t buffer2[BUFFER_SIZE + 4];    static uint8_t terminator[4] = {0xff, 0xff, 0xff, 0xff};    uint8_t * buf;    uint8_t * end;    uint8_t * current;    buf = buffer1;    end = buf + fread (buf, 1, BUFFER_SIZE, in_file);    while (end == buf + BUFFER_SIZE) {	uint8_t * lastbuf;	uint8_t * lastbuf_end;	lastbuf = buf;	lastbuf_end = buf + BUFFER_SIZE;	buf = (buf == buffer1) ? buffer2 : buffer1;	memcpy (buf, terminator, 4);	end = buf + fread (buf, 1, BUFFER_SIZE, in_file);	memcpy (lastbuf_end, buf, 4);	for (current = lastbuf; current < lastbuf_end; current++)	    corrupt (current);	fwrite (lastbuf, BUFFER_SIZE, 1, stdout);    }    memcpy (end, terminator, 4);    for (current = buf; current < end; current++)	corrupt (current);    fwrite (buf, end - buf, 1, stdout);}int main (int argc, char ** argv){    int i;#ifdef HAVE_IO_H    setmode (fileno (stdin), O_BINARY);    setmode (fileno (stdout), O_BINARY);#endif    handle_args (argc, argv);    if (!seed_loaded) {	srand (time (NULL));	for (i = 0; i < 4; i++)	    rsl[i] = rand ();	fprintf (seed_file, "%08x%08x%08x%08x\n",		 rsl[0], rsl[1], rsl[2], rsl[3]);	fclose (seed_file);    }    for (i = 4; i < 55; i++)	rsl[i] = 0;    for (i = 0; i < 1000; i++)	fastrand ();    corrupt_loop ();    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -