main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
__int64 v4; // rbx
__int64 v5; // rax
__int64 v6; // rax
__int64 v7; // rax
__int64 v8; // rax
__int64 v9; // rax
__int64 v10; // rbx
__int64 v11; // rax
__int64 v12; // rax
__int64 v13; // rbx
__int64 v14; // rbp
__int64 v15; // rax
__int64 v16; // rbx
__int64 v17; // rax
__int64 v18; // rbx
__int64 v19; // rax
__int64 v20; // rbx
__int64 v21; // r13
__int64 v22; // rax
__int64 v23; // rbx
__int64 v24; // rax
__int64 v25; // rbx
__int64 v26; // r12
__int64 v27; // rax
__int64 v28; // rbx
__int64 v29; // rax
__int64 v30; // rbx
__int64 v31; // rax
__int64 v32; // r14
__int64 v33; // rbx
__int64 v34; // rax
__int64 v35; // r14
__int64 v36; // rax
__int64 v37; // rax
__int64 v38; // rax
__int64 v39; // rax
__int64 v40; // rax
__int64 v41; // rax
__int64 v42; // rax
__int64 v43; // rax
__int64 v44; // rbx
__int64 v45; // rax
__int64 v46; // rbx
__int64 v47; // rax
__int64 v48; // rbx
__int64 v49; // rax
const char **v51; // [rsp+0h] [rbp-68h] BYREF
int v52; // [rsp+Ch] [rbp-5Ch] BYREF
char v53[88]; // [rsp+10h] [rbp-58h] BYREF

v52 = argc;
v51 = argv;
gtk_init(&v52, &v51, envp);
v3 = gtk_window_new(0LL);
wMain[0] = v3;
v4 = gtk_window_get_type();
v5 = g_type_check_instance_cast(v3, v4);
gtk_window_set_position(v5, 0LL);
v6 = g_type_check_instance_cast(wMain[0], v4);
gtk_window_set_default_size(v6, 1024LL, 600LL);
v7 = g_type_check_instance_cast(wMain[0], v4);
gtk_window_set_title(v7, "ext3Viewer GUI");
v8 = gdk_pixbuf_new_from_file("/usr/local/share/ext3Viewer//img/icon.png", 0LL);
wMain[1] = v8;
gtk_window_set_default_icon(v8);
g_object_unref(wMain[1]);
v9 = g_type_check_instance_cast(wMain[0], 80LL);
g_signal_connect_data(v9, "destroy", &onQuit, 0LL, 0LL, 0LL);
v10 = gtk_vbox_new(0LL, 0LL);
wMain[3] = v10;
v11 = gtk_container_get_type();
v12 = g_type_check_instance_cast(wMain[0], v11);
gtk_container_add(v12, v10);
v13 = createMenu(wMain[0]);
wMain[5] = v13;
v14 = gtk_box_get_type();
v15 = g_type_check_instance_cast(wMain[3], v14);
gtk_box_pack_start(v15, v13, 0LL, 0LL, 0LL);
v16 = gtk_hseparator_new();
wMain[8] = v16;
v17 = g_type_check_instance_cast(wMain[3], v14);
gtk_box_pack_start(v17, v16, 0LL, 0LL, 0LL);
v18 = create_search(v53);
wMain[11] = v18;
v19 = g_type_check_instance_cast(wMain[3], v14);
gtk_box_pack_start(v19, v18, 0LL, 0LL, 0LL);
v20 = gtk_hpaned_new();
wMain[2] = v20;
v21 = gtk_paned_get_type();
v22 = g_type_check_instance_cast(v20, v21);
gtk_paned_set_position(v22, 470LL);
v23 = wMain[2];
v24 = g_type_check_instance_cast(wMain[3], v14);
gtk_box_pack_start(v24, v23, 1LL, 1LL, 0LL);
*(&centre + 2) = create_tree();
v25 = gtk_scrolled_window_new(0LL, 0LL);
*(&centre + 1) = v25;
v26 = gtk_scrolled_window_get_type();
v27 = g_type_check_instance_cast(v25, v26);
gtk_scrolled_window_set_policy(v27, 1LL, 1LL);
v28 = *(&centre + 2);
v29 = g_type_check_instance_cast(*(&centre + 1), v26);
gtk_scrolled_window_add_with_viewport(v29, v28);
v30 = *(&centre + 1);
v31 = g_type_check_instance_cast(wMain[2], v21);
gtk_paned_add1(v31, v30);
v32 = gtk_text_view_new();
centre = v32;
v33 = gtk_text_view_get_type();
v34 = g_type_check_instance_cast(v32, v33);
v35 = gtk_text_view_get_buffer(v34);
v36 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_wrap_mode(v36, 2LL);
v37 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_editable(v37, 0LL);
v38 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_cursor_visible(v38, 0LL);
v39 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_pixels_below_lines(v39, 5LL);
v40 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_left_margin(v40, 10LL);
v41 = g_type_check_instance_cast(centre, v33);
gtk_text_view_set_right_margin(v41, 10LL);
init_tags(v35);
v42 = gtk_scrolled_window_new(0LL, 0LL);
*(&centre + 1) = v42;
v43 = g_type_check_instance_cast(v42, v26);
gtk_scrolled_window_set_policy(v43, 2LL, 1LL);
v44 = centre;
v45 = g_type_check_instance_cast(*(&centre + 1), v26);
gtk_scrolled_window_add_with_viewport(v45, v44);
v46 = *(&centre + 1);
v47 = g_type_check_instance_cast(wMain[2], v21);
gtk_paned_add2(v47, v46);
v48 = gtk_statusbar_new();
wMain[10] = v48;
v49 = g_type_check_instance_cast(wMain[3], v14);
gtk_box_pack_start(v49, v48, 0LL, 0LL, 0LL);
gtk_widget_show_all(wMain[0]);
unk_828[1] = 0;
gtk_main();
return 0;
}

original_code:
int main(int argc, char *argv[]) {
  struct ext3_super_block sb;
  struct ext3_inode i;
  struct ext3_group_desc gd;
  struct journal_superblock_s jsb;
  char *inodebitmap,*datablockbitmap;
  char c;
  char *block;
  int cc;
  int block_size;
  __u16 gd_num;
  __u32 inode_num;
  __u32 block_num;
  __u16 group_count;
  int fd;
  char pattern[255];
  long long int ret;
  ;
  ;
  if ( argc == 2 && !strcmp( argv[1], "-help" ) ) {
    printf("Usage: %s <FILESYSTEM> OPTION ARG1 [ ARG2 ... ]\n\n Dumps and interprets informations about ext3 filesystems.\n (in all this help, is the ext3 filesystem. ex: /dev/hda2)\n\n <FILESYSTEM> is the ext3 filesystem to examinate, could be a device or\n                 a image file. eg: /dev/hda2, /dev/sda3, ./image.ext3\n\n OPTION and ARGS are shown below :\n\t-stats [ <block num> <block size> ]\n\t                           info about the superblock and the group\n\t                           descriptors. if you specify a block number\n\t                           and a block size, it will read an alternate \n\t                           superblock. see -backups\n\n\t-stat  <inode num>         show the inode structure contents\n\t-bpoint  <block num>       display a block as a pointer of blocks\n\t-printgd  <group num>      dump the group_desc structure of a group\n\n\n\t-tree  <inode num>         show the form of an inode block allocation\n\t-imap  <group_desc num>    print the inode bitmap as an array\n\t-bmap  <group_desc num>    print the block bitmap as an array\n\t-ffi                       find the first free inode thanks to the\n\t                           bitmap\n\t-ffb                       find the first free block\n\n\n\t-cat  <inode num>  [ -x ]  dump the contents of a file.(read all the\n\t                           blocks). -x for hexa.\n\t-bcat  <block num> [ -x ]  dump the contents of a block.(read just one\n\t                           block) -x for hexa.\n\n\n\t-ls  <inode num>           print the directory entries of an inode.\n\t                           the root has inode number 2.\n\n\t-find  <inode_dir starting number> <regex pattern>\n\t                           find files recursively from a given directory\n\t                           that matches a regex pattern. for / type 2\n\n\t-iname  <inode num>        find all the files that have the given inode\n\n\t-backups                   calculate where the copies of the\n\t                           superblock are\n\n\n\t-jbd                       dump the journal contents.\n\n\n\t-help                      display this help. see also the man page\n\n See the man page for more details.\n\next3Viewer 1.0.2 GNU public license\nCopyright (C) 2013 Laurent Sebag\nCopyright (C) 2007 Laurent Sebag & Nathan Periana\ne2view (2003) Julien Poitrat, original idea\n", argv[0]);
    return 0;
  }
  else if ( argc < 3 ) {
    printf("Usage: %s <fd>  \n               [ -stats   | -stat | -printgd | -imap | -bmap | -ffi   |\n                 -ffb     | -cat  | -bcat    | -ls   | -find | -iname |\n                 -backups | -jbd  | -bpoint  | -tree ]\n'%s -help' for help.\nversion: ext3Viewer 1.0.2\n", argv[0], argv[0]);
    return 1;
  }
  else if ( !strcmp( argv[2], "-stats" ) ) {
    if ( argc != 5 && argc != 3 ) {
      printf("usage %s <filesystem> -stats [ <block number> <block size> ]\n",
          argv[0]);
      return 1;
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    if ( argc == 3 ) {
      ret = read_superblock( fd, &sb );
    }
    else {
      block_num = strtoul ( argv[3], ((void *)0), 10 );
      block_size = strtoul ( argv[4], ((void *)0), 10 );
      ret = read_superblock_backup( fd, &sb, block_num, block_size );
    }
    if ( ret == -1 )
      return 1;
    print_superblock( &sb );
    close_fs ( fd );
  }
  else if( !strcmp( argv[2], "-ls" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -ls <inode number>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 )
      exit(1);
    read_inode( fd, &sb, inode_num, &i);
    if ( !((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("WARNING: This inode does not seem to be a directory\n");
      printf("         seeing it as a directory could lead to impre-\n"
          "         dictable consequences\n");
      printf("continue anyway (y/n) ? ");
      c = getchar();
      if ( c == 'y' ) {
        print_dir( fd, &sb, inode_num );
      }
    }
    else {
      print_dir( fd, &sb, inode_num );
    }
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-stat" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -stat <inode number>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "Superblock read error\n");
      return 1;
    }
    if ( ret == -2 )
      return 0;
    read_inode ( fd, &sb, inode_num, &i );
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\tEXT3_INODE STRUCTURE OF INODE #%u\n", inode_num);
    printf("+------------------------------------------------------------------------------+\n");
    print_inode(fd,&sb, &i);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-tree" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -tree <inode number>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "Superblock read error\n");
      return 1;
    }
    if ( ret == -2 )
      return 0;
    read_inode ( fd, &sb, inode_num, &i );
    print_tree(fd,&sb, &i);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bpoint" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -bpoint <block num>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    block_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "read_superblock\n");
      exit(1);
    }
    print_block_as_bpointer( fd, &sb, block_num );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bcat" ) ) {
    if ( argc != 4 && argc != 5 ) {
      printf("syntax: %s <filesystem> -bcat <block number> -x\n", argv[0]);
      exit (1);
    }
    block_num = strtoul ( argv[3], ((void *)0), 10 );
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    if ( argc == 5 && !strcmp("-x", argv[4]) ) {
      printf("+------------------------------------------------------------------------------+\n");
      printf("\t\t\tSHOWING BLOCK #%u IN HEXADECIMAL\n", block_num );
      printf("+------------------------------------------------------------------------------+\n");
      print_block_hexa( fd, &sb, block_num );
      printf("+------------------------------------------------------------------------------+\n");
    }
    else if ( argc == 4 ) {
      block = malloc ( (1024 << (&sb)->s_log_block_size) );
      ret = read_block(fd, &sb, block_num, block );
      if ( ret == -1 )
        exit(1);
      for ( cc = 0 ; cc < (1024 << (&sb)->s_log_block_size) ; cc++ ) {
        putchar(block[cc]);
      }
      free(block);
      close_fs ( fd );
    }
    else {
      printf("syntax: %s <filesystem> -bcat <block number> -x\n", argv[0]);
    }
  }
  else if ( !strcmp( argv[2], "-cat" ) ) {
    if ( argc != 4 && argc != 5 ) {
      printf("syntax: %s <filesystem> -cat <inode number> [ -x ]\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    read_inode( fd, &sb, inode_num, &i);
    if ( ((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("This inode is a directory, you should use -ls instead.\n");
      printf("use it anyway (y/n) ? ");
      c = getchar();
      if ( c != 'y') {
        close_fs(fd);
        return 0;
      }
    }
    else if ( ((((i.i_mode)) & 0170000) == (0120000)) ) {
      print_symlink( fd, &sb, inode_num);
      close_fs(fd);
      return 0;
    }
    if ( argc == 5 && !strcmp(argv[4],"-x") ) {
      printf("+------------------------------------------------------------------------------+\n");
      printf("\t\tDUMPING FILE WITH INODE #%u IN HEXADECIMAL\n", inode_num );
      printf("+------------------------------------------------------------------------------+\n");
      print_file ( fd, &sb, inode_num, 0 );
      printf("+------------------------------------------------------------------------------+\n");
    }
    else if ( argc == 4 )
      print_file ( fd, &sb, inode_num, 1 );
    else
      printf("syntax: %s <filesystem> -cat <inode number> [ -x ]\n", argv[0]);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-iname" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -iname <inode num>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    search_inode ( fd, &sb, 2, inode_num );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-find" ) ) {
    if ( argc != 5 ) {
      printf("syntax: %s <filesystem> -find <inode num of the parent dir>"
          " <regex pattern>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10);
    strcpy ( pattern, argv[4] );
    read_superblock( fd, &sb );
    read_inode( fd, &sb, inode_num, &i);
    if ( !((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("usage: -find <inode of the dir where the search begin> "
          "<pattern>\n");
      printf("The inode you specified is not a directory. Please specify\n");
      printf("an inode of a directory (eg. \"/\" has inode number 2)\n");
    }
    else {
      search_file ( fd, &sb, inode_num, pattern );
    }
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-imap" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -imap <group_descriptor_num>\n", argv[0]);
      exit (1);
    }
    gd_num =(__u16) atoi(argv[3]);
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if( gd_num >= group_count && gd_num != 0 )
    {
      printf("WARNING: Group descriptor %d entered seems to be "
          "inexistant.\n", gd_num);
      printf("(Existing group descriptors: from num. %d to num. %d,"
          " total %d)\n", 0, group_count == 0?0:group_count-1, group_count);
      printf("Proceed anyway? (y/n)");
      if(getchar()!='y')
      {
        exit(0);
      }
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    inodebitmap = malloc( ((&sb)->s_inodes_per_group)/8 );
    read_inodebitmap( fd, &sb, &gd, inodebitmap);
    print_inodebitmap(&sb, inodebitmap, gd_num);
    free((void *)inodebitmap);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bmap" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -bmap <group_descriptor_num>\n", argv[0]);
      exit (1);
    }
    gd_num =(__u16) atoi(argv[3]);
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if( gd_num >= group_count && gd_num != 0 )
    {
      printf("WARNING: Group descriptor %u entered seems to be inexistant.\n",
          gd_num);
      printf("(Existing group descriptors: from num. %u to num. %u,"
          " total %u)\n", 0, group_count == 0?0:group_count-1, group_count);
      printf("Proceed anyway? (y/n)");
      if(getchar()!='y')
      {
        exit(0);
      }
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    datablockbitmap = malloc( ((&sb)->s_blocks_per_group)/8 );
    read_datablockbitmap( fd, &sb, &gd, gd_num, datablockbitmap);
    print_datablockbitmap(&sb, datablockbitmap, gd_num);
    free((void *)datablockbitmap);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-ffi" ) ) {
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    inodebitmap = malloc( (((&sb)->s_inodes_per_group)/8) );
    inode_num = search_first_free_inode(fd, &sb, inodebitmap);
    if(inode_num>0)
    {
      printf("First Free Inode found: %u\n", inode_num);
    }
    else
    {
      printf("No free inode found\n");
    }
    free(inodebitmap);
    close_fs(fd);
  }
  else if ( !strcmp( argv[2], "-ffb" ) ) {
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    datablockbitmap = malloc( (((&sb)->s_blocks_per_group)/8) );
    block_num = search_first_free_block(fd, &sb, datablockbitmap);
    if(block_num>0)
    {
      printf("First Free Block found: %u\n", block_num);
    }
    else
    {
      printf("No free block found\n");
    }
    free( datablockbitmap );
    close_fs(fd);
  }
  else if ( !strcmp( argv[2], "-jbd" ) ) {
    if ( argc != 3 ) {
      printf("syntax: %s <filesystem> -jbd\n", argv[0]);
      return 1;
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "superblock read error\n");
      exit(1);
    }
    else if ( ret == -2 ) {
      exit(0);
    }
    read_inode ( fd, &sb, sb.s_journal_inum, &i );
    read_journal_superblock( fd, (1024 << (&sb)->s_log_block_size), i.i_block[0], &jsb );
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\t\tJOURNAL SUPERBLOCK\n");
    printf("+------------------------------------------------------------------------------+\n""\n");
    print_journal_superblock(&jsb);
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\t\tJOURNAL CONTENTS\n");
    printf("+------------------------------------------------------------------------------+\n""\n");
    if ( jsb.s_start == 0 ) {
      printf("The journal is empty ! Dumping old transactions :\n");
    }
    dump_journal( fd, (1024 << (&sb)->s_log_block_size), &i );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-printgd" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -printgd <group num>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    gd_num = (__u16) atoi(argv[3]);
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if ( gd_num > group_count ) {
      printf("WARNING: Group descriptor %d entered seems to be ", gd_num);
      printf("inexistant.\n");
      printf("(Existing group descriptors: from num. %d to num. %d,"
          " total %d)\n", 0, group_count, group_count+1);
      printf("Proceed anyway? (y/n) ");
      c = getchar();
      if ( c != 'y' )
        return 0;
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    print_groupdesc ( &gd);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-backups" ) ) {
    if ( argc != 3 ) {
      printf("syntax: %s <filesystem> -backups\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    print_sb_copy ( &sb );
    close_fs ( fd );
  }
  else {
    printf("Usage: %s <fd>  \n               [ -stats   | -stat | -printgd | -imap | -bmap | -ffi   |\n                 -ffb     | -cat  | -bcat    | -ls   | -find | -iname |\n                 -backups | -jbd  | -bpoint  | -tree ]\n'%s -help' for help.\nversion: ext3Viewer 1.0.2\n", argv[0], argv[0]);
    return 1;
  }
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  struct ext3_super_block sb;
  struct ext3_inode i;
  struct ext3_group_desc gd;
  struct journal_superblock_s jsb;
  char *inodebitmap; char *datablockbitmap;
  char c;
  char *block;
  int cc;
  int block_size;
  unsigned short gd_num;
  unsigned int inode_num;
  unsigned int block_num;
  unsigned short group_count;
  int fd;
  char pattern[255];
  long long ret;
  ;
  ;
  if ( argc == 2 && !strcmp( argv[1], "-help" ) ) {
    printf("Usage: %s <FILESYSTEM> OPTION ARG1 [ ARG2 ... ]\n\n Dumps and interprets informations about ext3 filesystems.\n (in all this help, is the ext3 filesystem. ex: /dev/hda2)\n\n <FILESYSTEM> is the ext3 filesystem to examinate, could be a device or\n                 a image file. eg: /dev/hda2, /dev/sda3, ./image.ext3\n\n OPTION and ARGS are shown below :\n\t-stats [ <block num> <block size> ]\n\t                           info about the superblock and the group\n\t                           descriptors. if you specify a block number\n\t                           and a block size, it will read an alternate \n\t                           superblock. see -backups\n\n\t-stat  <inode num>         show the inode structure contents\n\t-bpoint  <block num>       display a block as a pointer of blocks\n\t-printgd  <group num>      dump the group_desc structure of a group\n\n\n\t-tree  <inode num>         show the form of an inode block allocation\n\t-imap  <group_desc num>    print the inode bitmap as an array\n\t-bmap  <group_desc num>    print the block bitmap as an array\n\t-ffi                       find the first free inode thanks to the\n\t                           bitmap\n\t-ffb                       find the first free block\n\n\n\t-cat  <inode num>  [ -x ]  dump the contents of a file.(read all the\n\t                           blocks). -x for hexa.\n\t-bcat  <block num> [ -x ]  dump the contents of a block.(read just one\n\t                           block) -x for hexa.\n\n\n\t-ls  <inode num>           print the directory entries of an inode.\n\t                           the root has inode number 2.\n\n\t-find  <inode_dir starting number> <regex pattern>\n\t                           find files recursively from a given directory\n\t                           that matches a regex pattern. for / type 2\n\n\t-iname  <inode num>        find all the files that have the given inode\n\n\t-backups                   calculate where the copies of the\n\t                           superblock are\n\n\n\t-jbd                       dump the journal contents.\n\n\n\t-help                      display this help. see also the man page\n\n See the man page for more details.\n\next3Viewer 1.0.2 GNU public license\nCopyright (C) 2013 Laurent Sebag\nCopyright (C) 2007 Laurent Sebag & Nathan Periana\ne2view (2003) Julien Poitrat, original idea\n", argv[0]);
    return 0;
  }
  else if ( argc < 3 ) {
    printf("Usage: %s <fd>  \n               [ -stats   | -stat | -printgd | -imap | -bmap | -ffi   |\n                 -ffb     | -cat  | -bcat    | -ls   | -find | -iname |\n                 -backups | -jbd  | -bpoint  | -tree ]\n'%s -help' for help.\nversion: ext3Viewer 1.0.2\n", argv[0], argv[0]);
    return 1;
  }
  else if ( !strcmp( argv[2], "-stats" ) ) {
    if ( argc != 5 && argc != 3 ) {
      printf("usage %s <filesystem> -stats [ <block number> <block size> ]\n",
          argv[0]);
      return 1;
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    if ( argc == 3 ) {
      ret = read_superblock( fd, &sb );
    }
    else {
      block_num = strtoul ( argv[3], ((void *)0), 10 );
      block_size = strtoul ( argv[4], ((void *)0), 10 );
      ret = read_superblock_backup( fd, &sb, block_num, block_size );
    }
    if ( ret == -1 )
      return 1;
    print_superblock( &sb );
    close_fs ( fd );
  }
  else if( !strcmp( argv[2], "-ls" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -ls <inode number>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 )
      exit(1);
    read_inode( fd, &sb, inode_num, &i);
    if ( !((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("WARNING: This inode does not seem to be a directory\n");
      printf("         seeing it as a directory could lead to impre-\n"
          "         dictable consequences\n");
      printf("continue anyway (y/n) ? ");
      c = getchar();
      if ( c == 'y' ) {
        print_dir( fd, &sb, inode_num );
      }
    }
    else {
      print_dir( fd, &sb, inode_num );
    }
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-stat" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -stat <inode number>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "Superblock read error\n");
      return 1;
    }
    if ( ret == -2 )
      return 0;
    read_inode ( fd, &sb, inode_num, &i );
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\tEXT3_INODE STRUCTURE OF INODE #%u\n", inode_num);
    printf("+------------------------------------------------------------------------------+\n");
    print_inode(fd,&sb, &i);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-tree" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -tree <inode number>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "Superblock read error\n");
      return 1;
    }
    if ( ret == -2 )
      return 0;
    read_inode ( fd, &sb, inode_num, &i );
    print_tree(fd,&sb, &i);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bpoint" ) ) {
    if ( argc != 4 ) {
      printf("usage %s <filesystem> -bpoint <block num>\n", argv[0]);
      exit(1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    block_num = strtoul( argv[3], ((void *)0), 10 );
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "read_superblock\n");
      exit(1);
    }
    print_block_as_bpointer( fd, &sb, block_num );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bcat" ) ) {
    if ( argc != 4 && argc != 5 ) {
      printf("syntax: %s <filesystem> -bcat <block number> -x\n", argv[0]);
      exit (1);
    }
    block_num = strtoul ( argv[3], ((void *)0), 10 );
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    if ( argc == 5 && !strcmp("-x", argv[4]) ) {
      printf("+------------------------------------------------------------------------------+\n");
      printf("\t\t\tSHOWING BLOCK #%u IN HEXADECIMAL\n", block_num );
      printf("+------------------------------------------------------------------------------+\n");
      print_block_hexa( fd, &sb, block_num );
      printf("+------------------------------------------------------------------------------+\n");
    }
    else if ( argc == 4 ) {
      block = malloc ( (1024 << (&sb)->s_log_block_size) );
      ret = read_block(fd, &sb, block_num, block );
      if ( ret == -1 )
        exit(1);
      for ( cc = 0 ; cc < (1024 << (&sb)->s_log_block_size) ; cc++ ) {
        putchar(block[cc]);
      }
      free(block);
      close_fs ( fd );
    }
    else {
      printf("syntax: %s <filesystem> -bcat <block number> -x\n", argv[0]);
    }
  }
  else if ( !strcmp( argv[2], "-cat" ) ) {
    if ( argc != 4 && argc != 5 ) {
      printf("syntax: %s <filesystem> -cat <inode number> [ -x ]\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    read_inode( fd, &sb, inode_num, &i);
    if ( ((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("This inode is a directory, you should use -ls instead.\n");
      printf("use it anyway (y/n) ? ");
      c = getchar();
      if ( c != 'y') {
        close_fs(fd);
        return 0;
      }
    }
    else if ( ((((i.i_mode)) & 0170000) == (0120000)) ) {
      print_symlink( fd, &sb, inode_num);
      close_fs(fd);
      return 0;
    }
    if ( argc == 5 && !strcmp(argv[4],"-x") ) {
      printf("+------------------------------------------------------------------------------+\n");
      printf("\t\tDUMPING FILE WITH INODE #%u IN HEXADECIMAL\n", inode_num );
      printf("+------------------------------------------------------------------------------+\n");
      print_file ( fd, &sb, inode_num, 0 );
      printf("+------------------------------------------------------------------------------+\n");
    }
    else if ( argc == 4 )
      print_file ( fd, &sb, inode_num, 1 );
    else
      printf("syntax: %s <filesystem> -cat <inode number> [ -x ]\n", argv[0]);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-iname" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -iname <inode num>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10 );
    read_superblock( fd, &sb );
    search_inode ( fd, &sb, 2, inode_num );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-find" ) ) {
    if ( argc != 5 ) {
      printf("syntax: %s <filesystem> -find <inode num of the parent dir>"
          " <regex pattern>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    inode_num = strtoul ( argv[3], ((void *)0), 10);
    strcpy ( pattern, argv[4] );
    read_superblock( fd, &sb );
    read_inode( fd, &sb, inode_num, &i);
    if ( !((((i.i_mode)) & 0170000) == (0040000)) ) {
      printf("usage: -find <inode of the dir where the search begin> "
          "<pattern>\n");
      printf("The inode you specified is not a directory. Please specify\n");
      printf("an inode of a directory (eg. \"/\" has inode number 2)\n");
    }
    else {
      search_file ( fd, &sb, inode_num, pattern );
    }
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-imap" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -imap <group_descriptor_num>\n", argv[0]);
      exit (1);
    }
    gd_num =(unsigned short) atoi(argv[3]);
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if( gd_num >= group_count && gd_num != 0 )
    {
      printf("WARNING: Group descriptor %d entered seems to be "
          "inexistant.\n", gd_num);
      printf("(Existing group descriptors: from num. %d to num. %d,"
          " total %d)\n", 0, group_count == 0?0:group_count-1, group_count);
      printf("Proceed anyway? (y/n)");
      if(getchar()!='y')
      {
        exit(0);
      }
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    inodebitmap = malloc( ((&sb)->s_inodes_per_group)/8 );
    read_inodebitmap( fd, &sb, &gd, inodebitmap);
    print_inodebitmap(&sb, inodebitmap, gd_num);
    free((void *)inodebitmap);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-bmap" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -bmap <group_descriptor_num>\n", argv[0]);
      exit (1);
    }
    gd_num =(unsigned short) atoi(argv[3]);
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if( gd_num >= group_count && gd_num != 0 )
    {
      printf("WARNING: Group descriptor %u entered seems to be inexistant.\n",
          gd_num);
      printf("(Existing group descriptors: from num. %u to num. %u,"
          " total %u)\n", 0, group_count == 0?0:group_count-1, group_count);
      printf("Proceed anyway? (y/n)");
      if(getchar()!='y')
      {
        exit(0);
      }
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    datablockbitmap = malloc( ((&sb)->s_blocks_per_group)/8 );
    read_datablockbitmap( fd, &sb, &gd, gd_num, datablockbitmap);
    print_datablockbitmap(&sb, datablockbitmap, gd_num);
    free((void *)datablockbitmap);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-ffi" ) ) {
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    inodebitmap = malloc( (((&sb)->s_inodes_per_group)/8) );
    inode_num = search_first_free_inode(fd, &sb, inodebitmap);
    if(inode_num>0)
    {
      printf("First Free Inode found: %u\n", inode_num);
    }
    else
    {
      printf("No free inode found\n");
    }
    free(inodebitmap);
    close_fs(fd);
  }
  else if ( !strcmp( argv[2], "-ffb" ) ) {
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    datablockbitmap = malloc( (((&sb)->s_blocks_per_group)/8) );
    block_num = search_first_free_block(fd, &sb, datablockbitmap);
    if(block_num>0)
    {
      printf("First Free Block found: %u\n", block_num);
    }
    else
    {
      printf("No free block found\n");
    }
    free( datablockbitmap );
    close_fs(fd);
  }
  else if ( !strcmp( argv[2], "-jbd" ) ) {
    if ( argc != 3 ) {
      printf("syntax: %s <filesystem> -jbd\n", argv[0]);
      return 1;
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    ret = read_superblock( fd, &sb );
    if ( ret == -1 ) {
      fprintf( stderr, "superblock read error\n");
      exit(1);
    }
    else if ( ret == -2 ) {
      exit(0);
    }
    read_inode ( fd, &sb, sb.s_journal_inum, &i );
    read_journal_superblock( fd, (1024 << (&sb)->s_log_block_size), i.i_block[0], &jsb );
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\t\tJOURNAL SUPERBLOCK\n");
    printf("+------------------------------------------------------------------------------+\n""\n");
    print_journal_superblock(&jsb);
    printf("+------------------------------------------------------------------------------+\n");
    printf("\t\t\t\tJOURNAL CONTENTS\n");
    printf("+------------------------------------------------------------------------------+\n""\n");
    if ( jsb.s_start == 0 ) {
      printf("The journal is empty ! Dumping old transactions :\n");
    }
    dump_journal( fd, (1024 << (&sb)->s_log_block_size), &i );
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-printgd" ) ) {
    if ( argc != 4 ) {
      printf("syntax: %s <filesystem> -printgd <group num>\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    gd_num = (unsigned short) atoi(argv[3]);
    read_superblock( fd, &sb );
    group_count = sb.s_blocks_count/((&sb)->s_blocks_per_group);
    if ( gd_num > group_count ) {
      printf("WARNING: Group descriptor %d entered seems to be ", gd_num);
      printf("inexistant.\n");
      printf("(Existing group descriptors: from num. %d to num. %d,"
          " total %d)\n", 0, group_count, group_count+1);
      printf("Proceed anyway? (y/n) ");
      c = getchar();
      if ( c != 'y' )
        return 0;
    }
    read_group_desc( fd, &sb, gd_num, &gd);
    print_groupdesc ( &gd);
    close_fs ( fd );
  }
  else if ( !strcmp( argv[2], "-backups" ) ) {
    if ( argc != 3 ) {
      printf("syntax: %s <filesystem> -backups\n", argv[0]);
      exit (1);
    }
    fd = open_fs( argv[1] );
    if( fd == -1 )
      return 1;
    read_superblock( fd, &sb );
    print_sb_copy ( &sb );
    close_fs ( fd );
  }
  else {
    printf("Usage: %s <fd>  \n               [ -stats   | -stat | -printgd | -imap | -bmap | -ffi   |\n                 -ffb     | -cat  | -bcat    | -ls   | -find | -iname |\n                 -backups | -jbd  | -bpoint  | -tree ]\n'%s -help' for help.\nversion: ext3Viewer 1.0.2\n", argv[0], argv[0]);
    return 1;
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: struct ext3_super_block { unsigned int s_inodes_count; unsigned int s_blocks_count; unsigned int s_r_blocks_count; unsigned int s_free_blocks_count; unsigned int s_free_inodes_count; unsigned int s_first_data_block; unsigned int s_log_block_size; unsigned int s_log_frag_size; unsigned int s_blocks_per_group; unsigned int s_frags_per_group; unsigned int s_inodes_per_group; unsigned int s_mtime; unsigned int s_wtime; unsigned short s_mnt_count; unsigned short s_max_mnt_count; unsigned short s_magic; unsigned short s_state; unsigned short s_errors; unsigned short s_minor_rev_level; unsigned int s_lastcheck; unsigned int s_checkinterval; unsigned int s_creator_os; unsigned int s_rev_level; unsigned short s_def_resuid; unsigned short s_def_resgid; unsigned int s_first_ino; unsigned short s_inode_size; unsigned short s_block_group_nr; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; char s_volume_name[16]; char s_last_mounted[64]; unsigned int s_algorithm_usage_bitmap; unsigned char s_prealloc_blocks; unsigned char s_prealloc_dir_blocks; unsigned short s_reserved_gdt_blocks; unsigned char s_journal_uuid[16]; unsigned int s_journal_inum; unsigned int s_journal_dev; unsigned int s_last_orphan; unsigned int s_hash_seed[4]; unsigned char s_def_hash_version; unsigned char s_reserved_char_pad; unsigned short s_reserved_word_pad; unsigned int s_default_mount_opts; unsigned int s_first_meta_bg; unsigned int s_mkfs_time; unsigned int s_jnl_blocks[17]; unsigned int s_blocks_count_hi; unsigned int s_r_blocks_count_hi; unsigned int s_free_blocks_count_hi; unsigned short s_min_extra_isize; unsigned short s_want_extra_isize; unsigned int s_flags; unsigned short s_raid_stride; unsigned short s_mmp_interval; unsigned long long s_mmp_block; unsigned int s_raid_stripe_width; unsigned char s_log_groups_per_flex; unsigned char s_reserved_char_pad2; unsigned short s_reserved_pad; unsigned int s_reserved[162]; }

variable_types: struct ext3_inode { unsigned short i_mode; unsigned short i_uid; unsigned int i_size; unsigned int i_atime; unsigned int i_ctime; unsigned int i_mtime; unsigned int i_dtime; unsigned short i_gid; unsigned short i_links_count; unsigned int i_blocks; unsigned int i_flags; union { struct { unsigned int l_i_reserved1; } linux1; struct { unsigned int h_i_translator; } hurd1; struct { unsigned int m_i_reserved1; } masix1; } osd1; unsigned int i_block[-1]; unsigned int i_generation; unsigned int i_file_acl; unsigned int i_dir_acl; unsigned int i_faddr; union { struct { unsigned char l_i_frag; unsigned char l_i_fsize; unsigned short i_pad1; unsigned short l_i_uid_high; unsigned short l_i_gid_high; unsigned int l_i_reserved2; } linux2; struct { unsigned char h_i_frag; unsigned char h_i_fsize; unsigned short h_i_mode_high; unsigned short h_i_uid_high; unsigned short h_i_gid_high; unsigned int h_i_author; } hurd2; struct { unsigned char m_i_frag; unsigned char m_i_fsize; unsigned short m_pad1; unsigned int m_i_reserved2[2]; } masix2; } osd2; unsigned short i_extra_isize; unsigned short i_pad1; }

variable_types: struct ext3_group_desc { unsigned int bg_block_bitmap; unsigned int bg_inode_bitmap; unsigned int bg_inode_table; unsigned short bg_free_blocks_count; unsigned short bg_free_inodes_count; unsigned short bg_used_dirs_count; unsigned short bg_pad; unsigned int bg_reserved[3]; }

variable_types: struct journal_superblock_s { struct journal_header_s { unsigned int h_magic; unsigned int h_blocktype; unsigned int h_sequence; } s_header; unsigned int s_blocksize; unsigned int s_maxlen; unsigned int s_first; unsigned int s_sequence; unsigned int s_start; unsigned int s_errno; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; unsigned int s_nr_users; unsigned int s_dynsuper; unsigned int s_max_transaction; unsigned int s_max_trans_data; unsigned int s_padding[44]; unsigned char s_users[-1]; }

variable_types:
inodebitmap
char *

variable_types:
datablockbitmap
char *

variable_types: c char

variable_types:
block
char *

variable_types: cc int

variable_types: fd int

variable_types:
pattern
char [255]

variable_types:
ret
long long

user_defined_types: struct journal_superblock_s { struct journal_header_s s_header; unsigned int s_blocksize; unsigned int s_maxlen; unsigned int s_first; unsigned int s_sequence; unsigned int s_start; unsigned int s_errno; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; unsigned int s_nr_users; unsigned int s_dynsuper; unsigned int s_max_transaction; unsigned int s_max_trans_data; unsigned int s_padding[44]; unsigned char s_users[-1]; }


decompiled_code:
__int64 __fastcall read_xattrh(int fd, __int64 a2, unsigned int a3, void *a4)
{
unsigned int v5; // er12

if ( (unsigned int)lseek64(fd, a3, 0) == -1 )
{
v5 = -1;
perror("ext3Viewer - lseek error: ACL");
}
else
{
v5 = read(fd, a4, 0x20uLL);
if ( v5 == -1 )
perror("ext3Viewer - read error: ACL");
else
v5 = 0;
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, __int64 a2, unsigned int a3, void *a4)
{
unsigned int v5; // er12

if ( (unsigned int)lseek64(fd, a3, 0) == -1 )
{
v5 = -1;
perror("ext3Viewer - lseek error: ACL");
}
else
{
v5 = read(fd, a4, 0x20uLL);
if ( v5 == -1 )
perror("ext3Viewer - read error: ACL");
else
v5 = 0;
}
return v5;
}

original_code:
int read_xattrh(int fd, const struct ext3_super_block *sb, __u32 header_pos,
    struct ext3_xattr_header * header )
{
  int ret;
  ret = lseek(fd, header_pos, 0);
  if ( ret == -1 ) {
    perror("ext3Viewer - lseek error: ACL");
    return -1;
  }
  ret = read( fd, header, sizeof(struct ext3_xattr_header) );
  if ( ret == -1 ) {
    perror("ext3Viewer - read error: ACL");
    return -1;
  }
  return 0;
}

canonical_original_code:
int read_xattrh(int fd, struct ext3_super_block *sb, unsigned int header_pos, struct ext3_xattr_header *header)
{
  int ret;
  ret = lseek(fd, header_pos, 0);
  if ( ret == -1 ) {
    perror("ext3Viewer - lseek error: ACL");
    return -1;
  }
  ret = read( fd, header, sizeof(struct ext3_xattr_header) );
  if ( ret == -1 ) {
    perror("ext3Viewer - read error: ACL");
    return -1;
  }
  return 0;
}

variable_types: struct ext3_super_block { unsigned int s_inodes_count; unsigned int s_blocks_count; unsigned int s_r_blocks_count; unsigned int s_free_blocks_count; unsigned int s_free_inodes_count; unsigned int s_first_data_block; unsigned int s_log_block_size; unsigned int s_log_frag_size; unsigned int s_blocks_per_group; unsigned int s_frags_per_group; unsigned int s_inodes_per_group; unsigned int s_mtime; unsigned int s_wtime; unsigned short s_mnt_count; unsigned short s_max_mnt_count; unsigned short s_magic; unsigned short s_state; unsigned short s_errors; unsigned short s_minor_rev_level; unsigned int s_lastcheck; unsigned int s_checkinterval; unsigned int s_creator_os; unsigned int s_rev_level; unsigned short s_def_resuid; unsigned short s_def_resgid; unsigned int s_first_ino; unsigned short s_inode_size; unsigned short s_block_group_nr; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; char s_volume_name[16]; char s_last_mounted[64]; unsigned int s_algorithm_usage_bitmap; unsigned char s_prealloc_blocks; unsigned char s_prealloc_dir_blocks; unsigned short s_reserved_gdt_blocks; unsigned char s_journal_uuid[16]; unsigned int s_journal_inum; unsigned int s_journal_dev; unsigned int s_last_orphan; unsigned int s_hash_seed[4]; unsigned char s_def_hash_version; unsigned char s_reserved_char_pad; unsigned short s_reserved_word_pad; unsigned int s_default_mount_opts; unsigned int s_first_meta_bg; unsigned int s_mkfs_time; unsigned int s_jnl_blocks[17]; unsigned int s_blocks_count_hi; unsigned int s_r_blocks_count_hi; unsigned int s_free_blocks_count_hi; unsigned short s_min_extra_isize; unsigned short s_want_extra_isize; unsigned int s_flags; unsigned short s_raid_stride; unsigned short s_mmp_interval; unsigned long long s_mmp_block; unsigned int s_raid_stripe_width; unsigned char s_log_groups_per_flex; unsigned char s_reserved_char_pad2; unsigned short s_reserved_pad; unsigned int s_reserved[162]; } *

variable_types: struct ext3_xattr_header { unsigned int h_magic; unsigned int h_refcount; unsigned int h_blocks; unsigned int h_hash; unsigned int h_reserved[4]; } *

variable_types: ret int

return_type: int


decompiled_code:
__int64 __fastcall read_xattre(int fd, __int64 a2, int a3, unsigned __int16 a4, void *a5)
{
unsigned int v6; // er12

if ( (unsigned int)lseek64(fd, a3 * (1024 << *(_DWORD *)(a2 + 24)) + (unsigned int)a4, 0) == -1 )
{
v6 = -1;
perror("ext3Viewer - lseek error: xattr_entry");
}
else
{
v6 = read(fd, a5, 0x10uLL);
if ( v6 == -1 )
perror("ext3Viewer - read error: xattr_entry");
else
v6 = 0;
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func1(int fd, __int64 a2, int a3, unsigned __int16 a4, void *a5)
{
unsigned int v6; // er12

if ( (unsigned int)lseek64(fd, a3 * (1024 << *(_DWORD *)(a2 + 24)) + (unsigned int)a4, 0) == -1 )
{
v6 = -1;
perror("ext3Viewer - lseek error: xattr_entry");
}
else
{
v6 = read(fd, a5, 0x10uLL);
if ( v6 == -1 )
perror("ext3Viewer - read error: xattr_entry");
else
v6 = 0;
}
return v6;
}

original_code:
int read_xattre(int fd, const struct ext3_super_block *sb, __u32 entry_blocknum,
    __u16 offset, struct ext3_xattr_entry * entry )
{
  int ret;
  entry_blocknum = entry_blocknum*(1024 << (sb)->s_log_block_size);
  ret = lseek(fd, entry_blocknum+offset, 0);
  if ( ret == -1 ) {
    perror("ext3Viewer - lseek error: xattr_entry");
    return -1;
  }
  ret = read( fd, entry, sizeof(struct ext3_xattr_entry) );
  if ( ret == -1 ) {
    perror("ext3Viewer - read error: xattr_entry");
    return -1;
  }
  return 0;
}

canonical_original_code:
int read_xattre(int fd, struct ext3_super_block *sb, unsigned int entry_blocknum, unsigned short offset, struct ext3_xattr_entry *entry)
{
  int ret;
  entry_blocknum = entry_blocknum*(1024 << (sb)->s_log_block_size);
  ret = lseek(fd, entry_blocknum+offset, 0);
  if ( ret == -1 ) {
    perror("ext3Viewer - lseek error: xattr_entry");
    return -1;
  }
  ret = read( fd, entry, sizeof(struct ext3_xattr_entry) );
  if ( ret == -1 ) {
    perror("ext3Viewer - read error: xattr_entry");
    return -1;
  }
  return 0;
}

variable_types:
offset
unsigned short

variable_types: struct ext3_xattr_entry { unsigned char e_name_len; unsigned char e_name_index; unsigned short e_value_offs; unsigned int e_value_block; unsigned int e_value_size; unsigned int e_hash; char e_name[]; } *

user_defined_types: struct ext3_super_block { unsigned int s_inodes_count; unsigned int s_blocks_count; unsigned int s_r_blocks_count; unsigned int s_free_blocks_count; unsigned int s_free_inodes_count; unsigned int s_first_data_block; unsigned int s_log_block_size; unsigned int s_log_frag_size; unsigned int s_blocks_per_group; unsigned int s_frags_per_group; unsigned int s_inodes_per_group; unsigned int s_mtime; unsigned int s_wtime; unsigned short s_mnt_count; unsigned short s_max_mnt_count; unsigned short s_magic; unsigned short s_state; unsigned short s_errors; unsigned short s_minor_rev_level; unsigned int s_lastcheck; unsigned int s_checkinterval; unsigned int s_creator_os; unsigned int s_rev_level; unsigned short s_def_resuid; unsigned short s_def_resgid; unsigned int s_first_ino; unsigned short s_inode_size; unsigned short s_block_group_nr; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; char s_volume_name[16]; char s_last_mounted[64]; unsigned int s_algorithm_usage_bitmap; unsigned char s_prealloc_blocks; unsigned char s_prealloc_dir_blocks; unsigned short s_reserved_gdt_blocks; unsigned char s_journal_uuid[16]; unsigned int s_journal_inum; unsigned int s_journal_dev; unsigned int s_last_orphan; unsigned int s_hash_seed[4]; unsigned char s_def_hash_version; unsigned char s_reserved_char_pad; unsigned short s_reserved_word_pad; unsigned int s_default_mount_opts; unsigned int s_first_meta_bg; unsigned int s_mkfs_time; unsigned int s_jnl_blocks[17]; unsigned int s_blocks_count_hi; unsigned int s_r_blocks_count_hi; unsigned int s_free_blocks_count_hi; unsigned short s_min_extra_isize; unsigned short s_want_extra_isize; unsigned int s_flags; unsigned short s_raid_stride; unsigned short s_mmp_interval; unsigned long long s_mmp_block; unsigned int s_raid_stripe_width; unsigned char s_log_groups_per_flex; unsigned char s_reserved_char_pad2; unsigned short s_reserved_pad; unsigned int s_reserved[162]; }


decompiled_code:
int __fastcall print_acl(int fd, __int64 a2, int a3)
{
unsigned __int16 v4; // bx
char v5[2]; // [rsp+0h] [rbp-48h] BYREF
unsigned __int16 v6; // [rsp+2h] [rbp-46h]
unsigned int v7; // [rsp+4h] [rbp-44h]
unsigned int v8; // [rsp+8h] [rbp-40h]
unsigned int v9; // [rsp+Ch] [rbp-3Ch]
int v10[14]; // [rsp+10h] [rbp-38h] BYREF

if ( !a3 )
return puts("No ACL entry associated.");
v4 = a3;
puts(
"This is the number of the file system block on which\n"
" the Extended Attributes associated with this inode are stored.");
read_xattrh(fd, a2, v4, v10);
read_xattre(fd, a2, v4, 0x20u, v5);
puts("Header of the extended attributes list");
printf("The magic number should be %#x, is %#x\n", 3925999616LL, (unsigned int)v10[0]);
printf("This set of attributes is referenced %u times\n", (unsigned int)v10[1]);
printf("%u blocks are used\n", (unsigned int)v10[2]);
printf("Hash value of all attributes:%#x\n", (unsigned int)v10[3]);
printf("Name length: %hhu\n", (unsigned __int8)v5[0]);
printf("Attribute name index: %hhu\n", (unsigned __int8)v5[1]);
printf("Disk block offset of value: %u\n", v6);
printf("Disk block attribute is stored on: %u\n", v7);
printf("Size of attribute value: %u\n", v8);
printf("Hash value of name and value: %#x\n", v9);
return printf("Attribute name: %#x\n", (unsigned int)SLOBYTE(v10[0]));
}

canonical_decompiled_code:
int __fastcall func2(int fd, __int64 a2, int a3)
{
unsigned __int16 v4; // bx
char v5[2]; // [rsp+0h] [rbp-48h] BYREF
unsigned __int16 v6; // [rsp+2h] [rbp-46h]
unsigned int v7; // [rsp+4h] [rbp-44h]
unsigned int v8; // [rsp+8h] [rbp-40h]
unsigned int v9; // [rsp+Ch] [rbp-3Ch]
int v10[14]; // [rsp+10h] [rbp-38h] BYREF

if ( !a3 )
return puts("No ACL entry associated.");
v4 = a3;
puts(
"This is the number of the file system block on which\n"
" the Extended Attributes associated with this inode are stored.");
func0(fd, a2, v4, v10);
func1(fd, a2, v4, 0x20u, v5);
puts("Header of the extended attributes list");
printf("The magic number should be %#x, is %#x\n", 3925999616LL, (unsigned int)v10[0]);
printf("This set of attributes is referenced %u times\n", (unsigned int)v10[1]);
printf("%u blocks are used\n", (unsigned int)v10[2]);
printf("Hash value of all attributes:%#x\n", (unsigned int)v10[3]);
printf("Name length: %hhu\n", (unsigned __int8)v5[0]);
printf("Attribute name index: %hhu\n", (unsigned __int8)v5[1]);
printf("Disk block offset of value: %u\n", v6);
printf("Disk block attribute is stored on: %u\n", v7);
printf("Size of attribute value: %u\n", v8);
printf("Hash value of name and value: %#x\n", v9);
return printf("Attribute name: %#x\n", (unsigned int)SLOBYTE(v10[0]));
}

original_code:
void print_acl(int fd, const struct ext3_super_block *sb, __u32 i_type_acl)
{
  struct ext3_xattr_header xattr_header;
  struct ext3_xattr_entry xattr_entry;
  __u16 position = 0, offset = 0;
  if(i_type_acl == 0)
  {
    printf("No ACL entry associated.\n");
  }
  else
  {
    printf("This is the number of the file system block on which\n "
        "the Extended Attributes associated with this inode are stored.\n");
    position = i_type_acl;
    read_xattrh(fd, sb, position,&xattr_header);
    offset = sizeof(struct ext3_xattr_header);
    read_xattre(fd, sb, position, offset,&xattr_entry);
    printf("Header of the extended attributes list\n");
    printf("The magic number should be %#x, is %#x\n", 0xEA020000,
        xattr_header.h_magic);
    printf("This set of attributes is referenced %u times\n",
        xattr_header.h_refcount);
    printf("%u blocks are used\n", xattr_header.h_blocks);
    printf("Hash value of all attributes:%#x\n", xattr_header.h_hash);
    printf("Name length: %hhu\n", xattr_entry.e_name_len);
    printf("Attribute name index: %hhu\n", xattr_entry.e_name_index);
    printf("Disk block offset of value: %u\n",
        ((__u16)(__le16)(xattr_entry.e_value_offs)));
    printf("Disk block attribute is stored on: %u\n",
        ((__u32)(__le32)(xattr_entry.e_value_block)));
    printf("Size of attribute value: %u\n",
        ((__u32)(__le32)(xattr_entry.e_value_size)));
    printf("Hash value of name and value: %#x\n",
        ((__u32)(__le32)(xattr_entry.e_hash)));
    printf("Attribute name: %#x\n", xattr_entry.e_name[0]);
    offset = ((__u16)(__le16)(xattr_entry.e_value_offs));
  }
}

canonical_original_code:
void print_acl(int fd, struct ext3_super_block *sb, unsigned int i_type_acl)
{
  struct ext3_xattr_header xattr_header;
  struct ext3_xattr_entry xattr_entry;
  unsigned short position = 0; unsigned short offset = 0;
  if(i_type_acl == 0)
  {
    printf("No ACL entry associated.\n");
  }
  else
  {
    printf("This is the number of the file system block on which\n "
        "the Extended Attributes associated with this inode are stored.\n");
    position = i_type_acl;
    read_xattrh(fd, sb, position,&xattr_header);
    offset = sizeof(struct ext3_xattr_header);
    read_xattre(fd, sb, position, offset,&xattr_entry);
    printf("Header of the extended attributes list\n");
    printf("The magic number should be %#x, is %#x\n", 0xEA020000,
        xattr_header.h_magic);
    printf("This set of attributes is referenced %u times\n",
        xattr_header.h_refcount);
    printf("%u blocks are used\n", xattr_header.h_blocks);
    printf("Hash value of all attributes:%#x\n", xattr_header.h_hash);
    printf("Name length: %hhu\n", xattr_entry.e_name_len);
    printf("Attribute name index: %hhu\n", xattr_entry.e_name_index);
    printf("Disk block offset of value: %u\n",
        ((__u16)(__le16)(xattr_entry.e_value_offs)));
    printf("Disk block attribute is stored on: %u\n",
        ((__u32)(__le32)(xattr_entry.e_value_block)));
    printf("Size of attribute value: %u\n",
        ((__u32)(__le32)(xattr_entry.e_value_size)));
    printf("Hash value of name and value: %#x\n",
        ((__u32)(__le32)(xattr_entry.e_hash)));
    printf("Attribute name: %#x\n", xattr_entry.e_name[0]);
    offset = ((__u16)(__le16)(xattr_entry.e_value_offs));
  }
}

variable_types: struct ext3_xattr_header { unsigned int h_magic; unsigned int h_refcount; unsigned int h_blocks; unsigned int h_hash; unsigned int h_reserved[4]; }

variable_types: struct ext3_xattr_entry { unsigned char e_name_len; unsigned char e_name_index; unsigned short e_value_offs; unsigned int e_value_block; unsigned int e_value_size; unsigned int e_hash; char e_name[]; }

variable_types:
position
unsigned short

return_type: void


push

decompiled_code:
__int64 __fastcall push(char **a1, const char *a2, int a3)
{
char *v4; // rax
char *v5; // rbx
__int64 result; // rax

v4 = (char *)malloc(0x110uLL);
if ( v4 )
{
v5 = v4;
strcpy(v4, a2);
*((_DWORD *)v5 + 64) = a3;
*((_QWORD *)v5 + 33) = *a1;
*a1 = v5;
result = 0LL;
}
else
{
perror("path_filo");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(char **a1, const char *a2, int a3)
{
char *v4; // rax
char *v5; // rbx
__int64 result; // rax

v4 = (char *)malloc(0x110uLL);
if ( v4 )
{
v5 = v4;
strcpy(v4, a2);
*((_DWORD *)v5 + 64) = a3;
*((_QWORD *)v5 + 33) = *a1;
*a1 = v5;
result = 0LL;
}
else
{
perror("path_filo");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int push ( struct path_filo **p, const char * name, __u32 inode ) {
  struct path_filo *element = malloc(sizeof(path_filo));
  if(!element) {
    perror("path_filo");
    return -1;
  }
  strcpy ( element->name, name );
  element->inode = inode;
  element->prev = *p;
  *p = element;
  return 0;
}

canonical_original_code:
int push(struct path_filo **p, char *name, unsigned int inode) {
  struct path_filo *element = malloc(sizeof(path_filo));
  if(!element) {
    perror("path_filo");
    return -1;
  }
  strcpy ( element->name, name );
  element->inode = inode;
  element->prev = *p;
  *p = element;
  return 0;
}

variable_types: struct path_filo { char name[255]; unsigned int inode; struct path_filo *prev; } **

variable_types:
name
char *

variable_types:
inode
unsigned int


decompiled_code:
__int64 __fastcall remove_top(_QWORD **a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbp

v2 = *a1;
if ( !v2 )
return 0xFFFFFFFFLL;
v3 = (_QWORD *)v2[33];
free(v2);
*a1 = v3;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD **a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbp

v2 = *a1;
if ( !v2 )
return 0xFFFFFFFFLL;
v3 = (_QWORD *)v2[33];
free(v2);
*a1 = v3;
return 0LL;
}

original_code:
int remove_top(struct path_filo **p)
{
  struct path_filo *tmp;
  if( *p == ((void *)0) )
    return -1;
  tmp = (*p)->prev;
  free(*p);
  *p = tmp;
  return 0;
}

variable_types: struct path_filo { char name[255]; unsigned int inode; struct path_filo *prev; } *


decompiled_code:
void __fastcall free_path(_QWORD *a1)
{
_QWORD *v2; // rbx
void *v3; // rdi

v2 = (_QWORD *)*a1;
if ( *a1 )
{
do
{
v3 = v2;
v2 = (_QWORD *)v2[33];
free(v3);
*a1 = v2;
}
while ( v2 );
}
}

canonical_decompiled_code:
void __fastcall func2(_QWORD *a1)
{
_QWORD *v2; // rbx
void *v3; // rdi

v2 = (_QWORD *)*a1;
if ( *a1 )
{
do
{
v3 = v2;
v2 = (_QWORD *)v2[33];
free(v3);
*a1 = v2;
}
while ( v2 );
}
}

original_code:
void free_path(struct path_filo **p)
{
  struct path_filo *tmp;
  while( *p != ((void *)0) )
  {
    tmp = (*p)->prev;
    free(*p);
    *p = tmp;
  }
}

user_defined_types: struct path_filo { char name[255]; unsigned int inode; struct path_filo *prev; }


view

decompiled_code:
int __fastcall view(__int64 a1)
{
int result; // eax

if ( a1 )
{
view(*(_QWORD *)(a1 + 264));
result = printf("%s %d ", (const char *)a1, *(unsigned int *)(a1 + 256));
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
int result; // eax

if ( a1 )
{
func3(*(_QWORD *)(a1 + 264));
result = printf("%s %d ", (const char *)a1, *(unsigned int *)(a1 + 256));
}
return result;
}

original_code:
void view(const struct path_filo *p)
{
  if ( p != ((void *)0) ) {
    view ( p->prev) ;
    printf("%s %d ", p->name, p->inode);
  }
}

canonical_original_code:
void view(struct path_filo *p)
{
  if ( p != ((void *)0) ) {
    view ( p->prev) ;
    printf("%s %d ", p->name, p->inode);
  }
}


decompiled_code:
void __fastcall fill_path_name(char *src, char *dest)
{
if ( src )
{
fill_path_name(*((char **)src + 33), dest);
*(_WORD *)&dest[strlen(dest)] = 47;
strcat(dest, src);
}
}

canonical_decompiled_code:
void __fastcall func4(char *src, char *dest)
{
if ( src )
{
func4(*((char **)src + 33), dest);
*(_WORD *)&dest[strlen(dest)] = 47;
strcat(dest, src);
}
}

original_code:
void fill_path_name( struct path_filo *p, char *string )
{
  if ( p != ((void *)0) ) {
    fill_path_name ( p->prev, string );
    strcat ( string, "/");
    strcat ( string, p->name );
  }
}

canonical_original_code:
void fill_path_name(struct path_filo *p, char *string)
{
  if ( p != ((void *)0) ) {
    fill_path_name ( p->prev, string );
    strcat ( string, "/");
    strcat ( string, p->name );
  }
}

variable_types:
string
char *


decompiled_code:
__int64 __fastcall read_superblock(int fd, void *buf)
{
__int64 result; // rax
char v3; // bl

if ( lseek64(fd, 1024LL, 0) == -1 )
{
perror("ext3Viewer error - lseek superblock error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else if ( *((_WORD *)buf + 28) == 0xEF53 )
{
result = mask(*((unsigned int *)buf + 24), 4LL);
if ( (_DWORD)result )
{
printf(
"WARNING: This filesystem is mounted or corrupted.\n"
" unmount it or fsck before using ext3viewer.\n"
" Using ext3viewer on mounted partition may\n"
" be unsafe.\n"
"continue anyway (y/n)? ");
v3 = getchar();
while ( getchar() != 10 )
;
result = 3 * (unsigned int)(v3 == 121) - 2;
}
}
else
{
fwrite("!!ERROR!! : This filesystem is not a valid ext. Bad magic number\n", 1uLL, 0x41uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, void *buf)
{
__int64 result; // rax
char v3; // bl

if ( lseek64(fd, 1024LL, 0) == -1 )
{
perror("ext3Viewer error - lseek superblock error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else if ( *((_WORD *)buf + 28) == 0xEF53 )
{
result = mask(*((unsigned int *)buf + 24), 4LL);
if ( (_DWORD)result )
{
printf(
"WARNING: This filesystem is mounted or corrupted.\n"
" unmount it or fsck before using ext3viewer.\n"
" Using ext3viewer on mounted partition may\n"
" be unsafe.\n"
"continue anyway (y/n)? ");
v3 = getchar();
while ( getchar() != 10 )
;
result = 3 * (unsigned int)(v3 == 121) - 2;
}
}
else
{
fwrite("!!ERROR!! : This filesystem is not a valid ext. Bad magic number\n", 1uLL, 0x41uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int read_superblock ( int fd, struct ext3_super_block *sb ) {
  char c;
  if( (lseek( fd, 1024, 0 )) == -1 ) {
    perror("ext3Viewer error - lseek superblock error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    fprintf( stderr, "!!ERROR!! : This filesystem is not a valid ext. "
        "Bad magic number\n");
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) ) {
    printf("WARNING: This filesystem is mounted or corrupted.\n"
        "         unmount it or fsck before using ext3viewer.\n"
        "         Using ext3viewer on mounted partition may\n"
        "         be unsafe.\n"
        "continue anyway (y/n)? ");
    c = getchar();
    while ( getchar()!='\n');
    if ( c != 'y' )
      return -2;
    return 1;
  }
  return 0;
}

canonical_original_code:
int read_superblock(int fd, struct ext3_super_block *sb) {
  char c;
  if( (lseek( fd, 1024, 0 )) == -1 ) {
    perror("ext3Viewer error - lseek superblock error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    fprintf( stderr, "!!ERROR!! : This filesystem is not a valid ext. "
        "Bad magic number\n");
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) ) {
    printf("WARNING: This filesystem is mounted or corrupted.\n"
        "         unmount it or fsck before using ext3viewer.\n"
        "         Using ext3viewer on mounted partition may\n"
        "         be unsafe.\n"
        "continue anyway (y/n)? ");
    c = getchar();
    while ( getchar()!='\n');
    if ( c != 'y' )
      return -2;
    return 1;
  }
  return 0;
}

variable_types: c char


decompiled_code:
__int64 __fastcall read_superblock_backup(int fd, void *buf, int a3, int a4)
{
__int64 result; // rax
char v5; // bl

if ( lseek64(fd, (unsigned int)(a3 * a4), 0) == -1 )
{
perror("ext3Viewer error - superblock lseek error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else if ( *((_WORD *)buf + 28) == 0xEF53 )
{
result = mask(*((unsigned int *)buf + 24), 4LL);
if ( (_DWORD)result )
{
printf(
"WARNING: This filesystem is mounted or corrupted.\n"
" unmount it or fsck before using ext3viewer.\n"
" Using ext3viewer on mounted partition may\n"
" be unsafe.\n"
"continue anyway (y/n)? ");
v5 = getchar();
while ( getchar() != 10 )
;
result = 3 * (unsigned int)(v5 == 121) - 2;
}
}
else
{
fwrite("!!ERROR!! : This filesystem is not a valid ext. Bad magic number\n", 1uLL, 0x41uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int fd, void *buf, int a3, int a4)
{
__int64 result; // rax
char v5; // bl

if ( lseek64(fd, (unsigned int)(a3 * a4), 0) == -1 )
{
perror("ext3Viewer error - superblock lseek error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else if ( *((_WORD *)buf + 28) == 0xEF53 )
{
result = mask(*((unsigned int *)buf + 24), 4LL);
if ( (_DWORD)result )
{
printf(
"WARNING: This filesystem is mounted or corrupted.\n"
" unmount it or fsck before using ext3viewer.\n"
" Using ext3viewer on mounted partition may\n"
" be unsafe.\n"
"continue anyway (y/n)? ");
v5 = getchar();
while ( getchar() != 10 )
;
result = 3 * (unsigned int)(v5 == 121) - 2;
}
}
else
{
fwrite("!!ERROR!! : This filesystem is not a valid ext. Bad magic number\n", 1uLL, 0x41uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int read_superblock_backup ( int fd, struct ext3_super_block *sb,
    __u32 block_num, int block_size ) {
  char c;
  if( (lseek( fd, block_num*block_size, 0 )) == -1 ) {
    perror("ext3Viewer error - superblock lseek error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    fprintf( stderr, "!!ERROR!! : This filesystem is not a valid ext. "
        "Bad magic number\n");
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) ) {
    printf("WARNING: This filesystem is mounted or corrupted.\n"
        "         unmount it or fsck before using ext3viewer.\n"
        "         Using ext3viewer on mounted partition may\n"
        "         be unsafe.\n"
        "continue anyway (y/n)? ");
    c = getchar();
    while ( getchar()!='\n');
    if ( c != 'y' )
      return -2;
    return 1;
  }
  return 0;
}

canonical_original_code:
int read_superblock_backup(int fd, struct ext3_super_block *sb, unsigned int block_num, int block_size) {
  char c;
  if( (lseek( fd, block_num*block_size, 0 )) == -1 ) {
    perror("ext3Viewer error - superblock lseek error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    fprintf( stderr, "!!ERROR!! : This filesystem is not a valid ext. "
        "Bad magic number\n");
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) ) {
    printf("WARNING: This filesystem is mounted or corrupted.\n"
        "         unmount it or fsck before using ext3viewer.\n"
        "         Using ext3viewer on mounted partition may\n"
        "         be unsafe.\n"
        "continue anyway (y/n)? ");
    c = getchar();
    while ( getchar()!='\n');
    if ( c != 'y' )
      return -2;
    return 1;
  }
  return 0;
}

variable_types: fd int


decompiled_code:
__int64 __fastcall read_superblock_gui(int fd, void *buf)
{
__int64 result; // rax

if ( lseek64(fd, 1024LL, 0) == -1 )
{
perror("ext3Viewer error - superblock lseek error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else
{
result = 0xFFFFFFFFLL;
if ( *((_WORD *)buf + 28) == 0xEF53 )
result = (unsigned int)mask(*((unsigned int *)buf + 24), 4LL) != 0;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int fd, void *buf)
{
__int64 result; // rax

if ( lseek64(fd, 1024LL, 0) == -1 )
{
perror("ext3Viewer error - superblock lseek error");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, buf, 0x400uLL) == -1 )
{
perror("ext3Viewer error - superblock read error");
result = 0xFFFFFFFFLL;
}
else
{
result = 0xFFFFFFFFLL;
if ( *((_WORD *)buf + 28) == 0xEF53 )
result = (unsigned int)mask(*((unsigned int *)buf + 24), 4LL) != 0;
}
return result;
}

original_code:
int read_superblock_gui ( int fd, struct ext3_super_block *sb ) {
  if( (lseek( fd, 1024, 0 )) == -1 ) {
    perror("ext3Viewer error - superblock lseek error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) )
    return 1;
  else
    return 0;
}

canonical_original_code:
int read_superblock_gui(int fd, struct ext3_super_block *sb) {
  if( (lseek( fd, 1024, 0 )) == -1 ) {
    perror("ext3Viewer error - superblock lseek error");
    return -1;
  }
  if( (read(fd, sb, sizeof(struct ext3_super_block) )) == -1 ) {
    perror("ext3Viewer error - superblock read error");
    return -1;
  }
  if ( sb->s_magic != 0xEF53 ) {
    return -1;
  }
  if( mask(sb->s_feature_incompat, 0x0004) )
    return 1;
  else
    return 0;
}


decompiled_code:
int __fastcall print_superblock(const char *a1)
{
puts("+------------------------------------------------------------------------------+");
puts("\t\t\t\tEXT3_SUPER_BLOCK");
puts("+------------------------------------------------------------------------------+");
printf("Total inode count = %u\n", *(unsigned int *)a1);
printf("Block count = %u\n", *((unsigned int *)a1 + 1));
printf("Reserved block count = %u\n", *((unsigned int *)a1 + 2));
printf("Free block count = %u\n", *((unsigned int *)a1 + 3));
printf("Free inode count = %u\n", *((unsigned int *)a1 + 4));
printf("First data block = %u\n", *((unsigned int *)a1 + 5));
printf("Block size = 1024 * 2^%u octets\n", *((unsigned int *)a1 + 6));
printf("Fragment size =%u\n", *((unsigned int *)a1 + 7));
printf("Blocks per group count =%u\n", *((unsigned int *)a1 + 8));
printf("Fragments per group count =%u\n", *((unsigned int *)a1 + 9));
printf("Inode per group count =%u\n", *((unsigned int *)a1 + 10));
puts("+------------------------------------------------------------------------------+");
printf("Last mounting operation timestamp =%u\n", *((unsigned int *)a1 + 11));
print_time(*((unsigned int *)a1 + 11));
printf("Last writing operation timestamp =%u\n", *((unsigned int *)a1 + 12));
print_time(*((unsigned int *)a1 + 12));
printf("Counter (times mounted)=%hu\n", *((unsigned __int16 *)a1 + 26));
printf("Authorized mount count before integrity checking =%hu\n", *((unsigned __int16 *)a1 + 27));
printf("Magic Number =%#.4hx\n", *((unsigned __int16 *)a1 + 28));
printf("Status flag =%hx\n", *((unsigned __int16 *)a1 + 29));
print_state(*((unsigned __int16 *)a1 + 29));
printf("Behaviour when detecting errors =%hu\n", *((unsigned __int16 *)a1 + 30));
print_errorbehavior(*((unsigned __int16 *)a1 + 30));
printf("Minimum compatible revision level (version)=%hu\n", *((unsigned __int16 *)a1 + 31));
print_revlev(*((unsigned __int16 *)a1 + 31));
printf("Last check timestamp =%u\n", *((unsigned int *)a1 + 16));
print_time(*((unsigned int *)a1 + 16));
printf("Maximum interval between checks = %u secondes\n", *((unsigned int *)a1 + 17));
printf("Creator OS =%u\n", *((unsigned int *)a1 + 18));
print_creatorOS(*((unsigned int *)a1 + 18));
printf("Current revision level (version)=%u\n", *((unsigned int *)a1 + 19));
print_revlev(*((unsigned int *)a1 + 19));
puts("+------------------------------------------------------------------------------+");
printf("Default UID for reserved blocks =%hu\n", *((unsigned __int16 *)a1 + 40));
printf("Default GID for reserved blocks =%hu\n", *((unsigned __int16 *)a1 + 41));
printf("First non-reserved inode number =%u\n", *((unsigned int *)a1 + 21));
printf("Inode size = %hu\n", *((unsigned __int16 *)a1 + 44));
printf("Superblock block number (being read)= %hu\n", *((unsigned __int16 *)a1 + 45));
puts("+------------------------------------------------------------------------------+");
printf("Compatible features set = %#.4x\n", *((unsigned int *)a1 + 23));
print_featcompat(*((unsigned int *)a1 + 23));
printf("Incompatible features set = %#.4x\n", *((unsigned int *)a1 + 24));
print_featincompat(*((unsigned int *)a1 + 24));
printf("Read-Only Compatible features set = %#.4x\n", *((unsigned int *)a1 + 25));
print_featROcompat(*((unsigned int *)a1 + 25));
puts("+------------------------------------------------------------------------------+");
print_UUID(a1 + 104);
printf("Volume name = \"%s\"\n", a1 + 120);
printf("Last mounted in directory \"%s\"\n", a1 + 136);
printf("Compression usage bitmap = %u\n", *((unsigned int *)a1 + 50));
printf("Number of blocks to try to preallocate = %hu\n", *((unsigned __int8 *)a1 + 204));
printf("Number of blocks to preallocate for directories = %hu\n", *((unsigned __int8 *)a1 + 205));
puts("+------------------------------------------------------------------------------+");
printf("Journal ");
print_UUID(a1 + 208);
printf("Journal Inode number = %u\n", *((unsigned int *)a1 + 56));
printf("Journal device number = %u\n", *((unsigned int *)a1 + 57));
printf("Start of list of orphaned inodes to delete = %u\n", *((unsigned int *)a1 + 58));
printf(
"HTREE default hash seed = %x|%x|%x|%x\n",
*((unsigned int *)a1 + 59),
*((unsigned int *)a1 + 60),
*((unsigned int *)a1 + 61),
*((unsigned int *)a1 + 62));
printf("Hash default version = %hd\n", *((unsigned __int8 *)a1 + 252));
printf("Default mount options = %u\n", *((unsigned int *)a1 + 64));
print_mountoptions(*((unsigned int *)a1 + 64));
return printf("First metablock block group = %u\n", *((unsigned int *)a1 + 65));
}

canonical_decompiled_code:
int __fastcall func3(const char *a1)
{
puts("+------------------------------------------------------------------------------+");
puts("\t\t\t\tEXT3_SUPER_BLOCK");
puts("+------------------------------------------------------------------------------+");
printf("Total inode count = %u\n", *(unsigned int *)a1);
printf("Block count = %u\n", *((unsigned int *)a1 + 1));
printf("Reserved block count = %u\n", *((unsigned int *)a1 + 2));
printf("Free block count = %u\n", *((unsigned int *)a1 + 3));
printf("Free inode count = %u\n", *((unsigned int *)a1 + 4));
printf("First data block = %u\n", *((unsigned int *)a1 + 5));
printf("Block size = 1024 * 2^%u octets\n", *((unsigned int *)a1 + 6));
printf("Fragment size =%u\n", *((unsigned int *)a1 + 7));
printf("Blocks per group count =%u\n", *((unsigned int *)a1 + 8));
printf("Fragments per group count =%u\n", *((unsigned int *)a1 + 9));
printf("Inode per group count =%u\n", *((unsigned int *)a1 + 10));
puts("+------------------------------------------------------------------------------+");
printf("Last mounting operation timestamp =%u\n", *((unsigned int *)a1 + 11));
print_time(*((unsigned int *)a1 + 11));
printf("Last writing operation timestamp =%u\n", *((unsigned int *)a1 + 12));
print_time(*((unsigned int *)a1 + 12));
printf("Counter (times mounted)=%hu\n", *((unsigned __int16 *)a1 + 26));
printf("Authorized mount count before integrity checking =%hu\n", *((unsigned __int16 *)a1 + 27));
printf("Magic Number =%#.4hx\n", *((unsigned __int16 *)a1 + 28));
printf("Status flag =%hx\n", *((unsigned __int16 *)a1 + 29));
print_state(*((unsigned __int16 *)a1 + 29));
printf("Behaviour when detecting errors =%hu\n", *((unsigned __int16 *)a1 + 30));
print_errorbehavior(*((unsigned __int16 *)a1 + 30));
printf("Minimum compatible revision level (version)=%hu\n", *((unsigned __int16 *)a1 + 31));
print_revlev(*((unsigned __int16 *)a1 + 31));
printf("Last check timestamp =%u\n", *((unsigned int *)a1 + 16));
print_time(*((unsigned int *)a1 + 16));
printf("Maximum interval between checks = %u secondes\n", *((unsigned int *)a1 + 17));
printf("Creator OS =%u\n", *((unsigned int *)a1 + 18));
print_creatorOS(*((unsigned int *)a1 + 18));
printf("Current revision level (version)=%u\n", *((unsigned int *)a1 + 19));
print_revlev(*((unsigned int *)a1 + 19));
puts("+------------------------------------------------------------------------------+");
printf("Default UID for reserved blocks =%hu\n", *((unsigned __int16 *)a1 + 40));
printf("Default GID for reserved blocks =%hu\n", *((unsigned __int16 *)a1 + 41));
printf("First non-reserved inode number =%u\n", *((unsigned int *)a1 + 21));
printf("Inode size = %hu\n", *((unsigned __int16 *)a1 + 44));
printf("Superblock block number (being read)= %hu\n", *((unsigned __int16 *)a1 + 45));
puts("+------------------------------------------------------------------------------+");
printf("Compatible features set = %#.4x\n", *((unsigned int *)a1 + 23));
print_featcompat(*((unsigned int *)a1 + 23));
printf("Incompatible features set = %#.4x\n", *((unsigned int *)a1 + 24));
print_featincompat(*((unsigned int *)a1 + 24));
printf("Read-Only Compatible features set = %#.4x\n", *((unsigned int *)a1 + 25));
print_featROcompat(*((unsigned int *)a1 + 25));
puts("+------------------------------------------------------------------------------+");
print_UUID(a1 + 104);
printf("Volume name = \"%s\"\n", a1 + 120);
printf("Last mounted in directory \"%s\"\n", a1 + 136);
printf("Compression usage bitmap = %u\n", *((unsigned int *)a1 + 50));
printf("Number of blocks to try to preallocate = %hu\n", *((unsigned __int8 *)a1 + 204));
printf("Number of blocks to preallocate for directories = %hu\n", *((unsigned __int8 *)a1 + 205));
puts("+------------------------------------------------------------------------------+");
printf("Journal ");
print_UUID(a1 + 208);
printf("Journal Inode number = %u\n", *((unsigned int *)a1 + 56));
printf("Journal device number = %u\n", *((unsigned int *)a1 + 57));
printf("Start of list of orphaned inodes to delete = %u\n", *((unsigned int *)a1 + 58));
printf(
"HTREE default hash seed = %x|%x|%x|%x\n",
*((unsigned int *)a1 + 59),
*((unsigned int *)a1 + 60),
*((unsigned int *)a1 + 61),
*((unsigned int *)a1 + 62));
printf("Hash default version = %hd\n", *((unsigned __int8 *)a1 + 252));
printf("Default mount options = %u\n", *((unsigned int *)a1 + 64));
print_mountoptions(*((unsigned int *)a1 + 64));
return printf("First metablock block group = %u\n", *((unsigned int *)a1 + 65));
}

original_code:
void print_superblock ( const struct ext3_super_block *sb ) {
  printf("+------------------------------------------------------------------------------+\n");
  printf("\t\t\t\tEXT3_SUPER_BLOCK\n");
  printf("+------------------------------------------------------------------------------+\n");
  printf("Total inode count    = %u\n", sb->s_inodes_count);
  printf("Block count    = %u\n", sb->s_blocks_count);
  printf("Reserved block count  = %u\n", sb->s_r_blocks_count);
  printf("Free block count = %u\n", sb->s_free_blocks_count);
  printf("Free inode count = %u\n", sb->s_free_inodes_count);
  printf("First data block = %u\n", sb->s_first_data_block);
  printf("Block size = 1024 * 2^%u octets\n", sb->s_log_block_size);
  printf("Fragment size =%u\n", sb->s_log_frag_size);
  printf("Blocks per group count =%u\n", sb->s_blocks_per_group);
  printf("Fragments per group count =%u\n", sb->s_frags_per_group);
  printf("Inode per group count =%u\n", sb->s_inodes_per_group);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Last mounting operation timestamp =%u\n", sb->s_mtime);
  print_time(sb->s_mtime);
  printf("Last writing operation timestamp =%u\n", sb->s_wtime);
  print_time(sb->s_wtime);
  printf("Counter (times mounted)=%hu\n", sb->s_mnt_count);
  printf("Authorized mount count before integrity checking =%hu\n", sb->s_max_mnt_count);
  printf("Magic Number =%#.4hx\n", sb->s_magic);
  printf("Status flag =%hx\n", sb->s_state);
  print_state(sb->s_state);
  printf("Behaviour when detecting errors =%hu\n", sb->s_errors);
  print_errorbehavior(sb->s_errors);
  printf("Minimum compatible revision level (version)=%hu\n", sb->s_minor_rev_level);
  print_revlev(sb->s_minor_rev_level);
  printf("Last check timestamp =%u\n", sb->s_lastcheck);
  print_time(sb->s_lastcheck);
  printf("Maximum interval between checks = %u secondes\n", sb->s_checkinterval);
  printf("Creator OS =%u\n", sb->s_creator_os);
  print_creatorOS(sb->s_creator_os);
  printf("Current revision level (version)=%u\n", sb->s_rev_level);
  print_revlev(sb->s_rev_level);
  printf("%s", "+------------------------------------------------------------------------------+\n");
  printf("Default UID for reserved blocks =%hu\n", sb->s_def_resuid);
  printf("Default GID for reserved blocks =%hu\n", sb->s_def_resgid);
  printf("First non-reserved inode number =%u\n", sb->s_first_ino);
  printf("Inode size = %hu\n", sb->s_inode_size);
  printf("Superblock block number (being read)= %hu\n", sb->s_block_group_nr);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Compatible features set = %#.4x\n", sb->s_feature_compat);
  print_featcompat(sb->s_feature_compat);
  printf("Incompatible features set = %#.4x\n", sb->s_feature_incompat);
  print_featincompat(sb->s_feature_incompat);
  printf("Read-Only Compatible features set = %#.4x\n", sb->s_feature_ro_compat);
  print_featROcompat(sb->s_feature_ro_compat);
  printf("%s", "+------------------------------------------------------------------------------+\n");
  print_UUID( sb->s_uuid );
  printf("Volume name = \"%s\"\n", sb->s_volume_name);
  printf("Last mounted in directory \"%s\"\n", sb->s_last_mounted);
  printf("Compression usage bitmap = %u\n", sb->s_algorithm_usage_bitmap);
  printf("Number of blocks to try to preallocate = %hu\n", sb->s_prealloc_blocks);
  printf("Number of blocks to preallocate for directories = %hu\n", sb->s_prealloc_dir_blocks);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Journal ");
  print_UUID( sb->s_journal_uuid );
  printf("Journal Inode number = %u\n", sb->s_journal_inum);
  printf("Journal device number = %u\n", sb->s_journal_dev);
  printf("Start of list of orphaned inodes to delete = %u\n", sb->s_last_orphan);
  printf("HTREE default hash seed = %x|%x|%x|%x\n", sb->s_hash_seed[0], sb->s_hash_seed[1], sb->s_hash_seed[2], sb->s_hash_seed[3]);
  printf("Hash default version = %hd\n", sb->s_def_hash_version);
  printf("Default mount options = %u\n", sb->s_default_mount_opts);
  print_mountoptions(sb->s_default_mount_opts);
  printf("First metablock block group = %u\n", sb->s_first_meta_bg);
}

canonical_original_code:
void print_superblock(struct ext3_super_block *sb) {
  printf("+------------------------------------------------------------------------------+\n");
  printf("\t\t\t\tEXT3_SUPER_BLOCK\n");
  printf("+------------------------------------------------------------------------------+\n");
  printf("Total inode count    = %u\n", sb->s_inodes_count);
  printf("Block count    = %u\n", sb->s_blocks_count);
  printf("Reserved block count  = %u\n", sb->s_r_blocks_count);
  printf("Free block count = %u\n", sb->s_free_blocks_count);
  printf("Free inode count = %u\n", sb->s_free_inodes_count);
  printf("First data block = %u\n", sb->s_first_data_block);
  printf("Block size = 1024 * 2^%u octets\n", sb->s_log_block_size);
  printf("Fragment size =%u\n", sb->s_log_frag_size);
  printf("Blocks per group count =%u\n", sb->s_blocks_per_group);
  printf("Fragments per group count =%u\n", sb->s_frags_per_group);
  printf("Inode per group count =%u\n", sb->s_inodes_per_group);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Last mounting operation timestamp =%u\n", sb->s_mtime);
  print_time(sb->s_mtime);
  printf("Last writing operation timestamp =%u\n", sb->s_wtime);
  print_time(sb->s_wtime);
  printf("Counter (times mounted)=%hu\n", sb->s_mnt_count);
  printf("Authorized mount count before integrity checking =%hu\n", sb->s_max_mnt_count);
  printf("Magic Number =%#.4hx\n", sb->s_magic);
  printf("Status flag =%hx\n", sb->s_state);
  print_state(sb->s_state);
  printf("Behaviour when detecting errors =%hu\n", sb->s_errors);
  print_errorbehavior(sb->s_errors);
  printf("Minimum compatible revision level (version)=%hu\n", sb->s_minor_rev_level);
  print_revlev(sb->s_minor_rev_level);
  printf("Last check timestamp =%u\n", sb->s_lastcheck);
  print_time(sb->s_lastcheck);
  printf("Maximum interval between checks = %u secondes\n", sb->s_checkinterval);
  printf("Creator OS =%u\n", sb->s_creator_os);
  print_creatorOS(sb->s_creator_os);
  printf("Current revision level (version)=%u\n", sb->s_rev_level);
  print_revlev(sb->s_rev_level);
  printf("%s", "+------------------------------------------------------------------------------+\n");
  printf("Default UID for reserved blocks =%hu\n", sb->s_def_resuid);
  printf("Default GID for reserved blocks =%hu\n", sb->s_def_resgid);
  printf("First non-reserved inode number =%u\n", sb->s_first_ino);
  printf("Inode size = %hu\n", sb->s_inode_size);
  printf("Superblock block number (being read)= %hu\n", sb->s_block_group_nr);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Compatible features set = %#.4x\n", sb->s_feature_compat);
  print_featcompat(sb->s_feature_compat);
  printf("Incompatible features set = %#.4x\n", sb->s_feature_incompat);
  print_featincompat(sb->s_feature_incompat);
  printf("Read-Only Compatible features set = %#.4x\n", sb->s_feature_ro_compat);
  print_featROcompat(sb->s_feature_ro_compat);
  printf("%s", "+------------------------------------------------------------------------------+\n");
  print_UUID( sb->s_uuid );
  printf("Volume name = \"%s\"\n", sb->s_volume_name);
  printf("Last mounted in directory \"%s\"\n", sb->s_last_mounted);
  printf("Compression usage bitmap = %u\n", sb->s_algorithm_usage_bitmap);
  printf("Number of blocks to try to preallocate = %hu\n", sb->s_prealloc_blocks);
  printf("Number of blocks to preallocate for directories = %hu\n", sb->s_prealloc_dir_blocks);
  printf("+------------------------------------------------------------------------------+\n");
  printf("Journal ");
  print_UUID( sb->s_journal_uuid );
  printf("Journal Inode number = %u\n", sb->s_journal_inum);
  printf("Journal device number = %u\n", sb->s_journal_dev);
  printf("Start of list of orphaned inodes to delete = %u\n", sb->s_last_orphan);
  printf("HTREE default hash seed = %x|%x|%x|%x\n", sb->s_hash_seed[0], sb->s_hash_seed[1], sb->s_hash_seed[2], sb->s_hash_seed[3]);
  printf("Hash default version = %hd\n", sb->s_def_hash_version);
  printf("Default mount options = %u\n", sb->s_default_mount_opts);
  print_mountoptions(sb->s_default_mount_opts);
  printf("First metablock block group = %u\n", sb->s_first_meta_bg);
}


decompiled_code:
int __fastcall print_sb_copy(_DWORD *a1)
{
int v1; // er12
int result; // eax
int v3; // ebx
unsigned int i; // ebx

v1 = a1[1] / a1[8];
printf("The superblock contains very important datas, ext3 maintains several copies of \nit. ");
if ( (unsigned int)mask((unsigned int)a1[25], 1LL) )
{
puts("Your filesystem uses the sparse superblock feature :\n");
if ( v1 <= 0 )
{
result = puts("There is no copy of the superblock");
}
else
{
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 1LL, (unsigned int)a1[8]);
if ( v1 > 3 )
{
for ( i = 3; i != v1; ++i )
{
if ( !(unsigned int)is_pow_of(i, 3LL) && !(unsigned int)is_pow_of(i, 5LL) )
{
result = is_pow_of(i, 7LL);
if ( !result )
continue;
}
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", i, a1[8] * i);
}
}
}
}
else
{
puts("a copy exists at the start of every block group");
if ( v1 <= 0 )
{
result = puts("There is no copy of the superblock");
}
else
{
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 1LL, (unsigned int)a1[8]);
if ( v1 > 3 )
{
v3 = 3;
do
{
while ( !v3 )
{
printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 0LL, (unsigned int)(1024 << a1[6]));
v3 = 1;
}
result = printf(
"\tThere is a copy of the superblock at group #%d block #%d\n\n",
(unsigned int)v3,
(unsigned int)(a1[8] * v3));
++v3;
}
while ( v1 > v3 || !v3 );
}
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func4(_DWORD *a1)
{
int v1; // er12
int result; // eax
int v3; // ebx
unsigned int i; // ebx

v1 = a1[1] / a1[8];
printf("The superblock contains very important datas, ext3 maintains several copies of \nit. ");
if ( (unsigned int)mask((unsigned int)a1[25], 1LL) )
{
puts("Your filesystem uses the sparse superblock feature :\n");
if ( v1 <= 0 )
{
result = puts("There is no copy of the superblock");
}
else
{
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 1LL, (unsigned int)a1[8]);
if ( v1 > 3 )
{
for ( i = 3; i != v1; ++i )
{
if ( !(unsigned int)is_pow_of(i, 3LL) && !(unsigned int)is_pow_of(i, 5LL) )
{
result = is_pow_of(i, 7LL);
if ( !result )
continue;
}
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", i, a1[8] * i);
}
}
}
}
else
{
puts("a copy exists at the start of every block group");
if ( v1 <= 0 )
{
result = puts("There is no copy of the superblock");
}
else
{
result = printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 1LL, (unsigned int)a1[8]);
if ( v1 > 3 )
{
v3 = 3;
do
{
while ( !v3 )
{
printf("\tThere is a copy of the superblock at group #%d block #%d\n\n", 0LL, (unsigned int)(1024 << a1[6]));
v3 = 1;
}
result = printf(
"\tThere is a copy of the superblock at group #%d block #%d\n\n",
(unsigned int)v3,
(unsigned int)(a1[8] * v3));
++v3;
}
while ( v1 > v3 || !v3 );
}
}
}
return result;
}

original_code:
void print_sb_copy ( const struct ext3_super_block *sb ) {
  int group_count = sb->s_blocks_count/((sb)->s_blocks_per_group);
  int i = 1;
  printf("The superblock contains very important datas, ext3 maintains "
      "several copies of \nit. ");
  if (! mask( sb->s_feature_ro_compat, 0x0001)) {
    printf("a copy exists at the start of every block group\n");
    if ( group_count > 0 ) {
      printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
          i, i*((sb)->s_blocks_per_group) );
      for ( i = 3 ; i < group_count || i == 0; i++ )
        printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
            i, i == 0?(1024 << (sb)->s_log_block_size):i*((sb)->s_blocks_per_group) );
    }
    else {
      printf("There is no copy of the superblock\n");
    }
  }
  else {
    printf("Your filesystem uses the sparse superblock feature :\n\n");
    if ( group_count > 0 ) {
      printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
          1, i*((sb)->s_blocks_per_group) );
      for ( i = 3 ; i < group_count ; i++ ) {
        if ( is_pow_of( i, 3 ) || is_pow_of( i, 5 ) || is_pow_of( i, 7 ) ) {
          printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
              i, i*((sb)->s_blocks_per_group) );
        }
      }
    }
    else {
      printf("There is no copy of the superblock\n");
    }
  }
}

canonical_original_code:
void print_sb_copy(struct ext3_super_block *sb) {
  int group_count = sb->s_blocks_count/((sb)->s_blocks_per_group);
  int i = 1;
  printf("The superblock contains very important datas, ext3 maintains "
      "several copies of \nit. ");
  if (! mask( sb->s_feature_ro_compat, 0x0001)) {
    printf("a copy exists at the start of every block group\n");
    if ( group_count > 0 ) {
      printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
          i, i*((sb)->s_blocks_per_group) );
      for ( i = 3 ; i < group_count || i == 0; i++ )
        printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
            i, i == 0?(1024 << (sb)->s_log_block_size):i*((sb)->s_blocks_per_group) );
    }
    else {
      printf("There is no copy of the superblock\n");
    }
  }
  else {
    printf("Your filesystem uses the sparse superblock feature :\n\n");
    if ( group_count > 0 ) {
      printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
          1, i*((sb)->s_blocks_per_group) );
      for ( i = 3 ; i < group_count ; i++ ) {
        if ( is_pow_of( i, 3 ) || is_pow_of( i, 5 ) || is_pow_of( i, 7 ) ) {
          printf("\tThere is a copy of the superblock at group #%d block #%d\n\n",
              i, i*((sb)->s_blocks_per_group) );
        }
      }
    }
    else {
      printf("There is no copy of the superblock\n");
    }
  }
}

variable_types: i int


decompiled_code:
__int64 __fastcall read_block(int fd, __int64 a2, unsigned int a3, void *a4)
{
__int64 result; // rax

if ( lseek64(fd, a3 * (__int64)(1024 << *(_DWORD *)(a2 + 24)), 0) <= 0 )
{
perror("ext3Viewer error - lseek read_block");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, a4, 1024 << *(_DWORD *)(a2 + 24)) )
{
result = 0LL;
}
else
{
perror("ext3Viewer error - read read_block");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, __int64 a2, unsigned int a3, void *a4)
{
__int64 result; // rax

if ( lseek64(fd, a3 * (__int64)(1024 << *(_DWORD *)(a2 + 24)), 0) <= 0 )
{
perror("ext3Viewer error - lseek read_block");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, a4, 1024 << *(_DWORD *)(a2 + 24)) )
{
result = 0LL;
}
else
{
perror("ext3Viewer error - read read_block");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int read_block ( int fd, struct ext3_super_block *sb,
    __u32 num, char *block ) {
  off_t lret;
  size_t sret;
  lret = lseek( fd, ((off_t) num)*(1024 << (sb)->s_log_block_size), 0);
  if ( lret <= 0 ) {
    perror("ext3Viewer error - lseek read_block");
    return -1;
  }
  sret = read ( fd, block, (1024 << (sb)->s_log_block_size) );
  if ( sret <= 0 ) {
    perror("ext3Viewer error - read read_block");
    return -1;
  }
  return 0;
}

canonical_original_code:
int read_block(int fd, struct ext3_super_block *sb, unsigned int num, char *block) {
  long lret;
  unsigned long sret;
  lret = lseek( fd, ((long) num)*(1024 << (sb)->s_log_block_size), 0);
  if ( lret <= 0 ) {
    perror("ext3Viewer error - lseek read_block");
    return -1;
  }
  sret = read ( fd, block, (1024 << (sb)->s_log_block_size) );
  if ( sret <= 0 ) {
    perror("ext3Viewer error - read read_block");
    return -1;
  }
  return 0;
}

variable_types:
num
unsigned int

variable_types:
block
char *

variable_types: lret long

variable_types:
sret
unsigned long


decompiled_code:
__int64 __fastcall read_block_pointer(int fd, int a2, unsigned int a3, void *a4)
{
__int64 result; // rax

if ( lseek64(fd, a2 * (unsigned __int64)a3, 0) <= 0 )
{
perror("ext3Viewer error - lseek read_block");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, a4, a2) )
{
result = 0LL;
}
else
{
perror("ext3Viewer error - read read_block");
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int fd, int a2, unsigned int a3, void *a4)
{
__int64 result; // rax

if ( lseek64(fd, a2 * (unsigned __int64)a3, 0) <= 0 )
{
perror("ext3Viewer error - lseek read_block");
result = 0xFFFFFFFFLL;
}
else if ( read(fd, a4, a2) )
{
result = 0LL;
}
else
{
perror("ext3Viewer error - read read_block");
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int read_block_pointer ( int fd, int block_size,
    __u32 num, __u32 *block ) {
  off_t lret;
  size_t sret;
  lret = lseek( fd, ((off_t) num)*block_size, 0);
  if ( lret <= 0 ) {
    perror("ext3Viewer error - lseek read_block");
    return -1;
  }
  sret = read ( fd, block, block_size );
  if ( sret <= 0 ) {
    perror("ext3Viewer error - read read_block");
    return -1;
  }
  return 0;
}

canonical_original_code:
int read_block_pointer(int fd, int block_size, unsigned int num, unsigned int *block) {
  long lret;
  unsigned long sret;
  lret = lseek( fd, ((long) num)*block_size, 0);
  if ( lret <= 0 ) {
    perror("ext3Viewer error - lseek read_block");
    return -1;
  }
  sret = read ( fd, block, block_size );
  if ( sret <= 0 ) {
    perror("ext3Viewer error - read read_block");
    return -1;
  }
  return 0;
}

variable_types:
block
unsigned int *


variable_types: struct ext3_super_block { unsigned int s_inodes_count; unsigned int s_blocks_count; unsigned int s_r_blocks_count; unsigned int s_free_blocks_count; unsigned int s_free_inodes_count; unsigned int s_first_data_block; unsigned int s_log_block_size; unsigned int s_log_frag_size; unsigned int s_blocks_per_group; unsigned int s_frags_per_group; unsigned int s_inodes_per_group; unsigned int s_mtime; unsigned int s_wtime; unsigned short s_mnt_count; unsigned short s_max_mnt_count; unsigned short s_magic; unsigned short s_state; unsigned short s_errors; unsigned short s_minor_rev_level; unsigned int s_lastcheck; unsigned int s_checkinterval; unsigned int s_creator_os; unsigned int s_rev_level; unsigned short s_def_resuid; unsigned short s_def_resgid; unsigned int s_first_ino; unsigned short s_inode_size; unsigned short s_block_group_nr; unsigned int s_feature_compat; unsigned int s_feature_incompat; unsigned int s_feature_ro_compat; unsigned char s_uuid[16]; char s_volume_name[16]; char s_last_mounted[64]; unsigned int s_algorithm_usage_bitmap; unsigned char s_prealloc_blocks; unsigned char s_prealloc_dir_blocks; unsigned short s_reserved_gdt_blocks; unsigned char s_journal_uuid[16]; unsigned int s_journal_inum; unsigned int s_journal_dev; unsigned int s_last_orphan; unsigned int s_hash_seed[4]; unsigned char s_def_hash_version; unsigned char s_reserved_char_pad; unsigned short s_reserved_word_pad; unsigned int s_default_mount_opts; unsigned int s_first_meta_bg; unsigned int s_mkfs_time; unsigned int s_jnl_blocks[17]; unsigned int s_blocks_count_hi; unsigned int s_r_blocks_count_hi; unsigned int s_free_blocks_count_hi; unsigned short s_min_extra_isize; unsigned short s_want_extra_isize; unsigned int s_flags; unsigned short s_raid_stride; unsigned short s_mmp_interval; unsigned long long s_mmp_block; unsigned int s_raid_stripe_width; unsigned char s_log_groups_per_flex; unsigned char s_reserved_char_pad2; unsigned short s_reserved_pad; unsigned int s_reserved[162]; } *

variable_types: max int

variable_types:
block
unsigned int [-1]

variable_types: ret int