Created
September 18, 2016 14:07
-
-
Save Siguza/9261e7ece1e1ca1e2b2f3bf87749af10 to your computer and use it in GitHub Desktop.
Img3 extractor
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
/* | |
* img3ex.c - Extract Img3 files from any binary blob, e.g. a /dev/disk* dump. | |
* | |
* Placed in the Public Domain, do whatever you want with it. No warranty of any kind. | |
* | |
* Compile with: cc -o img3ex -std=c11 -Wall -O3 img3ex.c | |
*/ | |
#include <errno.h> // errno | |
#include <fcntl.h> // open, O_RDONLY | |
#include <stddef.h> // size_t | |
#include <stdint.h> // uint32_t | |
#include <stdio.h> // FILE, fopen, fwrite, fclose, fprintf, snprintf | |
#include <stdlib.h> // exit | |
#include <string.h> // memmem, strerror | |
#include <unistd.h> // close | |
#include <sys/mman.h> // mmap, munmap, MAP_FAILED | |
#include <sys/stat.h> // fstat, struct stat | |
#define ERROR(code, str, args...) \ | |
{ \ | |
fprintf(stderr, "[!] " str " [" __FILE__ ":%u]\n", ##args, __LINE__); \ | |
exit(code); \ | |
} | |
typedef struct | |
{ | |
char d; | |
char c; | |
char b; | |
char a; | |
} ascii_le_t; | |
typedef struct | |
{ | |
int fd; | |
size_t len; | |
void *mem; | |
} filemap_t; | |
void mapFile(filemap_t *map, const char *file) | |
{ | |
int fd = open(file, O_RDONLY); | |
if(fd == -1) | |
{ | |
ERROR(4, "Failed to open %s for reading: %s", file, strerror(errno)); | |
} | |
struct stat s; | |
if(fstat(fd, &s) != 0) | |
{ | |
ERROR(4, "Failed to stat() %s: %s", file, strerror(errno)); | |
} | |
size_t len = s.st_size; | |
void *mem = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); | |
if(mem == MAP_FAILED) | |
{ | |
ERROR(errno == ENOMEM ? 3 : 4, "Failed to map %s to memory: %s", file, strerror(errno)); | |
} | |
map->fd = fd; | |
map->len = len; | |
map->mem = mem; | |
} | |
void unmapFile(filemap_t *map) | |
{ | |
if(munmap(map->mem, map->len) != 0) | |
{ | |
ERROR(3, "munmap() failed: %s", strerror(errno)); | |
} | |
if(close(map->fd) != 0) | |
{ | |
ERROR(4, "close() failed: %s", strerror(errno)); | |
} | |
} | |
int main(int argc, const char **argv) | |
{ | |
if(argc < 2) | |
{ | |
ERROR(1, "Too few arguments"); | |
} | |
filemap_t map; | |
mapFile(&map, argv[1]); | |
char *ptr = map.mem, | |
*end = ptr + map.len; | |
while(ptr < end) | |
{ | |
ptr = memmem(ptr, end - ptr, "3gmI", 4); | |
if(ptr == NULL) | |
{ | |
break; | |
} | |
uint32_t len = ((uint32_t*)ptr)[1]; | |
ascii_le_t *id = (ascii_le_t*)&((uint32_t*)ptr)[4]; | |
char name[21]; | |
snprintf(name, 21, "0x%08x.%c%c%c%c.img3", (uint32_t)(ptr - (char*)map.mem), id->a, id->b, id->c, id->d); | |
FILE *f = fopen(name, "wbx"); | |
if(f == NULL) | |
{ | |
ERROR(3, "IO error: %s", strerror(errno)); | |
} | |
fwrite(ptr, 1, len, f); | |
fclose(f); | |
fprintf(stderr, "Extracted %s\n", name); | |
ptr += len; | |
} | |
unmapFile(&map); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment