Skip to content

Instantly share code, notes, and snippets.

@rpedde
Last active November 20, 2015 17:01
Show Gist options
  • Save rpedde/b4c45fae10ec4960f77c to your computer and use it in GitHub Desktop.
Save rpedde/b4c45fae10ec4960f77c to your computer and use it in GitHub Desktop.
#include <stddef.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#pragma pack(1)
typedef struct t_ext_sb {
uint32_t s_inodes_count;
uint32_t s_blocks_count;
uint32_t s_r_blocks_count;
uint32_t s_free_blocks_count;
uint32_t s_free_inodes_count;
uint32_t s_first_data_block;
uint32_t s_log_block_size;
uint32_t s_log_log_frag_size;
uint32_t s_blocks_per_group;
uint32_t s_frags_per_group;
uint32_t s_inodes_per_group;
uint32_t s_mtime;
uint32_t s_wtime;
uint16_t s_mnt_count;
uint16_t s_max_mnt_count;
uint16_t s_magic;
uint16_t s_state;
uint16_t s_errors;
uint16_t s_minor_rev_level;
uint32_t s_lastcheck;
uint32_t s_checkinterval;
uint32_t s_creator_os;
uint32_t s_rev_level;
uint16_t s_def_resuid;
uint16_t s_def_resgid;
// EXT2_DYNAMIC_REV
uint32_t s_first_ino;
uint16_t s_inode_size;
uint16_t s_block_group_nr;
uint32_t s_feature_compat;
uint32_t s_feature_incompat;
uint32_t s_feature_ro_compat;
uint8_t s_uuid[16];
uint8_t s_volume_name[16];
uint8_t s_last_mounted[64];
uint32_t s_algo_bitmap;
} t_ext_sb;
void splitfile(FILE *in, long offset, char *name) {
FILE *out;
uint8_t buffer[1024];
size_t bytes_read;
if(!(out = fopen(name, "wb"))) {
perror("fopen");
exit(1);
}
printf("Seeking to %ld\n", offset);
if(fseek(in, offset, SEEK_SET) < 0) {
perror("fseek");
exit(1);
}
printf("Copying fs data\n");
while((bytes_read = fread(buffer, 1, sizeof(buffer), in)) > 0) {
fwrite(buffer, 1, bytes_read, out);
}
fclose(out);
}
int main(int argc, char **argv) {
FILE *input;
long current_offset=0;
uint8_t buffer[2048];
size_t read;
uint8_t *ptr;
uint16_t *ui16;
uint32_t *ui32;
t_ext_sb *superblock;
int is_fs;
printf("Offset s_magic: %ld\n", (long) offsetof(struct t_ext_sb, s_magic));
printf("Offset s_algo_bitmap: %ld\n", (long) offsetof(struct t_ext_sb, s_algo_bitmap));
if(argc != 2) {
fprintf(stderr, "Usage: findextfs <file>\n");
exit(1);
}
if(!(input = fopen(argv[1], "rb"))) {
perror("fopen");
exit(1);
}
while((read = fread(buffer, 1, sizeof(buffer), input)) > 0) {
ptr = &buffer[0];
while((ptr - buffer) < read) {
/* if(*ptr == 0x53) */
/* printf("Next: %02x at %08lx\n", *(ptr + 1), current_offset); */
if((*ptr == 0x53) && (*(ptr + 1) == 0xef)) { // && (current_offset > 0x438)) {
/* read-read the block here */
current_offset -= 0x438;
if(fseek(input, current_offset, SEEK_SET) < 0) {
perror("fseek");
exit(1);
}
read = fread(buffer, 1, sizeof(buffer), input);
is_fs = 1;
// pretend this is a fs
superblock = (t_ext_sb *)&buffer[1024];
if(superblock->s_magic != 0xef53) {
printf("alignment problem\n");
exit(1);
}
if(superblock->s_r_blocks_count >= superblock->s_blocks_count)
is_fs = 0;
if(superblock->s_inodes_count <= superblock->s_free_inodes_count)
is_fs = 0;
if(superblock->s_blocks_count <= superblock->s_free_blocks_count)
is_fs = 0;
if(superblock->s_state > 2)
is_fs = 0;
if(superblock->s_errors > 3)
is_fs = 0;
if(superblock->s_rev_level > 1)
is_fs = 0;
if(superblock->s_creator_os > 4)
is_fs = 0;
if(superblock->s_log_block_size > 3)
is_fs = 0;
if(is_fs) {
splitfile(input, current_offset, "fs.img");
printf("Found and split\n");
exit(0);
}
ptr = buffer + 0x439;
current_offset += 0x439;
} else {
ptr++;
current_offset++;
}
}
if (read == sizeof(buffer)) {
fseek(input, current_offset - 1, SEEK_SET);
current_offset -= 1;
}
}
fclose(input);
printf("Done: %ld\n", current_offset);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment