Last active
November 20, 2015 17:01
-
-
Save rpedde/b4c45fae10ec4960f77c to your computer and use it in GitHub Desktop.
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 <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