Created
October 20, 2019 06:29
-
-
Save hikalium/7567d487d32af63ec0f4bc68e5a354cb to your computer and use it in GitHub Desktop.
AVI file reader for SECCON 2019 Online CTF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
char buf[1024 * 1024 * 4]; | |
typedef struct _avimainheader { | |
uint32_t fcc; | |
uint32_t cb; | |
uint32_t dwMicroSecPerFrame; | |
uint32_t dwMaxBytesPerSec; | |
uint32_t dwPaddingGranularity; | |
uint32_t dwFlags; | |
uint32_t dwTotalFrames; | |
uint32_t dwInitialFrames; | |
uint32_t dwStreams; | |
uint32_t dwSuggestedBufferSize; | |
uint32_t dwWidth; | |
uint32_t dwHeight; | |
uint32_t dwReserved[4]; | |
} AVIMAINHEADER; | |
typedef struct { | |
uint32_t ckid; | |
uint32_t dwFlags; | |
uint32_t dwChunkOffset; | |
uint32_t dwChunkLength; | |
} AVIINDEXENTRY; | |
typedef struct { | |
uint32_t CompressedBMHeight; | |
uint32_t CompressedBMWidth; | |
uint32_t ValidBMHeight; | |
uint32_t ValidBMWidth; | |
uint32_t ValidBMXOffset; | |
uint32_t ValidBMYOffset; | |
uint32_t VideoXOffsetInT; | |
uint32_t VideoYValidStartLine; | |
} VIDEO_FIELD_DESC; | |
typedef struct { | |
uint32_t VideoFormatToken; | |
uint32_t VideoStandard; | |
uint32_t dwVerticalRefreshRate; | |
uint32_t dwHTotalInT; | |
uint32_t dwVTotalInLines; | |
uint32_t dwFrameAspectRatio; | |
uint32_t dwFrameWidthInPixels; | |
uint32_t dwFrameHeightInLines; | |
uint32_t nbFieldPerFrame; | |
VIDEO_FIELD_DESC FieldInfo[]; | |
} VideoPropHeader; | |
void pad(int depth) { | |
for (int i = 0; i < depth * 2; i++) putchar(' '); | |
} | |
void parse(int idx, int chunk_size, int depth) { | |
int i = idx; | |
while (i < chunk_size) { | |
i = (i + 1) & ~1; | |
pad(depth); | |
printf("@+0x%06X: %.4s\n", i, &buf[i]); | |
int size = *(uint32_t *)&buf[i + 4]; | |
pad(depth); | |
printf(" size = %d\n", size); | |
if (strncmp(&buf[i], "avih", 4) == 0) { | |
AVIMAINHEADER *avih = (AVIMAINHEADER *)&buf[i]; | |
pad(depth); | |
printf(" dwFlags=0x%X\n", avih->dwFlags); | |
pad(depth); | |
printf(" dwTotalFrames=%d\n", avih->dwTotalFrames); | |
pad(depth); | |
printf(" w=%d\n", avih->dwWidth); | |
pad(depth); | |
printf(" h=%d\n", avih->dwHeight); | |
} | |
if (strncmp(&buf[i], "LIST", 4) == 0) { | |
pad(depth); | |
printf(" %.4s\n", &buf[i + 8]); | |
parse(i + 12, size - 4, depth + 1); | |
} | |
if (strncmp(&buf[i], "RIFF", 4) == 0) { | |
pad(depth); | |
printf(" %.4s\n", &buf[i + 8]); | |
parse(i + 12, size - 4, depth + 1); | |
} | |
if (strncmp(&buf[i], "vprp", 4) == 0) { | |
VideoPropHeader *e = (VideoPropHeader *)&buf[i + 8]; | |
pad(depth); | |
printf(" VideoFormatToken: 0x%08X\n", e->VideoFormatToken); | |
printf(" VideoStandard: 0x%08X\n", e->VideoStandard); | |
printf(" dwVerticalRefreshRate: 0x%08X\n", e->dwVerticalRefreshRate); | |
printf(" dwHTotalInT: 0x%08X\n", e->dwHTotalInT); | |
printf(" dwVTotalInLines: 0x%08X\n", e->dwVTotalInLines); | |
printf(" dwFrameAspectRatio: 0x%08X\n", e->dwFrameAspectRatio); | |
printf(" dwFrameHeightInLines: 0x%08X\n", e->dwFrameHeightInLines); | |
printf(" nbFieldPerFrame: 0x%08X\n", e->nbFieldPerFrame); | |
} | |
if (strncmp(&buf[i], "00dc", 4) == 0) { | |
pad(depth); | |
int k = 0; | |
for (; k < 8; k++) { | |
printf(" %02X", (uint8_t)buf[i + 8 + k]); | |
} | |
for (; k < size; k++) { | |
if (k % 32 == 8) { | |
putchar('\n'); | |
pad(depth); | |
} | |
printf(" %02X", (uint8_t)buf[i + 8 + k]); | |
} | |
putchar('\n'); | |
} | |
if (strncmp(&buf[i], "idx1", 4) == 0) { | |
AVIINDEXENTRY *e = (AVIINDEXENTRY *)&buf[i + 8]; | |
for (int k = 0; k < size / sizeof(AVIINDEXENTRY); k++) { | |
pad(depth); | |
printf(" %3d: (%8X) +0x%8X %8d\n", k, e[k].dwFlags, e[k].dwChunkOffset, | |
e[k].dwChunkLength); | |
} | |
} | |
i += 8 + size; | |
} | |
} | |
int main(int argc, char *argv[]) { | |
FILE *fp = fopen(argv[1], "rb"); | |
if (!fp) return 1; | |
int file_size = fread(buf, 1, sizeof(buf), fp); | |
printf("file size: %d\n", file_size); | |
int i = 0; | |
while (buf[i] == 0) i++; | |
parse(i, file_size - i, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment