From cef46fa34ddf94cc6b2e1ba3c60f5ca3a4b1023f Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 12 Apr 2023 23:51:47 -0400 Subject: [PATCH] add wav, bitmap, and generic extractor --- bitmapdump.c | 60 ++++++++++++++++++++++++++++++++++++++ extract.c | 28 ++++++++++++++++++ wavdump.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 bitmapdump.c create mode 100644 extract.c create mode 100644 wavdump.c diff --git a/bitmapdump.c b/bitmapdump.c new file mode 100644 index 0000000..9d7c636 --- /dev/null +++ b/bitmapdump.c @@ -0,0 +1,60 @@ +#include +#include +#include + +typedef struct bmp_header bmp_header; +struct bmp_header { + uint8_t id[2]; + uint8_t size[4]; + uint8_t r1[2]; + uint8_t r2[2]; + uint8_t offset[4]; +}; + +int32_t little_endian(uint8_t bytes[4]) { + int32_t le = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); + return le; +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "extractor [usage]: input_file"); + return EXIT_FAILURE; + } + bmp_header header; + char search; + int count = 0; + char out_name[128] = {0}; + + char *in = argv[1]; + FILE *fin = fopen(in, "r"); + fseek(fin, 0, SEEK_SET); + while (fread(&search, sizeof(char), 1, fin) > 0) { + if (search != 'B') + continue; + if (fread(&search, sizeof(char), 1, fin) <= 0) + continue; + if (search != 'M') + continue; + fpos_t pos; + fseek(fin, -2 * sizeof(char), SEEK_CUR); + fgetpos(fin, &pos); + fread(&header, sizeof(bmp_header), 1, fin); + if (header.r1[0] == 0 && header.r1[1] == 0 && header.r2[0] == 0 && + header.r2[1] == 0) { + fseek(fin, pos, SEEK_SET); + int32_t size = little_endian(header.size); + char *data = (char *)malloc((size + 1) * sizeof(char)); + fread(data, sizeof(char), size, fin); + data[size + 1] = 0; + snprintf(out_name, sizeof out_name, "%s_%d.bmp", in, ++count); + FILE *fout = fopen(out_name, "w"); + fwrite(data, sizeof(char), size, fout); + fclose(fout); + free(data); + } + } + + fclose(fin); + return EXIT_SUCCESS; +} diff --git a/extract.c b/extract.c new file mode 100644 index 0000000..1767e36 --- /dev/null +++ b/extract.c @@ -0,0 +1,28 @@ +#include +#include + +int +main(int argc, char** argv) +{ + if (argc != 5) + { + fprintf(stderr, "extractor [usage]: input_file output_file size offset"); + return EXIT_FAILURE; + } + + char* in = argv[1]; + char* out = argv[2]; + int size = atoi(argv[3]); + int offset = atoi(argv[4]); + char* data = (char*)malloc(size + 1 * sizeof(char)); + FILE* fin = fopen(in, "r"); + fseek(fin, offset, SEEK_SET); + fread(data, sizeof(char), size, fin); + data[size + 1] = 0; + fclose(fin); + FILE* fout = fopen(out, "w"); + fwrite(data, sizeof(char), size, fout); + fclose(fout); + free(data); + return EXIT_SUCCESS; +} diff --git a/wavdump.c b/wavdump.c new file mode 100644 index 0000000..ee90e23 --- /dev/null +++ b/wavdump.c @@ -0,0 +1,81 @@ +#include +#include +#include + +typedef struct wav_header wav_header; +struct wav_header { + uint8_t id[4]; + uint8_t size[4]; + char wave[4]; + char fmt[4]; + uint8_t fmt_data_len[4]; + uint8_t type[2]; + uint8_t channels[2]; + uint8_t sample_rate[4]; + uint8_t total_rate[4]; + uint8_t audio_type[2]; + uint8_t bbs[2]; + char data_str[4]; + uint8_t data_size[4]; +}; + +int32_t little_endian(uint8_t bytes[4]) { + int32_t le = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); + return le; +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "extractor [usage]: input_file"); + return EXIT_FAILURE; + } + wav_header header; + char search; + int count = 0; + char out_name[128] = {0}; + + char *in = argv[1]; + FILE *fin = fopen(in, "r"); + fseek(fin, 0, SEEK_SET); + while (fread(&search, sizeof(char), 1, fin) > 0) { + if (search != 'R') + continue; + + if (fread(&search, sizeof(char), 1, fin) <= 0) + continue; + + if (search != 'I') + continue; + + if (fread(&search, sizeof(char), 1, fin) <= 0) + continue; + + if (search != 'F') + continue; + + if (fread(&search, sizeof(char), 1, fin) <= 0) + continue; + + if (search != 'F') + continue; + + fpos_t pos; + fseek(fin, -4 * sizeof(char), SEEK_CUR); + fgetpos(fin, &pos); + fread(&header, sizeof(wav_header), 1, fin); + + fseek(fin, pos, SEEK_SET); + int32_t size = little_endian(header.data_size); + char *data = (char *)malloc((size + 1) * sizeof(char)); + fread(data, sizeof(char), size, fin); + data[size + 1] = 0; + snprintf(out_name, sizeof out_name, "%s_%d.wav", in, ++count); + FILE *fout = fopen(out_name, "w"); + fwrite(data, sizeof(char), size, fout); + fclose(fout); + free(data); + } + + fclose(fin); + return EXIT_SUCCESS; +}