Anri-chan/Source/mp4nerf.c

From SDA Knowledge Base

< Anri-chan‎ | Source
Revision as of 10:49, 18 July 2007 by B'man (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

/* for disabling audio commentary tracks in MP4 streams author: DJ Grenola date: 17 July 2007 license: none (public domain) target: win32 (MINGW), recommend using the free IDE from bloodshed.net version: beta 0.1 */ #define LARGE_FILE_SUPPORT #ifdef LARGE_FILE_SUPPORT /* not necessary for mingw/win32 but will probably become so if we start trying to compile it on linux and friends */ #define _FILE_OFFSET_BITS 64 #endif #include <stdio.h> #include <stdlib.h> #include <string.h> /* #define VERBOSE */ #define CHECKBYTES_LEN 8 #define CHECKBYTES { 0x74, 0x6B, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01 } #define REPBYTES { 0x74, 0x6B, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00 } #define NUM_TO_SKIP 2 #define BUFSIZE 1024*1024 #ifdef LARGE_FILE_SUPPORT #define FOPEN fopen64 #define FSEEK fseeko64 #define FTELL ftello64 #define OFF_T off64_t #else #define FOPEN fopen #define FSEEK fseek #define FTELL ftell #define OFF_T int #endif typedef long long int s64; void usage(char *argv0); unsigned char checkbytes[CHECKBYTES_LEN]=CHECKBYTES; unsigned char repbytes[CHECKBYTES_LEN]=REPBYTES; unsigned char buffer[BUFSIZE]; int main (int argc, char **argv) { FILE *f; unsigned int matches=0; unsigned int bufstart=0; unsigned int bytes_to_read; unsigned int error=0; s64 br; OFF_T pos=0,tmp64; char *fname=NULL; printf ("MP4 audio track disabler\n"); printf ("beta 0.1, DJ Grenola\n\n"); printf ("This software comes with no warranty.\n\n"); if ((argc!=2 && argc!=3) || (argc==3 && strcmp(argv[1],"-x"))) { usage(argv[0]); return 0; } fname=argv[argc-1]; if ((f=FOPEN(fname,"r+b"))==NULL) { printf ("[-] Failed to open file \"%s\".\n", fname); return 1; } printf ("[+] Using %u KiB chunks.\n", BUFSIZE/1024); printf ("[+] Scanning file \"%s\".\n", fname); while (~0) { int i; bytes_to_read=BUFSIZE-bufstart; br=fread(buffer+bufstart,1,bytes_to_read,f); pos+=br; #ifdef VERBOSE printf ("[+] Read %llu bytes.\n", pos); #endif for (i=0;i<br+bufstart;i++) { if (!memcmp(checkbytes,buffer+i,CHECKBYTES_LEN)) { matches++; printf ("[+] Match at offset 0x%0llx", pos-br+(i-bufstart)); if (argc==2) /* dummy mode */ printf (", no action taken.\n"); else { if (matches<=NUM_TO_SKIP) printf (", ignored.\n"); else { printf (", attempting overwrite ...\n"); if (matches>NUM_TO_SKIP) { /* FIXME: this is kind of dodgy because I don't know if off64_t can be relied upon to be signed ... it works now, but in the future ? */ tmp64=-br+(i-bufstart); if (FSEEK(f,pos+tmp64,SEEK_SET)==-1) { error=3; printf ("[-] Error seeking to offset.\n"); goto lbl_end; } if (fwrite(repbytes,1,CHECKBYTES_LEN,f) != CHECKBYTES_LEN) { error=4; printf ("[-] Error writing replacement string.\n"); goto lbl_end; } /* put file pointer back (if necessary) */ if (br==bytes_to_read) { if (FSEEK(f,pos,SEEK_SET)==-1) { error=5; printf ("[-] Error seeking to original position.\n"); goto lbl_end; } } printf ("[+] Replaced successfully.\n"); } } } } } bufstart=CHECKBYTES_LEN-1; memmove(buffer,buffer+(BUFSIZE-(CHECKBYTES_LEN-1)),CHECKBYTES_LEN-1); if (br!=bytes_to_read) break; } lbl_end: if (ferror(f) || error) { /* FIXME: actually report some sort of useful error instead */ printf ("[-] Erk. Something went wrong.\n"); fclose(f); return error?error:2; } fclose(f); return 0; } void usage(char *argv0) { printf ("Usage: %s [-x] <MP4 file>\n\n", argv0); printf ("By default, the file is scanned and no changes are made.\n"); printf ("Use the -x switch to force changes to the file.\n"); }

Personal tools