Skip to content

Instantly share code, notes, and snippets.

@Siguza
Created September 18, 2016 14:07
Show Gist options
  • Save Siguza/9261e7ece1e1ca1e2b2f3bf87749af10 to your computer and use it in GitHub Desktop.
Save Siguza/9261e7ece1e1ca1e2b2f3bf87749af10 to your computer and use it in GitHub Desktop.
Img3 extractor
/*
* 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